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

review 1: feature: CtTypeParameter#getTypeDeclarer() #1217

Merged
merged 3 commits into from
Mar 14, 2017
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
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