[groovy] branch master updated: Rework check for runtime retention of repeatable annotation collector

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[groovy] branch master updated: Rework check for runtime retention of repeatable annotation collector

Daniel.Sun
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new c2ea336  Rework check for runtime retention of repeatable annotation collector
c2ea336 is described below

commit c2ea336d935beb62da4977e82714261c182b69dd
Author: Eric Milles <[hidden email]>
AuthorDate: Tue Nov 5 10:59:25 2019 -0600

    Rework check for runtime retention of repeatable annotation collector
   
    - if repeatee has runtime retention, collector must as well
    - if repeatable isn't resolved, evaluateExpression will handle aliasing
---
 .../codehaus/groovy/classgen/ExtendedVerifier.java | 44 +++++++++++-----------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java b/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
index 3402886..57f13b1 100644
--- a/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
@@ -51,10 +51,12 @@ import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
+import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.evaluateExpression;
 
 /**
  * A specialized Groovy AST visitor meant to perform additional verifications upon the
@@ -177,10 +179,10 @@ public class ExtendedVerifier extends ClassCodeVisitorSupport {
                 seen.add(visited);
                 nonSourceAnnotations.put(name, seen);
             }
-            boolean isTargetAnnotation = name.equals("java.lang.annotation.Target");
 
             // Check if the annotation target is correct, unless it's the target annotating an annotation definition
             // defining on which target elements the annotation applies
+            boolean isTargetAnnotation = name.equals("java.lang.annotation.Target");
             if (!isTargetAnnotation && !visited.isTargetAllowed(target)) {
                 addError("Annotation @" + name + " is not allowed on element " + AnnotationNode.targetToName(target), visited);
             }
@@ -206,28 +208,26 @@ public class ExtendedVerifier extends ClassCodeVisitorSupport {
                 }
                 if (repeatable != null) {
                     AnnotationNode collector = new AnnotationNode(repeatable);
-                    if (repeatable.isResolved()) {
+                    if (repeatee.hasRuntimeRetention()) {
+                        collector.setRuntimeRetention(true);
+                    } else if (repeatable.isResolved()) {
                         Class<?> repeatableType = repeatable.getTypeClass();
-                        Retention retAnn = repeatableType.getAnnotation(Retention.class);
-                        collector.setRuntimeRetention(retAnn != null && retAnn.value().equals(RetentionPolicy.RUNTIME));
-                    } else if (repeatable.redirect() != null) {
-                        for (AnnotationNode annotationNode : repeatable.redirect().getAnnotations()) {
-                            if (!annotationNode.getClassNode().getName().equals("java.lang.annotation.Retention"))
-                                continue;
-                            String value = annotationNode.getMember("value").getText();
-                            collector.setRuntimeRetention(value.equals(RetentionPolicy.RUNTIME.name()) ||
-                                    value.equals(RetentionPolicy.class.getName() + "." + RetentionPolicy.RUNTIME.name()));
+                        Retention retention = repeatableType.getAnnotation(Retention.class);
+                        collector.setRuntimeRetention(retention != null && retention.value().equals(RetentionPolicy.RUNTIME));
+                    } else {
+                        for (AnnotationNode annotation : repeatable.getAnnotations()) {
+                            if (annotation.getClassNode().getName().equals("java.lang.annotation.Retention")) {
+                                Expression value = annotation.getMember("value"); assert value != null;
+                                Object retention = evaluateExpression(value, source.getConfiguration());
+                                collector.setRuntimeRetention(retention != null && retention.toString().equals("RUNTIME"));
+                                break;
+                            }
                         }
                     }
-
-                    List<Expression> annos = new ArrayList<>();
-                    for (AnnotationNode an : next.getValue()) {
-                        annos.add(new AnnotationConstantExpression(an));
-                    }
-                    collector.addMember("value", new ListExpression(annos));
-
-                    node.addAnnotation(collector);
+                    collector.addMember("value", new ListExpression(next.getValue().stream()
+                        .map(AnnotationConstantExpression::new).collect(Collectors.toList())));
                     node.getAnnotations().removeAll(next.getValue());
+                    node.addAnnotation(collector);
                 }
             }
         }
@@ -250,8 +250,8 @@ public class ExtendedVerifier extends ClassCodeVisitorSupport {
 
     // TODO GROOVY-5011 handle case of @Override on a property
     private void visitOverride(AnnotatedNode node, AnnotationNode visited) {
-        ClassNode annotationClassNode = visited.getClassNode();
-        if (annotationClassNode.isResolved() && annotationClassNode.getName().equals("java.lang.Override")) {
+        ClassNode annotationType = visited.getClassNode();
+        if (annotationType.isResolved() && annotationType.getName().equals("java.lang.Override")) {
             if (node instanceof MethodNode && !Boolean.TRUE.equals(node.getNodeMetaData(Verifier.DEFAULT_PARAMETER_GENERATED))) {
                 boolean override = false;
                 MethodNode origMethod = (MethodNode) node;
@@ -288,7 +288,7 @@ public class ExtendedVerifier extends ClassCodeVisitorSupport {
                 MethodNode found = getDeclaredMethodCorrected(genericsSpec, mn, correctedNext);
                 if (found != null) break;
             }
-            List<ClassNode> ifaces = new ArrayList<ClassNode>(Arrays.asList(next.getInterfaces()));
+            List<ClassNode> ifaces = new ArrayList<>(Arrays.asList(next.getInterfaces()));
             while (!ifaces.isEmpty()) {
                 ClassNode origInterface = ifaces.remove(0);
                 if (!origInterface.equals(ClassHelper.OBJECT_TYPE)) {

Apache Groovy committer & PMC member

Blog: http://blog.sunlan.me
Twitter: @daniel_sun