Skip to content

Commit

Permalink
feature: add metamodel method CtTypeParameter#getTypeParameterDeclare…
Browse files Browse the repository at this point in the history
…r() (#1217)
  • Loading branch information
pvojtechovsky authored and monperrus committed Mar 14, 2017
1 parent b715c39 commit f87ba4f
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/main/java/spoon/reflect/declaration/CtTypeParameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ public interface CtTypeParameter extends CtType<Object> {
@DerivedProperty
CtTypeParameterReference getReference();

/**
* @return the {@link CtFormalTypeDeclarer}, which declares this {@link CtTypeParameter}
*/
@DerivedProperty
CtFormalTypeDeclarer getTypeParameterDeclarer();

// override the return type
@Override
CtTypeParameter clone();
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/spoon/reflect/factory/TypeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ public CtTypeParameterReference createReference(CtTypeParameter type) {
ref.addAnnotation(ctAnnotation.clone());
}
ref.setSimpleName(type.getSimpleName());
//TypeParameter reference without parent is unusable. It lost information about it's declarer
ref.setParent(type);
return ref;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
package spoon.support.reflect.declaration;

import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtFormalTypeDeclarer;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtModifiable;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtTypeParameter;
import spoon.reflect.declaration.ModifierKind;
import spoon.reflect.declaration.ParentNotInitializedException;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.reference.CtTypeParameterReference;
Expand Down Expand Up @@ -78,6 +80,15 @@ public CtTypeParameter clone() {
return (CtTypeParameter) super.clone();
}

@Override
public CtFormalTypeDeclarer getTypeParameterDeclarer() {
try {
return getParent(CtFormalTypeDeclarer.class);
} catch (ParentNotInitializedException e) {
return null;
}
}

@Override
@UnsettableProperty
public <F, C extends CtType<Object>> C addFieldAtTop(CtField<F> field) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@
import java.util.ArrayList;

@SuppressWarnings("serial")
public class ClassThatBindsAGenericType extends ArrayList<File> {
class ClassThatBindsAGenericType extends ArrayList<File> {

public static void main(String[] args) throws Exception {
}

}

class ClassThatDefinesANewTypeArgument<T> {
void foo(T t){}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package spoon.test.generics;

public class ClassThatDefinesANewTypeArgument<T> {
void foo(T t){}
}
16 changes: 14 additions & 2 deletions src/test/java/spoon/test/generics/GenericsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertSame;
import static spoon.testing.utils.ModelUtils.build;
import static spoon.testing.utils.ModelUtils.buildClass;
import static spoon.testing.utils.ModelUtils.buildNoClasspath;
Expand All @@ -29,6 +30,7 @@
import spoon.reflect.declaration.CtConstructor;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtFormalTypeDeclarer;
import spoon.reflect.declaration.CtInterface;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtNamedElement;
Expand Down Expand Up @@ -141,8 +143,9 @@ public void testModelBuildingSimilarSignatureMethods() throws Exception {

@Test
public void testTypeParameterReference() throws Exception {
CtClass<?> classThatBindsAGenericType = build("spoon.test.generics", "ClassThatBindsAGenericType");
CtClass<?> classThatDefinesANewTypeArgument = classThatBindsAGenericType.getPackage().getElements(new NameFilter<CtClass<?>>("ClassThatDefinesANewTypeArgument")).get(0);
Factory factory = build(ClassThatBindsAGenericType.class, ClassThatDefinesANewTypeArgument.class);
CtClass<?> classThatBindsAGenericType = factory.Class().get(ClassThatBindsAGenericType.class);
CtClass<?> classThatDefinesANewTypeArgument = factory.Class().get(ClassThatDefinesANewTypeArgument.class);

CtTypeReference<?> tr1 = classThatBindsAGenericType.getSuperclass();
CtTypeReference<?> trExtends = tr1.getActualTypeArguments().get(0);
Expand All @@ -161,6 +164,15 @@ public void testTypeParameterReference() throws Exception {
assertEquals("T", tr3.getSimpleName());
}

@Test
public void testTypeParameterDeclarer() throws Exception {
// contract: one can navigate to the declarer of a type parameter
CtClass<?> classThatDefinesANewTypeArgument = build("spoon.test.generics", "ClassThatDefinesANewTypeArgument");
CtTypeParameter typeParam = classThatDefinesANewTypeArgument.getFormalCtTypeParameters().get(0);
assertSame(classThatDefinesANewTypeArgument, typeParam.getTypeParameterDeclarer());
assertSame(typeParam, typeParam.getReference().getDeclaration());
}

@Test
public void testGenericMethodCallWithExtend() throws Exception {
CtClass<?> type = build("spoon.test.generics", "GenericMethodCallWithExtend");
Expand Down

0 comments on commit f87ba4f

Please sign in to comment.