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

Use CtTypeAccess for CtFieldRead of .class and instanceof #458

Merged
merged 2 commits into from
Jan 4, 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
16 changes: 14 additions & 2 deletions src/main/java/spoon/reflect/factory/CodeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import spoon.reflect.code.CtStatementList;
import spoon.reflect.code.CtThisAccess;
import spoon.reflect.code.CtThrow;
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtNamedElement;
Expand Down Expand Up @@ -99,8 +100,19 @@ public <T> CtBinaryOperator<T> createBinaryOperator(CtExpression<?> left, CtExpr
*/
public <T> CtFieldAccess<Class<T>> createClassAccess(CtTypeReference<T> type) {
@SuppressWarnings({ "rawtypes", "unchecked" }) CtTypeReference<Class<T>> classType = (CtTypeReference) factory.Type().createReference(Class.class);
CtFieldReference<Class<T>> field = factory.Core().<Class<T>>createFieldReference().setDeclaringType(type).setType(classType).setSimpleName("class");
return factory.Core().<Class<T>>createFieldRead().<CtFieldRead<Class<T>>>setType(classType).<CtFieldRead<Class<T>>>setVariable(field);
CtTypeAccess<T> typeAccess = factory.Core().createTypeAccess();
typeAccess.setType(type);

CtFieldReference<Class<T>> fieldReference = factory.Core().createFieldReference();
fieldReference.setSimpleName("class");
fieldReference.setType(classType);
fieldReference.setDeclaringType(type);

CtFieldRead<Class<T>> fieldRead = factory.Core().createFieldRead();
fieldRead.setType(classType);
fieldRead.setVariable(fieldReference);
fieldRead.setTarget(typeAccess);
return fieldRead;
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/spoon/reflect/visitor/CtScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ public <T> void visitCtArrayTypeReference(CtArrayTypeReference<T> reference) {
scan(reference.getPackage());
scan(reference.getComponentType());
scan(reference.getActualTypeArguments());
scan(reference.getAnnotations());
exit(reference);
}

Expand Down Expand Up @@ -356,6 +357,7 @@ public <T> void visitCtExecutableReference(
scan(reference.getDeclaringType());
scan(reference.getType());
scan(reference.getActualTypeArguments());
scan(reference.getAnnotations());
exit(reference);
}

Expand Down Expand Up @@ -391,6 +393,7 @@ public <T> void visitCtFieldReference(CtFieldReference<T> reference) {
enter(reference);
scan(reference.getDeclaringType());
scan(reference.getType());
scan(reference.getAnnotations());
exit(reference);
}

Expand Down Expand Up @@ -464,6 +467,7 @@ public <T> void visitCtLocalVariableReference(
CtLocalVariableReference<T> reference) {
enter(reference);
scan(reference.getType());
scan(reference.getAnnotations());
exit(reference);
}

Expand All @@ -477,6 +481,7 @@ public <T> void visitCtCatchVariable(CtCatchVariable<T> catchVariable) {
public <T> void visitCtCatchVariableReference(CtCatchVariableReference<T> reference) {
enter(reference);
scan(reference.getType());
scan(reference.getAnnotations());
exit(reference);
}

Expand Down Expand Up @@ -581,6 +586,7 @@ public <T> void visitCtParameter(CtParameter<T> parameter) {
public <T> void visitCtParameterReference(CtParameterReference<T> reference) {
enter(reference);
scan(reference.getType());
scan(reference.getAnnotations());
exit(reference);
}

Expand Down Expand Up @@ -653,6 +659,7 @@ public void visitCtTypeParameterReference(CtTypeParameterReference ref) {
scan(ref.getPackage());
scan(ref.getDeclaringType());
scan(ref.getActualTypeArguments());
scan(ref.getAnnotations());
scan(ref.getBounds());
exit(ref);
}
Expand All @@ -662,6 +669,7 @@ public <T> void visitCtTypeReference(CtTypeReference<T> reference) {
scan(reference.getPackage());
scan(reference.getDeclaringType());
scan(reference.getActualTypeArguments());
scan(reference.getAnnotations());
exit(reference);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1948,7 +1948,9 @@ private <T> boolean hasDeclaringTypeWithGenerics(CtTypeReference<T> reference) {

@Override
public <T> void visitCtTypeAccess(CtTypeAccess<T> typeAccess) {
enterCtExpression(typeAccess);
scan(typeAccess.getType());
exitCtExpression(typeAccess);
}

public void visitCtTypeReferenceWithoutGenerics(CtTypeReference<?> ref) {
Expand Down Expand Up @@ -2043,10 +2045,8 @@ public DefaultJavaPrettyPrinter writeAnnotations(CtElement e) {
* Writes an annotation element.
*/
public DefaultJavaPrettyPrinter writeAnnotationElement(Factory factory, Object value) {
if (value instanceof CtTypeReference) {
context.ignoreGenerics = true;
scan((CtTypeReference<?>) value).write(".class");
context.ignoreGenerics = false;
if (value instanceof CtTypeAccess) {
scan((CtTypeAccess) value).write(".class");
} else if (value instanceof CtFieldReference) {
scan(((CtFieldReference<?>) value).getDeclaringType());
write("." + ((CtFieldReference<?>) value).getSimpleName());
Expand Down
77 changes: 41 additions & 36 deletions src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@
import spoon.reflect.code.CtExecutableReferenceExpression;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtFieldAccess;
import spoon.reflect.code.CtFieldRead;
import spoon.reflect.code.CtFor;
import spoon.reflect.code.CtForEach;
import spoon.reflect.code.CtIf;
Expand Down Expand Up @@ -749,7 +748,7 @@ private Object buildValuePairAnnotation(Object value) {
} else if (value instanceof FieldBinding) {
return getVariableReference((FieldBinding) value);
} else if (value instanceof BinaryTypeBinding) {
return getTypeReference((BinaryTypeBinding) value);
return factory.Code().createClassAccess(getTypeReference((BinaryTypeBinding) value));
} else if (value instanceof Object[]) {
Collection<Object> values = new ArrayList<Object>();
for (Object currentValue : (Object[]) value) {
Expand Down Expand Up @@ -1335,6 +1334,15 @@ public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedT
context.exit(parameterizedQualifiedTypeReference);
}

@Override
public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
if (skipTypeInAnnotation) {
skipTypeInAnnotation = false;
return;
}
context.exit(parameterizedQualifiedTypeReference);
}

@Override
public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
if (skipTypeInAnnotation) {
Expand Down Expand Up @@ -1973,18 +1981,8 @@ public boolean visit(CharLiteral charLiteral, BlockScope scope) {

@Override
public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) {
CtTypeReference<Class<Object>> ref = references.getTypeReference(classLiteral.targetType);
CtFieldReference<Class<Object>> fr = factory.Core().createFieldReference();
fr.setSimpleName("class");
fr.setType(ref);
fr.setDeclaringType(ref);

CtFieldRead<Class<Object>> fa = factory.Core().createFieldRead();
fa.setType(ref);
fa.setVariable(fr);

context.enter(fa, classLiteral);
return true;
context.enter(factory.Code().createClassAccess(references.getTypeReference(classLiteral.targetType)), classLiteral);
return false;
}

@Override
Expand Down Expand Up @@ -2285,9 +2283,6 @@ public boolean visit(Initializer initializer, MethodScope scope) {
public boolean visit(InstanceOfExpression instanceOfExpression, BlockScope scope) {
CtBinaryOperator<?> op = factory.Core().createBinaryOperator();
op.setKind(BinaryOperatorKind.INSTANCEOF);
CtLiteral<CtTypeReference<?>> l = factory.Core().createLiteral();
l.setValue(references.getBoundedTypeReference(instanceOfExpression.type.resolvedType));
op.setRightHandOperand(l);
context.enter(op, instanceOfExpression);
return true;
}
Expand Down Expand Up @@ -2546,14 +2541,25 @@ public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) {
return true;
}

@Override
public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
if (skipTypeInAnnotation) {
return true;
}
final CtTypeAccess<Object> typeAccess = factory.Core().createTypeAccess();
typeAccess.setType(references.getTypeReference(parameterizedQualifiedTypeReference.resolvedType));
context.enter(typeAccess, parameterizedQualifiedTypeReference);
return true;
}

@Override
public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
if (skipTypeInAnnotation) {
return true;
}
CtLiteral<CtTypeReference<?>> l = factory.Core().createLiteral();
l.setValue(references.getBoundedTypeReference(parameterizedQualifiedTypeReference.resolvedType));
context.enter(l, parameterizedQualifiedTypeReference);
final CtTypeAccess<Object> typeAccess = factory.Core().createTypeAccess();
typeAccess.setType(references.getTypeReference(parameterizedQualifiedTypeReference.resolvedType));
context.enter(typeAccess, parameterizedQualifiedTypeReference);
return true;
}

Expand All @@ -2562,9 +2568,9 @@ public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeRef
if (skipTypeInAnnotation) {
return true;
}
CtLiteral<CtTypeReference<?>> l = factory.Core().createLiteral();
l.setValue(references.getBoundedTypeReference(parameterizedSingleTypeReference.resolvedType));
context.enter(l, parameterizedSingleTypeReference);
final CtTypeAccess<Object> typeAccess = factory.Core().createTypeAccess();
typeAccess.setType(references.getTypeReference(parameterizedSingleTypeReference.resolvedType));
context.enter(typeAccess, parameterizedSingleTypeReference);
return true;
}

Expand All @@ -2573,9 +2579,9 @@ public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeRef
if (skipTypeInAnnotation) {
return true;
}
CtLiteral<CtTypeReference<?>> l = factory.Core().createLiteral();
l.setValue(references.getBoundedTypeReference(parameterizedSingleTypeReference.resolvedType));
context.enter(l, parameterizedSingleTypeReference);
final CtTypeAccess<Object> typeAccess = factory.Core().createTypeAccess();
typeAccess.setType(references.getTypeReference(parameterizedSingleTypeReference.resolvedType));
context.enter(typeAccess, parameterizedSingleTypeReference);
return super.visit(parameterizedSingleTypeReference, scope);
}

Expand Down Expand Up @@ -2771,9 +2777,9 @@ public boolean visit(QualifiedTypeReference arg0, BlockScope arg1) {
if (skipTypeInAnnotation) {
return true;
}
CtLiteral<CtTypeReference<?>> l = factory.Core().createLiteral();
l.setValue(references.getTypeReference(arg0.resolvedType));
context.enter(l, arg0);
final CtTypeAccess<Object> typeAccess = factory.Core().createTypeAccess();
typeAccess.setType(references.getTypeReference(arg0.resolvedType));
context.enter(typeAccess, arg0);
return true; // do nothing by default, keep traversing
}

Expand Down Expand Up @@ -2907,18 +2913,17 @@ public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope)
if (skipTypeInAnnotation) {
return true;
}
// if(context.annotationValueName.peek().equals("value")) return true;
CtLiteral<CtTypeReference<?>> l = factory.Core().createLiteral();
l.setValue(references.getTypeReference(singleTypeReference.resolvedType));
context.enter(l, singleTypeReference);
final CtTypeAccess<Object> typeAccess = factory.Core().createTypeAccess();
typeAccess.setType(references.getTypeReference(singleTypeReference.resolvedType));
context.enter(typeAccess, singleTypeReference);
return true; // do nothing by default, keep traversing
}

@Override
public boolean visit(SingleTypeReference singleTypeReference, ClassScope scope) {
CtLiteral<CtTypeReference<?>> l = factory.Core().createLiteral();
l.setValue(references.getTypeReference(singleTypeReference.resolvedType));
context.enter(l, singleTypeReference);
CtTypeAccess<Object> typeAccess = factory.Core().createTypeAccess();
typeAccess.setType(references.getTypeReference(singleTypeReference.resolvedType));
context.enter(typeAccess, singleTypeReference);
return true; // do nothing by default, keep traversing
}

Expand Down
5 changes: 1 addition & 4 deletions src/main/java/spoon/support/compiler/jdt/ParentExiter.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
import spoon.reflect.declaration.CtParameter;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtVariable;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.visitor.CtInheritanceScanner;

import java.util.ArrayList;
Expand Down Expand Up @@ -178,10 +177,8 @@ public <A extends java.lang.annotation.Annotation> void visitCtAnnotation(CtAnno
String name = this.jdtTreeBuilder.context.annotationValueName.peek();
Object value = child;

if (value instanceof CtVariableAccess) {
if (value instanceof CtVariableAccess && !"class".equals(((CtVariableAccess) value).getVariable().getSimpleName())) {
value = ((CtVariableAccess<?>) value).getVariable();
} else if (value instanceof CtFieldReference && ((CtFieldReference<?>) value).getSimpleName().equals("class")) {
value = ((CtFieldReference<?>) value).getType();
}
annotation.addValue(name, value);
super.visitCtAnnotation(annotation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import spoon.reflect.declaration.CtType;
import spoon.reflect.eval.PartialEvaluator;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.reference.CtReference;
import spoon.reflect.reference.CtTypeParameterReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.CtVisitor;
Expand All @@ -48,6 +47,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -131,8 +131,12 @@ public <T extends CtAnnotation<A>> T addValue(String elementName, Object value)
elementValues.put(elementName, value);
if (value instanceof CtElement) {
((CtElement) value).setParent(this);
} else if (value instanceof CtReference) {
((CtReference) value).setParent(this);
} else if (value instanceof Collection) {
for (Object element : (Collection) value) {
if (element instanceof CtElement) {
((CtElement) element).setParent(this);
}
}
}
} else {
Object o = elementValues.get(elementName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,12 +424,12 @@ public <T> void visitCtFieldWrite(CtFieldWrite<T> fieldWrite) {
}

private <T> void visitFieldAccess(CtFieldAccess<T> fieldAccess) {
if (fieldAccess.getVariable().getSimpleName().equals("class")) {
Class<?> c = fieldAccess.getVariable().getDeclaringType().getActualClass();
if (c != null) {
CtLiteral<Class<?>> l = fieldAccess.getFactory().Core().createLiteral();
l.setValue(c);
setResult(l);
if ("class".equals(fieldAccess.getVariable().getSimpleName())) {
Class<?> actualClass = fieldAccess.getVariable().getDeclaringType().getActualClass();
if (actualClass != null) {
CtLiteral<Class<?>> literal = fieldAccess.getFactory().Core().createLiteral();
literal.setValue(actualClass);
setResult(literal);
return;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import spoon.compiler.SpoonCompiler;
import spoon.reflect.code.CtExecutableReferenceExpression;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.declaration.CtClass;
Expand Down Expand Up @@ -121,7 +120,7 @@ public void testReferenceToAClassParametrizedConstructor() throws Exception {

assertTypedBy(Supplier.class, reference.getType());
assertTargetedBy(TEST_CLASS + "Type<java.lang.String>", reference.getTarget());
assertTrue(reference.getTarget() instanceof CtLiteral);
assertTrue(reference.getTarget() instanceof CtTypeAccess);
assertIsConstructorReference(reference.getExecutable());

assertIsWellPrinted(methodReference, reference);
Expand All @@ -134,7 +133,7 @@ public void testReferenceToAJavaUtilClassConstructor() throws Exception {

assertTypedBy(Supplier.class, reference.getType());
assertTargetedBy("java.util.HashSet<" + TEST_CLASS + "Person>", reference.getTarget());
assertTrue(reference.getTarget() instanceof CtLiteral);
assertTrue(reference.getTarget() instanceof CtTypeAccess);
assertIsConstructorReference(reference.getExecutable());

assertIsWellPrinted(methodReference, reference);
Expand Down
Loading