GROOVY-8226: JSR308 initial plumbing tweaks (closes #560, side effect: closes #546)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/c29cf2f3 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/c29cf2f3 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/c29cf2f3 Branch: refs/heads/GROOVY_2_5_X Commit: c29cf2f309d71ea96b0503a2052d6ceb4201f872 Parents: 63aab7a Author: paulk <pa...@asert.com.au> Authored: Mon Jun 12 20:10:50 2017 +1000 Committer: paulk <pa...@asert.com.au> Committed: Mon Jun 19 16:07:55 2017 +1000 ---------------------------------------------------------------------- .../org/codehaus/groovy/ast/AnnotationNode.java | 15 ++++++----- .../groovy/ast/decompiled/Annotations.java | 4 +-- .../org/codehaus/groovy/vmplugin/VMPlugin.java | 5 ++-- .../org/codehaus/groovy/vmplugin/v5/Java5.java | 8 +++++- .../org/codehaus/groovy/vmplugin/vm8/Java8.java | 12 +++++++++ src/test/gls/annotations/AnnotationTest.groovy | 26 ++++++++++++++++++++ 6 files changed, 59 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/c29cf2f3/src/main/org/codehaus/groovy/ast/AnnotationNode.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/ast/AnnotationNode.java b/src/main/org/codehaus/groovy/ast/AnnotationNode.java index e00f977..c493299 100644 --- a/src/main/org/codehaus/groovy/ast/AnnotationNode.java +++ b/src/main/org/codehaus/groovy/ast/AnnotationNode.java @@ -25,12 +25,8 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; - /** * Represents an annotation which can be attached to interfaces, classes, methods and fields. - * - * @author <a href="mailto:jstrac...@protique.com">James Strachan</a> - * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a> */ public class AnnotationNode extends ASTNode { public static final int CONSTRUCTOR_TARGET = 1 << 1; @@ -40,10 +36,13 @@ public class AnnotationNode extends ASTNode { public static final int LOCAL_VARIABLE_TARGET = 1 << 5; public static final int ANNOTATION_TARGET = 1 << 6; public static final int PACKAGE_TARGET = 1 << 7; + public static final int TYPE_PARAMETER_TARGET = 1 << 8; + public static final int TYPE_USE_TARGET = 1 << 9; public static final int TYPE_TARGET = 1 + ANNOTATION_TARGET; //GROOVY-7151 private static final int ALL_TARGETS = TYPE_TARGET | CONSTRUCTOR_TARGET | METHOD_TARGET - | FIELD_TARGET | PARAMETER_TARGET | LOCAL_VARIABLE_TARGET | ANNOTATION_TARGET | PACKAGE_TARGET; - + | FIELD_TARGET | PARAMETER_TARGET | LOCAL_VARIABLE_TARGET | ANNOTATION_TARGET + | PACKAGE_TARGET | TYPE_PARAMETER_TARGET | TYPE_USE_TARGET; + private final ClassNode classNode; private Map<String, Expression> members; private boolean runtimeRetention= false, sourceRetention= false, classRetention = false; @@ -179,6 +178,10 @@ public class AnnotationNode extends ASTNode { return "ANNOTATION"; case PACKAGE_TARGET: return "PACKAGE"; + case TYPE_PARAMETER_TARGET: + return "TYPE_PARAMETER"; + case TYPE_USE_TARGET: + return "TYPE_USE"; default: return "unknown target"; } http://git-wip-us.apache.org/repos/asf/groovy/blob/c29cf2f3/src/main/org/codehaus/groovy/ast/decompiled/Annotations.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/ast/decompiled/Annotations.java b/src/main/org/codehaus/groovy/ast/decompiled/Annotations.java index ce64070..15c0a22 100644 --- a/src/main/org/codehaus/groovy/ast/decompiled/Annotations.java +++ b/src/main/org/codehaus/groovy/ast/decompiled/Annotations.java @@ -21,6 +21,7 @@ package org.codehaus.groovy.ast.decompiled; import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.expr.*; +import org.codehaus.groovy.vmplugin.VMPluginFactory; import org.codehaus.groovy.vmplugin.v5.Java5; import org.objectweb.asm.Type; @@ -97,9 +98,8 @@ class Annotations { synchronized (initLock) { if (!lazyInitDone) { for (AnnotationNode annotation : getClassNode().getAnnotations()) { - Java5.configureAnnotationFromDefinition(annotation, this); + VMPluginFactory.getPlugin().configureAnnotationNodeFromDefinition(annotation, this); } - lazyInitDone = true; } } http://git-wip-us.apache.org/repos/asf/groovy/blob/c29cf2f3/src/main/org/codehaus/groovy/vmplugin/VMPlugin.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/vmplugin/VMPlugin.java b/src/main/org/codehaus/groovy/vmplugin/VMPlugin.java index 3ca6bdd..d139307 100644 --- a/src/main/org/codehaus/groovy/vmplugin/VMPlugin.java +++ b/src/main/org/codehaus/groovy/vmplugin/VMPlugin.java @@ -32,6 +32,7 @@ public interface VMPlugin { void setAdditionalClassInformation(ClassNode c); Class[] getPluginDefaultGroovyMethods(); Class[] getPluginStaticGroovyMethods(); + void configureAnnotationNodeFromDefinition(AnnotationNode definition, AnnotationNode root); void configureAnnotation(AnnotationNode an); void configureClassNode(CompileUnit compileUnit, ClassNode classNode); void invalidateCallSites(); @@ -54,8 +55,8 @@ public interface VMPlugin { Object invokeHandle(Object handle, Object[] args) throws Throwable; /** - * Gives the version the plguin is made for - * @return 5 for jdk5, 6 for jdk6, 7 for jdk7 or higher + * Gives the version the plugin is made for + * @return 5 for jdk5, 6 for jdk6, 7 for jdk7, 8 for jdk8 or higher */ int getVersion(); http://git-wip-us.apache.org/repos/asf/groovy/blob/c29cf2f3/src/main/org/codehaus/groovy/vmplugin/v5/Java5.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/vmplugin/v5/Java5.java b/src/main/org/codehaus/groovy/vmplugin/v5/Java5.java index 4e9359b..8e4fe7f 100644 --- a/src/main/org/codehaus/groovy/vmplugin/v5/Java5.java +++ b/src/main/org/codehaus/groovy/vmplugin/v5/Java5.java @@ -36,6 +36,7 @@ import org.codehaus.groovy.ast.expr.ListExpression; import org.codehaus.groovy.ast.expr.PropertyExpression; import org.codehaus.groovy.ast.stmt.ReturnStatement; import org.codehaus.groovy.vmplugin.VMPlugin; +import org.codehaus.groovy.vmplugin.VMPluginFactory; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; @@ -211,7 +212,12 @@ public class Java5 implements VMPlugin { } } + @Deprecated public static void configureAnnotationFromDefinition(AnnotationNode definition, AnnotationNode root) { + VMPluginFactory.getPlugin().configureAnnotationNodeFromDefinition(definition, root); + } + + public void configureAnnotationNodeFromDefinition(AnnotationNode definition, AnnotationNode root) { ClassNode type = definition.getClassNode(); if ("java.lang.annotation.Retention".equals(type.getName())) { Expression exp = definition.getMember("value"); @@ -318,7 +324,7 @@ public class Java5 implements VMPlugin { } } - private static int getElementCode(ElementType value) { + protected int getElementCode(ElementType value) { switch (value) { case TYPE: return AnnotationNode.TYPE_TARGET; http://git-wip-us.apache.org/repos/asf/groovy/blob/c29cf2f3/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java index 905af38..4656af1 100644 --- a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java +++ b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java @@ -18,8 +18,10 @@ */ package org.codehaus.groovy.vmplugin.vm8; +import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.vmplugin.v7.Java7; +import java.lang.annotation.ElementType; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -51,4 +53,14 @@ public class Java8 extends Java7 { return 8; } + @Override + protected int getElementCode(ElementType value) { + switch (value) { + case TYPE_PARAMETER: + return AnnotationNode.TYPE_PARAMETER_TARGET; + case TYPE_USE: + return AnnotationNode.TYPE_USE_TARGET; + } + return super.getElementCode(value); + } } http://git-wip-us.apache.org/repos/asf/groovy/blob/c29cf2f3/src/test/gls/annotations/AnnotationTest.groovy ---------------------------------------------------------------------- diff --git a/src/test/gls/annotations/AnnotationTest.groovy b/src/test/gls/annotations/AnnotationTest.groovy index a63e0bd..80e4242 100644 --- a/src/test/gls/annotations/AnnotationTest.groovy +++ b/src/test/gls/annotations/AnnotationTest.groovy @@ -678,6 +678,32 @@ class AnnotationTest extends CompilableTestSupport { ''' } + // GROOVY-8226 + void testAnnotationOnParameterType() { + assertScript ''' + import java.lang.annotation.* + import static java.lang.annotation.ElementType.* + import static java.lang.annotation.RetentionPolicy.* + + @Target([PARAMETER, FIELD, METHOD, ANNOTATION_TYPE, TYPE_USE]) + @Retention(RUNTIME) + public @interface NonNull { } + + class Foo { + @NonNull public Integer foo + @NonNull public Integer bar(@NonNull String baz) {} + } + + def expected = '@NonNull()' + def foo = Foo.getField('foo') + assert foo.annotations[0].toString() == expected + def bar = Foo.getMethod('bar', String) + assert bar.annotations[0].toString() == expected + def baz = bar.parameters[0] + assert baz.annotations[0].toString() == expected + ''' + } + //Parametrized tests in Spock would allow to make it much more readable private static String codeWithMetaAnnotationWithTarget(String targetElementTypeName) { """