Skip to content

Commit

Permalink
feat(annot): Reference to an annotation field as an invocation. (#660)
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardPaligot authored and monperrus committed May 11, 2016
1 parent 0b3390f commit 92a1975
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
*/
package spoon.support.reflect.declaration;

import spoon.reflect.code.CtComment;
import spoon.reflect.declaration.CtAnnotation;
import spoon.reflect.declaration.CtAnnotationType;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtFormalTypeDeclarer;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
Expand All @@ -30,6 +33,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

/**
* The implementation for {@link spoon.reflect.declaration.CtAnnotationType}.
Expand All @@ -44,6 +48,62 @@ public void accept(CtVisitor v) {
v.visitCtAnnotationType(this);
}

private <R> CtMethod<R> createGhostMethod(CtField<R> field) {
final CtMethod<R> method = factory.Core().createMethod();
method.setImplicit(true);
method.setSimpleName(field.getSimpleName());
method.setModifiers(field.getModifiers());
method.setType(factory.Core().clone(field.getType()));
for (CtAnnotation<? extends Annotation> ctAnnotation : field.getAnnotations()) {
method.addAnnotation(factory.Core().clone(ctAnnotation));
}
for (CtComment ctComment : field.getComments()) {
method.addComment(factory.Core().clone(ctComment));
}
method.setDocComment(field.getDocComment());
method.setPosition(field.getPosition());
method.setShadow(field.isShadow());
return method;
}

private <R> void addGhostMethod(CtField<R> field) {
super.addMethod(createGhostMethod(field));
}

@Override
public <F, C extends CtType<T>> C addField(CtField<F> field) {
addGhostMethod(field);
return super.addField(field);
}

@Override
public <F, C extends CtType<T>> C addField(int index, CtField<F> field) {
addGhostMethod(field);
return super.addField(index, field);
}

@Override
public <F, C extends CtType<T>> C addFieldAtTop(CtField<F> field) {
addGhostMethod(field);
return super.addFieldAtTop(field);
}

@Override
public <C extends CtType<T>> C setFields(List<CtField<?>> fields) {
Set<CtMethod<?>> methods = new TreeSet<CtMethod<?>>();
for (CtField<?> field : fields) {
methods.add(createGhostMethod(field));
}
super.setMethods(methods);
return super.setFields(fields);
}

@Override
public <F> boolean removeField(CtField<F> field) {
super.removeMethod(createGhostMethod(field));
return super.removeField(field);
}

@Override
public Set<CtTypeReference<?>> getSuperInterfaces() {
return Collections.emptySet();
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/spoon/support/visitor/SignaturePrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ public <T> void visitCtMethod(CtMethod<T> m) {
}
write("> ");
}
write(m.getType().getQualifiedName());
if (m.getType() != null) {
write(m.getType().getQualifiedName());
}
write(" ");
write(m.getSimpleName());
write("(");
Expand Down
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 @@ -318,7 +318,7 @@ public void testAnnotatedElementTypes() throws Exception {
CtAnnotationType<?> annotationType = pkg.getType("Bound");
assertEquals(Bound.class, annotationType.getActualClass());
assertNull(annotationType.getSuperclass());
assertEquals(0,annotationType.getAllMethods().size());
assertEquals(annotationType.getFields().size(),annotationType.getAllMethods().size());
assertEquals(0,annotationType.getSuperInterfaces().size());

annotations = annotationType.getAnnotations();
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/spoon/test/main/MainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public <T> void visitCtTypeReference(CtTypeReference<T> reference) {
@Override
public <T> void visitCtExecutableReference(CtExecutableReference<T> reference) {
assertNotNull(reference);
if (isLanguageExecutable(reference) || isDeclaredInAnAnnotation(reference)) {
if (isLanguageExecutable(reference)) {
super.visitCtExecutableReference(reference);
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package spoon.test.reference;

import org.junit.Test;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.factory.Factory;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.test.reference.testclasses.Mole;
import spoon.test.reference.testclasses.Parameter;
import spoon.testing.utils.ModelUtils;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class AnnotationFieldReferenceTest {
@Test
public void testAnnotationFieldReference() throws Exception {
final Factory factory = ModelUtils.build(Parameter.class, Mole.class);
final CtMethod<Object> make = factory.Class().get(Mole.class).getMethod("make", factory.Type().createReference(Parameter.class));
final CtInvocation<?> annotationInv = make.getElements(new TypeFilter<CtInvocation<?>>(CtInvocation.class)).get(0);
final CtExecutable<?> executableDeclaration = annotationInv.getExecutable().getExecutableDeclaration();
assertNotNull(executableDeclaration);
final CtField<?> value = factory.Annotation().get(Parameter.class).getField("value");
assertNotNull(value);
assertEquals(value.getSimpleName(), executableDeclaration.getSimpleName());
assertEquals(value.getType(), executableDeclaration.getType());
}
}
7 changes: 7 additions & 0 deletions src/test/java/spoon/test/reference/testclasses/Mole.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package spoon.test.reference.testclasses;

public class Mole {
private void make(Parameter p) {
p.value();
}
}
5 changes: 5 additions & 0 deletions src/test/java/spoon/test/reference/testclasses/Parameter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package spoon.test.reference.testclasses;

public @interface Parameter {
String value();
}

0 comments on commit 92a1975

Please sign in to comment.