Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: getAllMethods returns all methods, incl. those of libraries and java.lang.Object #771

Merged
merged 1 commit into from
Aug 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/main/java/spoon/reflect/declaration/CtType.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,13 @@ public interface CtType<T> extends CtNamedElement, CtTypeInformation, CtTypeMemb

/**
* Return all the accessible methods (concrete and abstract) for this type.
* It recursively collects all methods from super-classes and super-interfaces.
*
* The recursion stops when the super-type/super-interface is not in the model.
* As of 5.3: Really all methods (incl. those of library super-classes
* and Object are returned, thanks to runtime reflection)
*
* Up to 5.2: The recursion stops when the super-type/super-interface is not in the model,
* which means that no method of library super-classes, or of Object are present.
*/
Set<CtMethod<?>> getAllMethods();

Expand Down
11 changes: 7 additions & 4 deletions src/main/java/spoon/support/reflect/declaration/CtTypeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -776,14 +776,17 @@ private void addAllBasedOnSignature(Set<CtMethod<?>> from, Set<CtMethod<?>> dest
@Override
public Set<CtMethod<?>> getAllMethods() {
Set<CtMethod<?>> l = new HashSet<>(getMethods());
if ((getSuperclass() != null) && (getSuperclass().getDeclaration() != null)) {
CtType<?> t = getSuperclass().getDeclaration();
if ((getSuperclass() != null) && (getSuperclass().getTypeDeclaration() != null)) {
CtType<?> t = getSuperclass().getTypeDeclaration();
addAllBasedOnSignature(t.getAllMethods(), l);
} else {
// this is object
addAllBasedOnSignature(getFactory().Type().get(Object.class).getMethods(), l);
}

for (CtTypeReference<?> ref : getSuperInterfaces()) {
if (ref.getDeclaration() != null) {
CtType<?> t = ref.getDeclaration();
if (ref.getTypeDeclaration() != null) {
CtType<?> t = ref.getTypeDeclaration();
addAllBasedOnSignature(t.getAllMethods(), l);
}
}
Expand Down
30 changes: 19 additions & 11 deletions src/test/java/spoon/reflect/declaration/CtTypeInformationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,46 @@ public void setUp() throws Exception {

@Test
public void testGetSuperclass() throws Exception {
// test superclass of class
final CtType<?> type = this.factory.Type().get(Subclass.class);

CtTypeReference<?> superclass = type.getSuperclass();
final CtType<?> extendObject = this.factory.Type().get(ExtendsObject.class);

// only 1 method directly in this class
Assert.assertEquals(1, extendObject.getMethods().size());

// + 48 of ArrayList (in library)
// + 12 of java.lang.Object
Assert.assertEquals(1+12+48, extendObject.getAllMethods().size());

final CtType<?> subClass = this.factory.Type().get(Subclass.class);
assertEquals(2, subClass.getMethods().size());
assertEquals(61+2, subClass.getAllMethods().size());

CtTypeReference<?> superclass = subClass.getSuperclass();
Assert.assertEquals(ExtendsObject.class.getName(), superclass.getQualifiedName());

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// superclass = superclass.getSuperclass();
// Assert.assertEquals(Object.class.getName(), superclass.getQualifiedName());
Assert.assertEquals(ExtendsObject.class.getName(), superclass.getQualifiedName());

Assert.assertNull(superclass.getSuperclass());
Assert.assertNotNull(superclass.getSuperclass());

// test superclass of interface type reference
Set<CtTypeReference<?>> superInterfaces = type.getSuperInterfaces();
Set<CtTypeReference<?>> superInterfaces = subClass.getSuperInterfaces();
Assert.assertEquals(1, superInterfaces.size());
CtTypeReference<?> superinterface = superInterfaces.iterator().next();
Assert.assertEquals(Subinterface.class.getName(), superinterface.getQualifiedName());
Assert.assertNull(superinterface.getSuperclass());

assertEquals(2, type.getAllMethods().size());

// test superclass of interface
final CtType<?> type2 = this.factory.Type().get(Subinterface.class);
Assert.assertNull(type2.getSuperclass());

// the interface abstract method and the implementation method have the same signature
CtMethod<?> fooConcrete = type.getMethodsByName("foo").get(0);
CtMethod<?> fooConcrete = subClass.getMethodsByName("foo").get(0);
CtMethod<?> fooAbstract = type2.getMethodsByName("foo").get(0);
assertEquals(fooConcrete.getSignature(), fooAbstract.getSignature());
// yet they are different AST node
Assert.assertNotEquals(fooConcrete, fooAbstract);

assertEquals(type.getMethodsByName("foo").get(0).getSignature(),
assertEquals(subClass.getMethodsByName("foo").get(0).getSignature(),
type2.getMethodsByName("foo").get(0).getSignature());

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
package spoon.reflect.declaration.testclasses;

public class ExtendsObject {
}
package spoon.reflect.declaration.testclasses;

import java.util.ArrayList;

public class ExtendsObject extends ArrayList {
void m() {}
}
2 changes: 1 addition & 1 deletion src/test/java/spoon/test/annotation/AnnotationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ public void testAnnotatedElementTypes() throws Exception {
CtAnnotationType<?> annotationType = pkg.getType("Bound");
assertEquals(Bound.class, annotationType.getActualClass());
assertNull(annotationType.getSuperclass());
assertEquals(annotationType.getFields().size(),annotationType.getAllMethods().size());
assertEquals(annotationType.getFields().size(),annotationType.getMethods().size());
assertEquals(0,annotationType.getSuperInterfaces().size());

annotations = annotationType.getAnnotations();
Expand Down
3 changes: 1 addition & 2 deletions src/test/java/spoon/test/comparison/EqualTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ public void testEqualsEmptyException() throws Exception {
}

CtClass<?> clazz1 = (CtClass<?>) factory.Type().getAll().get(0);

CtMethod<?> method = (CtMethod<?>) clazz1.getAllMethods().toArray()[0];
CtMethod<?> method = (CtMethod<?>) clazz1.getMethods().toArray()[0];

CtInvocation<?> invo = (CtInvocation<?>) method.getBody().getStatement(0);

Expand Down
8 changes: 4 additions & 4 deletions src/test/java/spoon/test/interfaces/InterfaceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void testExtendsDefaultMethodInSubInterface() throws Exception {
final CtInterface<?> ctInterface = (CtInterface<?>) factory.Type().get(ExtendsDefaultMethodInterface.class);

assertEquals("Sub interface must have only one method in its interface", 1, ctInterface.getMethods().size());
assertEquals("Sub interface must have 6 methods in its interface and its super interfaces", 6, ctInterface.getAllMethods().size());
assertEquals("Sub interface must have 6+12(from java.lang.Object) methods in its interface and its super interfaces", 18, ctInterface.getAllMethods().size());

final CtMethod<?> getZonedDateTimeMethod = ctInterface.getMethodsByName("getZonedDateTime").get(0);
assertTrue("Method in the sub interface must be a default method", getZonedDateTimeMethod.isDefaultMethod());
Expand All @@ -70,7 +70,7 @@ public void testRedefinesDefaultMethodInSubInterface() throws Exception {
final CtInterface<?> ctInterface = (CtInterface<?>) factory.Type().get(RedefinesDefaultMethodInterface.class);

assertEquals("Sub interface must have only one method in its interface", 1, ctInterface.getMethods().size());
assertEquals("Sub interface must have 6 methods in its interface and its super interfaces", 6, ctInterface.getAllMethods().size());
assertEquals("Sub interface must have 6+12(from java.lang.Object) methods in its interface and its super interfaces", 18, ctInterface.getAllMethods().size());

final CtMethod<?> getZonedDateTimeMethod = ctInterface.getMethodsByName("getZonedDateTime").get(0);
assertFalse("Method in the sub interface mustn't be a default method", getZonedDateTimeMethod.isDefaultMethod());
Expand All @@ -82,7 +82,7 @@ public void testExtendsStaticMethodInSubInterface() throws Exception {
final CtInterface<?> ctInterface = (CtInterface<?>) factory.Type().get(ExtendsStaticMethodInterface.class);

assertEquals("Sub interface must have only one method in its interface", 1, ctInterface.getMethods().size());
assertEquals("Sub interface must have 6 methods in its interface and its super interfaces", 6, ctInterface.getAllMethods().size());
assertEquals("Sub interface must have 6+12(from java.lang.Object) methods in its interface and its super interfaces", 18, ctInterface.getAllMethods().size());

final CtMethod<?> getZoneIdMethod = ctInterface.getMethodsByName("getZoneId").get(0);
assertTrue("Method in the sub interface must be a static method", getZoneIdMethod.getModifiers().contains(ModifierKind.STATIC));
Expand All @@ -94,7 +94,7 @@ public void testRedefinesStaticMethodInSubInterface() throws Exception {
final CtInterface<?> ctInterface = (CtInterface<?>) factory.Type().get(RedefinesStaticMethodInterface.class);

assertEquals("Sub interface must have only one method in its interface", 1, ctInterface.getMethods().size());
assertEquals("Sub interface must have 6 methods in its interface and its super interfaces", 6, ctInterface.getAllMethods().size());
assertEquals("Sub interface must have 6+12(from java.lang.Object) methods in its interface and its super interfaces", 18, ctInterface.getAllMethods().size());

final CtMethod<?> getZoneIdMethod = ctInterface.getMethodsByName("getZoneId").get(0);
assertFalse("Method in the sub interface mustn't be a static method", getZoneIdMethod.getModifiers().contains(ModifierKind.STATIC));
Expand Down
11 changes: 7 additions & 4 deletions src/test/java/spoon/test/signature/SignatureTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.junit.Assert;
import org.junit.Test;

import spoon.Launcher;
import spoon.SpoonModelBuilder;
import spoon.compiler.SpoonCompiler;
Expand Down Expand Up @@ -29,6 +30,7 @@

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand Down Expand Up @@ -97,7 +99,8 @@ public void testNullSignatureInUnboundVariable() throws Exception {
}
CtClass<?> clazz1 = (CtClass<?>) factory.Type().getAll().get(0);

CtMethod<?> method = (CtMethod<?>) clazz1.getAllMethods().toArray()[0];
Set<CtMethod<?>> methods = clazz1.getMethods();
CtMethod<?> method = (CtMethod<?>) methods.toArray()[0];
assertEquals("java.lang.Object foo(java.util.List)", method.getSignature());


Expand Down Expand Up @@ -202,14 +205,14 @@ public void testMethodInvocationSignatureWithVariableAccess() throws Exception{

//**FIRST PART: passing local variable access.
///--------From the first method we take the method invocations
CtMethod<?> methodInteger = (CtMethod<?>) clazz1.getAllMethods().toArray()[0];
CtMethod<?> methodInteger = (CtMethod<?>) clazz1.getMethods().toArray()[0];
assertEquals("java.lang.Object foo(int)", methodInteger.getSignature());

CtInvocation<?> invoToInt1 = (CtInvocation<?>) methodInteger.getBody().getStatement(1);
CtExpression<?> argumentToInt1 = invoToInt1.getArguments().get(0);

//----------From the second method we take the Method Inv
CtMethod<?> methodString = (CtMethod<?>) clazz1.getAllMethods().toArray()[1];
CtMethod<?> methodString = (CtMethod<?>) clazz1.getMethods().toArray()[1];
assertEquals("java.lang.Object foo(java.lang.String)", methodString.getSignature());

CtInvocation<?> invoToString = (CtInvocation<?>) methodString.getBody().getStatement(1);
Expand Down Expand Up @@ -268,7 +271,7 @@ public void testUnboundFieldSignature(){

//**FIRST PART: passing local variable access.
///--------From the first method we take the method invocations
CtMethod<?> methodString = (CtMethod<?>) clazz1.getAllMethods().toArray()[0];
CtMethod<?> methodString = (CtMethod<?>) clazz1.getMethods().toArray()[0];
assertEquals("java.io.File foo(java.lang.String)", methodString.getSignature());

CtAssignment<?,?> invoToInt1 = (CtAssignment<?,?>) methodString.getBody().getStatement(0);
Expand Down