Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

test: interface method overrides object method #2025

Merged
merged 8 commits into from
Jun 5, 2018

Conversation

pvojtechovsky
Copy link
Collaborator

I tried to reproduce the problem mentioned in #2023 but isOverriding seems to be working well for interfaces and Object.

@krakowski
Copy link
Contributor

Hi Pavel,

here's a small snippet to reproduce the problem.

CtInterface<?> objectInterface = factory.Interface().get(ObjectInterface.class);
CtClass<?> objectClass = factory.Class().get(Object.class);

CtMethod<?> objectInterfaceEquals = objectInterface.getMethodsByName("equals").get(0);
CtMethod<?> objectEquals = objectClass.getMethodsByName("equals").get(0);

assertTrue(objectInterfaceEquals.isOverriding(objectEquals));

with ObjectInterface looking like this

public interface ObjectInterface {
    void doSomething();
    boolean equals(Object other);
}

@monperrus
Copy link
Collaborator

@pvojtechovsky, Do we merge this first and move the problem to another PR? Or do we update this PR?

@pvojtechovsky
Copy link
Collaborator Author

Hi Filip,

the problem is still not reproducible. Do you use latest Spoon sources?

@krakowski
Copy link
Contributor

Hi Pavel,

the code I posted fails on the latest master branch (0c36243). I think the code you used in this PR is working since you used ModelUtils.buildClass(ObjectInterface.class) instead of factory.Interface().get(ObjectInterface.class).

@krakowski
Copy link
Contributor

Could you please try the following (CtLambdaImpl does it the same way).

CtClass<?> fooClass = factory.Class().get(Foo.class);
CtClass<?> objectClass = factory.Class().get(Object.class);

CtLambda<?> objectInterfaceLambda = (CtLambda<?>) fooClass.filterChildren(new LambdaFilter(factory.Interface().get(ObjectInterface.class))).list().get(0);
CtTypeReference<?> lambdaTypeReference = objectInterfaceLambda.getType();
CtType<?> lambdaType = lambdaTypeReference.getTypeDeclaration();

CtMethod<?> lambdaTypeEquals = lambdaType.getMethodsByName("equals").get(0);
CtMethod<?> objectEquals = objectClass.getMethodsByName("equals").get(0);

assertTrue(lambdaTypeEquals.isOverriding(objectEquals));
public interface ObjectInterface {
    void doSomething();
    boolean equals(Object other);
}
public class Foo {

    public void useLambda() {
        ObjectInterface objectInterface = () -> { /* do nothing */ };
        objectInterface.doSomething();
    }
}

@pvojtechovsky
Copy link
Collaborator Author

My origin tests were wrong. Now it finally fails, so I can fix it :-)

@pvojtechovsky
Copy link
Collaborator Author

@monperrus now SuperInheritanceHierarchyFunction always visits Object reference as end of interface super type hierarchy. But is it correct? Interface doesn't extend Object, but it inherits all it's public members... https://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.2

Optional I might add method SuperInheritanceHierarchyFunction#interfacesExtendObject(boolean), which would activate this behavior only on client's demand.

WDYT?

@monperrus
Copy link
Collaborator

OK for me. Ping me back when ready for merge.

Thanks, --Martin

@pvojtechovsky
Copy link
Collaborator Author

@monperrus it is ready for merge

@monperrus monperrus merged commit 098b159 into INRIA:master Jun 5, 2018
@monperrus
Copy link
Collaborator

thanks!

@surli surli mentioned this pull request Jun 25, 2018
@pvojtechovsky pvojtechovsky deleted the fixIfaceExtendsObject branch September 1, 2018 08:01
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants