Skip to content

Commit

Permalink
Merge pull request #530 from GerardPaligot/fix_529
Browse files Browse the repository at this point in the history
  • Loading branch information
monperrus committed Feb 12, 2016
2 parents f4df7b2 + c21274e commit 0a2050b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/main/java/spoon/reflect/declaration/CtType.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public interface CtType<T> extends CtNamedElement, CtTypeInformation, CtTypeMemb
* The string separator in a Java innertype qualified name.
*/
String INNERTTYPE_SEPARATOR = "$";
/**
* Used in no classpath when we don't have any information to build the name of the type.
*/
String NAME_UNKNOWN = "<unknown>";

/**
* Returns the simple (unqualified) name of this element.
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2558,7 +2558,7 @@ public boolean visit(MarkerAnnotation annotation, BlockScope scope) {

private <A extends java.lang.annotation.Annotation> boolean visitMarkerAnnoation(MarkerAnnotation annotation, BlockScope scope) {
CtAnnotation<A> a = factory.Core().createAnnotation();
CtTypeReference<A> t = references.getTypeReference(annotation.resolvedType);
CtTypeReference<A> t = references.getTypeReference(annotation.resolvedType, annotation.type);
a.setAnnotationType(t);
context.enter(a, annotation);
skipTypeInAnnotation = true;
Expand Down Expand Up @@ -2738,7 +2738,7 @@ public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
}

private boolean isContainsInTypeAnnotation(TypeBinding binding, Annotation a) {
return !binding.hasTypeAnnotations() || !containsInTypeAnnotation(a, binding.getTypeAnnotations());
return binding == null || !binding.hasTypeAnnotations() || !containsInTypeAnnotation(a, binding.getTypeAnnotations());
}

private boolean containsInTypeAnnotation(Annotation a, AnnotationBinding[] typeAnnotations) {
Expand Down Expand Up @@ -3379,6 +3379,7 @@ public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
if (localTypeDeclaration.binding == null) {
// no classpath mode but JDT returns nothing. We create an empty class.
t = factory.Core().createClass();
t.setSimpleName(CtType.NAME_UNKNOWN);
((CtClass) t).setSuperclass(references.getTypeReference(null, localTypeDeclaration.allocation.type));
} else {
t = createType(localTypeDeclaration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtNewClass;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtTypeReference;
Expand Down Expand Up @@ -161,7 +162,7 @@ public void testCtNewClassInNoClasspath() throws Exception {
assertEquals("Lock$With", anonymousClass.getSuperclass().getQualifiedName());
assertEquals("Lock", anonymousClass.getSuperclass().getDeclaringType().getSimpleName());
assertEquals("Lock.With", anonymousClass.getSuperclass().toString());
assertNull(anonymousClass.getSimpleName()); // In noclasspath, we don't have this information.
assertEquals(CtType.NAME_UNKNOWN, anonymousClass.getSimpleName()); // In noclasspath, we don't have this information.
assertEquals(1, anonymousClass.getMethods().size());

canBeBuilt("./target/new-class", 8, true);
Expand Down
35 changes: 35 additions & 0 deletions src/test/java/spoon/test/reference/TypeReferenceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import spoon.compiler.SpoonResourceHelper;
import spoon.reflect.code.CtFieldRead;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtNewClass;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtInterface;
Expand Down Expand Up @@ -392,6 +393,40 @@ public void testInvocationWithFieldAccessInNoClasspath() throws Exception {
canBeBuilt("./src/test/resources/noclasspath/TestBot.java", 8, true);
}

@Test
public void testAnnotationOnMethodWithPrimitiveReturnTypeInNoClasspath() throws Exception {
// contract: In no classpath mode, if we have an annotation declared on a method and overridden
// from a super class in an anonymous class, we should rewrite correctly the annotation and don't
// throw a NPE.
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/resources/noclasspath/A.java");
launcher.setSourceOutputDirectory("./target/class-declaration");
launcher.getEnvironment().setNoClasspath(true);
launcher.run();

final CtClass<Object> aClass = launcher.getFactory().Class().get("A");
final CtClass anonymousClass = aClass.getElements(new TypeFilter<>(CtNewClass.class)).get(0).getAnonymousClass();
final CtMethod run = anonymousClass.getMethod("run");
assertNotNull(run);
assertEquals(1, run.getAnnotations().size());
assertEquals("@Override" + System.lineSeparator(), run.getAnnotations().get(0).toString());
}

@Test
public void testAnonymousClassesHaveAnEmptyStringForItsNameInNoClasspath() throws Exception {
// contract: In no classpath mode, a type reference have an empty string for its name.
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/resources/noclasspath/A.java");
launcher.setSourceOutputDirectory("./target/class-declaration");
launcher.getEnvironment().setNoClasspath(true);
launcher.run();

final CtClass<Object> aClass = launcher.getFactory().Class().get("A");
final CtClass anonymousClass = aClass.getElements(new TypeFilter<>(CtNewClass.class)).get(0).getAnonymousClass();
assertEquals(CtType.NAME_UNKNOWN, anonymousClass.getReference().getSimpleName());
assertEquals(7, aClass.getReferencedTypes().size());
}

class A {
class Tacos<K> {
}
Expand Down
18 changes: 18 additions & 0 deletions src/test/resources/noclasspath/A.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import example.B;

class A extends B {

private Runnable runnable;

public void foo() {
synchronized (lock) {
runnable = new Runnable() {

@Override
public void run() {

}
};
}
}
}

0 comments on commit 0a2050b

Please sign in to comment.