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/11/08 15:48:59 UTC
[groovy] branch GROOVY_3_0_X updated: GROOVY-9541: STC: add `GroovyClassLoader` to `evaluateExpression` params
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
new 2d5e383a58 GROOVY-9541: STC: add `GroovyClassLoader` to `evaluateExpression` params
2d5e383a58 is described below
commit 2d5e383a586e193d1219136bd615a5a987ce0ee2
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Nov 8 08:29:06 2022 -0600
GROOVY-9541: STC: add `GroovyClassLoader` to `evaluateExpression` params
3_0_X backport
---
.../ASTTransformationCollectorCodeVisitor.java | 4 +-
.../transform/stc/StaticTypeCheckingSupport.java | 53 +++++++++++++++++-----
2 files changed, 44 insertions(+), 13 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java b/src/main/java/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java
index 8638b7286e..d940f0a3db 100644
--- a/src/main/java/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java
@@ -183,7 +183,7 @@ public class ASTTransformationCollectorCodeVisitor extends ClassCodeVisitorSuppo
if (annotation.getClassNode().getName().equals(AnnotationCollector.class.getName())) {
Expression mode = annotation.getMember("mode");
modes.put(index, Optional.ofNullable(mode)
- .map(exp -> evaluateExpression(exp, source.getConfiguration()))
+ .map(exp -> evaluateExpression(exp, source.getConfiguration(), transformLoader))
.map(val -> (AnnotationCollectorMode) val)
.orElse(AnnotationCollectorMode.DUPLICATE)
);
@@ -191,7 +191,7 @@ public class ASTTransformationCollectorCodeVisitor extends ClassCodeVisitorSuppo
Expression processor = annotation.getMember("processor");
AnnotationCollectorTransform act = null;
if (processor != null) {
- String className = (String) evaluateExpression(processor, source.getConfiguration());
+ String className = (String) evaluateExpression(processor, source.getConfiguration(), transformLoader);
Class<?> klass = loadTransformClass(className, alias);
if (klass != null) {
try {
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 4420f87aec..9d6f028ba9 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -18,6 +18,7 @@
*/
package org.codehaus.groovy.transform.stc;
+import groovy.lang.GroovyClassLoader;
import org.apache.groovy.util.Maps;
import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.ast.ClassNode;
@@ -30,6 +31,7 @@ import org.codehaus.groovy.ast.Variable;
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
import org.codehaus.groovy.ast.expr.ArrayExpression;
import org.codehaus.groovy.ast.expr.BinaryExpression;
+import org.codehaus.groovy.ast.expr.CastExpression;
import org.codehaus.groovy.ast.expr.ClosureExpression;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
@@ -107,6 +109,7 @@ import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
import static org.codehaus.groovy.ast.ClassHelper.short_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.void_WRAPPER_TYPE;
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
+import static org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly;
import static org.codehaus.groovy.syntax.Types.BITWISE_AND;
import static org.codehaus.groovy.syntax.Types.BITWISE_AND_EQUAL;
import static org.codehaus.groovy.syntax.Types.BITWISE_OR;
@@ -2136,28 +2139,55 @@ public abstract class StaticTypeCheckingSupport {
}
/**
- * A helper method that can be used to evaluate expressions as found in annotation
- * parameters. For example, it will evaluate a constant, be it referenced directly as
- * an integer or as a reference to a field.
+ * Evaluates expressions as found in annotation parameters. For example, it
+ * will evaluate a constant, be it referenced directly as an integer or as a
+ * reference to a field.
* <p>
- * If this method throws an exception, then the expression cannot be evaluated on its own.
+ * If the expression cannot be evaluated on its own, an exception is thrown.
*
* @param expr the expression to be evaluated
* @param config the compiler configuration
* @return the result of the expression
+ * @throws GroovyBugError
*/
public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config) {
+ return evaluateExpression(expr, config, null);
+ }
+
+ /**
+ * Evaluates expressions as found in annotation parameters. For example, it
+ * will evaluate a constant, be it referenced directly as an integer or as a
+ * reference to a field.
+ * <p>
+ * If the expression cannot be evaluated on its own, an exception is thrown.
+ *
+ * @param expr the expression to be evaluated
+ * @param config the compiler configuration
+ * @param loader the compiler class loader
+ * @return the result of the expression
+ * @throws GroovyBugError
+ */
+ public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config, /*@Nullable*/ final GroovyClassLoader loader) {
+ Expression ce = expr instanceof CastExpression ? ((CastExpression) expr).getExpression() : expr;
+ if (ce instanceof ConstantExpression) {
+ if (expr.getType().equals(ce.getType()))
+ return ((ConstantExpression) ce).getValue();
+ } else if (ce instanceof ListExpression) {
+ if (expr.getType().isArray() && expr.getType().getComponentType().equals(STRING_TYPE))
+ return ((ListExpression) ce).getExpressions().stream().map(e -> evaluateExpression(e, config, loader)).toArray(String[]::new);
+ }
+
String className = "Expression$"+UUID.randomUUID().toString().replace('-', '$');
ClassNode classNode = new ClassNode(className, Opcodes.ACC_PUBLIC, OBJECT_TYPE);
addGeneratedMethod(classNode, "eval", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new ReturnStatement(expr));
- CompilerConfiguration copyConf = new CompilerConfiguration(config);
- // disable preview features so class can be executed by this JVM
- copyConf.setPreviewFeatures(false);
- copyConf.setScriptBaseClass(null);
- copyConf.setTargetBytecode(CompilerConfiguration.DEFAULT.getTargetBytecode());
+ // adjust configuration so class can be executed by this JVM
+ CompilerConfiguration cc = new CompilerConfiguration(config);
+ cc.setPreviewFeatures(false);
+ cc.setScriptBaseClass(null);
+ cc.setTargetBytecode(CompilerConfiguration.DEFAULT.getTargetBytecode());
- CompilationUnit cu = new CompilationUnit(copyConf);
+ CompilationUnit cu = new CompilationUnit(cc, null, loader);
try {
cu.addClassNode(classNode);
cu.compile(Phases.CLASS_GENERATION);
@@ -2168,7 +2198,8 @@ public abstract class StaticTypeCheckingSupport {
} catch (ReflectiveOperationException e) {
throw new GroovyBugError(e);
} finally {
- org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly(cu.getClassLoader());
+ if (loader == null)
+ closeQuietly(cu.getClassLoader());
}
}