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 <[email protected]> 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' + } +}
