You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/07/05 16:35:47 UTC
[groovy] 02/02: GROOVY-9871: class model: populate `AnnotationConstantExpression` values
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 842687fa68ade49549fd8c076eca4ffec4c93d70
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Jul 5 11:17:08 2022 -0500
GROOVY-9871: class model: populate `AnnotationConstantExpression` values
---
.../org/codehaus/groovy/vmplugin/v8/Java8.java | 99 ++++++++++++----------
.../ast/{Groovy7826Bug.java => Groovy7826.java} | 28 +++---
src/test/org/codehaus/groovy/ast/Groovy9871.groovy | 46 ++++++++++
3 files changed, 116 insertions(+), 57 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
index 51a6c3538c..81b060ebfe 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
@@ -35,6 +35,7 @@ import org.codehaus.groovy.ast.GenericsType;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.PackageNode;
import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
@@ -291,40 +292,7 @@ public class Java8 implements VMPlugin {
return gts;
}
- private void setAnnotationMetaData(final Annotation[] annotations, final AnnotatedNode an) {
- for (Annotation annotation : annotations) {
- AnnotationNode node = new AnnotationNode(ClassHelper.make(annotation.annotationType()));
- configureAnnotation(node, annotation);
- an.addAnnotation(node);
- }
- }
-
- @Override
- public void configureAnnotationNodeFromDefinition(final AnnotationNode definition, final AnnotationNode root) {
- ClassNode type = definition.getClassNode();
- final String typeName = type.getName();
- if ("java.lang.annotation.Retention".equals(typeName)) {
- Expression exp = definition.getMember("value");
- if (!(exp instanceof PropertyExpression)) return;
- PropertyExpression pe = (PropertyExpression) exp;
- String name = pe.getPropertyAsString();
- RetentionPolicy policy = RetentionPolicy.valueOf(name);
- setRetentionPolicy(policy, root);
- } else if ("java.lang.annotation.Target".equals(typeName)) {
- Expression exp = definition.getMember("value");
- if (!(exp instanceof ListExpression)) return;
- ListExpression le = (ListExpression) exp;
- int bitmap = 0;
- for (Expression e : le.getExpressions()) {
- if (!(e instanceof PropertyExpression)) return;
- PropertyExpression element = (PropertyExpression) e;
- String name = element.getPropertyAsString();
- ElementType value = ElementType.valueOf(name);
- bitmap |= getElementCode(value);
- }
- root.setAllowedTargets(bitmap);
- }
- }
+ //
@Override
public void configureAnnotation(final AnnotationNode node) {
@@ -367,37 +335,80 @@ public class Java8 implements VMPlugin {
for (Method declaredMethod : declaredMethods) {
try {
Object value = declaredMethod.invoke(annotation);
- Expression valueExpression = annotationValueToExpression(value);
- if (valueExpression == null)
- continue;
- node.setMember(declaredMethod.getName(), valueExpression);
+ Expression valueExpression = toAnnotationValueExpression(value);
+ if (valueExpression != null) node.setMember(declaredMethod.getName(), valueExpression);
+
} catch (IllegalAccessException | InvocationTargetException ignore) {
}
}
}
}
- private Expression annotationValueToExpression(final Object value) {
+ private void setAnnotationMetaData(final Annotation[] annotations, final AnnotatedNode target) {
+ for (Annotation annotation : annotations) {
+ target.addAnnotation(toAnnotationNode(annotation));
+ }
+ }
+
+ private AnnotationNode toAnnotationNode(final Annotation annotation) {
+ ClassNode type = ClassHelper.make(annotation.annotationType());
+ AnnotationNode node = new AnnotationNode(type);
+ configureAnnotation(node, annotation);
+ return node;
+ }
+
+ private Expression toAnnotationValueExpression(final Object value) {
if (value == null || value instanceof String || value instanceof Number || value instanceof Character || value instanceof Boolean)
return new ConstantExpression(value);
if (value instanceof Class)
return new ClassExpression(ClassHelper.makeWithoutCaching((Class<?>)value));
+ if (value instanceof Annotation)
+ return new AnnotationConstantExpression(toAnnotationNode((Annotation)value));
+
if (value instanceof Enum)
return new PropertyExpression(new ClassExpression(ClassHelper.makeWithoutCaching(value.getClass())), value.toString());
if (value.getClass().isArray()) {
- ListExpression elementExprs = new ListExpression();
- int len = Array.getLength(value);
- for (int i = 0; i != len; i += 1)
- elementExprs.addExpression(annotationValueToExpression(Array.get(value, i)));
- return elementExprs;
+ ListExpression list = new ListExpression();
+ for (int i = 0, n = Array.getLength(value); i < n; i += 1)
+ list.addExpression(toAnnotationValueExpression(Array.get(value, i)));
+ return list;
}
return null;
}
+ //
+
+ @Override
+ public void configureAnnotationNodeFromDefinition(final AnnotationNode definition, final AnnotationNode root) {
+ ClassNode type = definition.getClassNode();
+ final String typeName = type.getName();
+ if ("java.lang.annotation.Retention".equals(typeName)) {
+ Expression exp = definition.getMember("value");
+ if (!(exp instanceof PropertyExpression)) return;
+ PropertyExpression pe = (PropertyExpression) exp;
+ String name = pe.getPropertyAsString();
+ RetentionPolicy policy = RetentionPolicy.valueOf(name);
+ setRetentionPolicy(policy, root);
+ } else if ("java.lang.annotation.Target".equals(typeName)) {
+ Expression exp = definition.getMember("value");
+ if (!(exp instanceof ListExpression)) return;
+ ListExpression le = (ListExpression) exp;
+ int bitmap = 0;
+ for (Expression e : le.getExpressions()) {
+ if (!(e instanceof PropertyExpression)) return;
+ PropertyExpression element = (PropertyExpression) e;
+ String name = element.getPropertyAsString();
+ ElementType value = ElementType.valueOf(name);
+ bitmap |= getElementCode(value);
+ }
+ root.setAllowedTargets(bitmap);
+ }
+ }
+
@Override
public void configureClassNode(final CompileUnit compileUnit, final ClassNode classNode) {
try {
diff --git a/src/test/org/codehaus/groovy/ast/Groovy7826Bug.java b/src/test/org/codehaus/groovy/ast/Groovy7826.java
similarity index 61%
rename from src/test/org/codehaus/groovy/ast/Groovy7826Bug.java
rename to src/test/org/codehaus/groovy/ast/Groovy7826.java
index ed6b4ab596..fb8745c52a 100644
--- a/src/test/org/codehaus/groovy/ast/Groovy7826Bug.java
+++ b/src/test/org/codehaus/groovy/ast/Groovy7826.java
@@ -19,23 +19,25 @@
package org.codehaus.groovy.ast;
import groovy.lang.GroovyShell;
-import groovy.test.GroovyTestCase;
import org.codehaus.groovy.control.CompilerConfiguration;
+import org.junit.Test;
-public class Groovy7826Bug extends GroovyTestCase {
- public void testComplexTypeArguments() throws Exception {
- String script = "def f(org.codehaus.groovy.ast.Groovy7826Bug.C1 c1) { }";
+public final class Groovy7826 {
- CompilerConfiguration config = new CompilerConfiguration();
- config.getOptimizationOptions().put("asmResolving", false);
+ @Test
+ public void testComplexTypeArguments() throws Exception {
+ String script = "def f(" + getClass().getName() + ".C1 c1) { }";
- GroovyShell shell = new GroovyShell(config);
- shell.evaluate(script, "bug7826.groovy");
- }
+ CompilerConfiguration config = new CompilerConfiguration();
+ config.getOptimizationOptions().put("asmResolving", false);
- public static class C1<T2 extends C2<T2, T1>, T1 extends C1<T2, T1>> {
- }
+ GroovyShell shell = new GroovyShell(config);
+ shell.evaluate(script, "bug7826.groovy");
+ }
- public static class C2<T2 extends C2<T2, T1>, T1 extends C1<T2, T1>> {
- }
+ public static class C1<T2 extends C2<T2, T1>, T1 extends C1<T2, T1>> {
+ }
+
+ public static class C2<T2 extends C2<T2, T1>, T1 extends C1<T2, T1>> {
+ }
}
diff --git a/src/test/org/codehaus/groovy/ast/Groovy9871.groovy b/src/test/org/codehaus/groovy/ast/Groovy9871.groovy
new file mode 100644
index 0000000000..8ff8d14fc5
--- /dev/null
+++ b/src/test/org/codehaus/groovy/ast/Groovy9871.groovy
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.codehaus.groovy.ast
+
+import org.codehaus.groovy.ast.expr.AnnotationConstantExpression
+import org.codehaus.groovy.ast.expr.Expression
+import org.codehaus.groovy.ast.expr.ListExpression
+import org.junit.Test
+
+final class Groovy9871 {
+
+ @Test
+ void testAnnotationConstantExpression() {
+ ClassNode cn = new ClassNode(org.codehaus.groovy.runtime.ResourceGroovyMethods)
+ // method with @NamedParam annotations that should be wrapped in @NamedParams container
+ MethodNode mn = cn.getMethod('getText', new Parameter(ClassHelper.make(URL), 'url'), new Parameter(ClassHelper.MAP_TYPE, 'map'))
+
+ List<AnnotationNode> annotations = mn.parameters[1].annotations
+
+ assert annotations.size() == 1
+ assert annotations[0].classNode.name == 'groovy.transform.NamedParams'
+ assert annotations[0].members.value instanceof ListExpression
+
+ List<Expression> expressions = annotations[0].members.value.expressions
+
+ assert expressions.size() > 1 // 5 currently
+ assert expressions[0] instanceof AnnotationConstantExpression
+ assert expressions[0].type.name == 'groovy.transform.NamedParam'
+ }
+}