Skip to content

Commit 160d839

Browse files
committed
GROOVY-9541, GROOVY-10353
1 parent c3b4b08 commit 160d839

File tree

8 files changed

+94
-58
lines changed

8 files changed

+94
-58
lines changed

base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java

+11-4
Original file line numberDiff line numberDiff line change
@@ -2363,13 +2363,17 @@ public static boolean missesGenericsTypes(ClassNode cn) {
23632363
*/
23642364
public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config) {
23652365
// GRECLIPSE add
2366+
return evaluateExpression(expr, config, null);
2367+
}
2368+
2369+
public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config, /*@Nullable*/ final groovy.lang.GroovyClassLoader loader) {
23662370
Expression ce = expr instanceof CastExpression ? ((CastExpression) expr).getExpression() : expr;
23672371
if (ce instanceof ConstantExpression) {
2368-
if (expr.getType().equals(ce.getType()))
2369-
return ((ConstantExpression) ce).getValue();
2372+
if (expr.getType().equals(getWrapper(ce.getType())) || ((ConstantExpression) ce).isNullExpression())
2373+
return ((ConstantExpression) ce).getValue(); // boolean, number, string, or null
23702374
} else if (ce instanceof ListExpression) {
23712375
if (expr.getType().isArray() && expr.getType().getComponentType().equals(STRING_TYPE))
2372-
return ((ListExpression) ce).getExpressions().stream().map(e -> evaluateExpression(e, config)).toArray(String[]::new);
2376+
return ((ListExpression) ce).getExpressions().stream().map(e -> evaluateExpression(e, config, loader)).toArray(String[]::new);
23732377
}
23742378
// GRECLIPSE end
23752379
String className = "Expression$"+UUID.randomUUID().toString().replace('-', '$');
@@ -2383,7 +2387,7 @@ public static Object evaluateExpression(final Expression expr, final CompilerCon
23832387
/* GRECLIPSE edit -- supply the GroovyClassLoader
23842388
CompilationUnit cu = new CompilationUnit(copyConf);
23852389
*/
2386-
CompilationUnit cu = new CompilationUnit(copyConf, null, new groovy.lang.GroovyClassLoader(classNode.getClass().getClassLoader(), copyConf));
2390+
CompilationUnit cu = new CompilationUnit(copyConf, null, loader);
23872391
// GRECLIPSE end
23882392
try {
23892393
cu.addClassNode(classNode);
@@ -2395,6 +2399,9 @@ public static Object evaluateExpression(final Expression expr, final CompilerCon
23952399
} catch (ReflectiveOperationException e) {
23962400
throw new GroovyBugError(e);
23972401
} finally {
2402+
// GRECLIPSE add
2403+
if (loader == null)
2404+
// GRECLIPSE end
23982405
org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly(cu.getClassLoader());
23992406
}
24002407
}

base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,15 @@ private void findCollectedAnnotations(final AnnotationNode alias, final Annotate
183183
if (annotation.getClassNode().getName().equals(AnnotationCollector.class.getName())) {
184184
Expression mode = annotation.getMember("mode");
185185
modes.put(index, Optional.ofNullable(mode)
186-
.map(exp -> evaluateExpression(exp, source.getConfiguration()))
186+
.map(exp -> evaluateExpression(exp, source.getConfiguration(), transformLoader))
187187
.map(val -> (AnnotationCollectorMode) val)
188188
.orElse(AnnotationCollectorMode.DUPLICATE)
189189
);
190190

191191
Expression processor = annotation.getMember("processor");
192192
AnnotationCollectorTransform act = null;
193193
if (processor != null) {
194-
String className = (String) evaluateExpression(processor, source.getConfiguration());
194+
String className = (String) evaluateExpression(processor, source.getConfiguration(), transformLoader);
195195
Class<?> klass = loadTransformClass(className, alias);
196196
if (klass != null) {
197197
try {
@@ -272,7 +272,7 @@ private void addTransformsToClassNode(final AnnotationNode annotation) {
272272
annotation.getClassNode().getAnnotations().stream().filter(a -> a.getClassNode().getName().equals(GroovyASTTransformationClass.class.getName())).findFirst().ifPresent(transformClassAnnotation -> {
273273

274274
String[] transformClassNames = Optional.ofNullable(transformClassAnnotation.getMember("value")).map(value -> {
275-
Object result = evaluateExpression(value, source.getConfiguration());
275+
Object result = evaluateExpression(value, source.getConfiguration(), transformLoader);
276276
if (result instanceof String[]) {
277277
return (String[]) result;
278278
} else if (result instanceof String) {
@@ -285,7 +285,7 @@ private void addTransformsToClassNode(final AnnotationNode annotation) {
285285
}).orElseGet(() -> new String[0]);
286286

287287
Class[] transformClasses = Optional.ofNullable(transformClassAnnotation.getMember("classes")).map(classes -> {
288-
Object result = evaluateExpression(classes, source.getConfiguration());
288+
Object result = evaluateExpression(classes, source.getConfiguration(), transformLoader);
289289
if (result instanceof Class[]) {
290290
return (Class[]) result;
291291
} else if (result instanceof Class) {

base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java

+37-20
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.codehaus.groovy.transform.stc;
2020

21+
import groovy.lang.GroovyClassLoader;
2122
import org.apache.groovy.util.Maps;
2223
import org.codehaus.groovy.GroovyBugError;
2324
import org.codehaus.groovy.ast.ClassNode;
@@ -110,6 +111,7 @@
110111
import static org.codehaus.groovy.ast.ClassHelper.short_TYPE;
111112
import static org.codehaus.groovy.ast.ClassHelper.void_WRAPPER_TYPE;
112113
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
114+
import static org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly;
113115
import static org.codehaus.groovy.syntax.Types.BITWISE_AND;
114116
import static org.codehaus.groovy.syntax.Types.BITWISE_AND_EQUAL;
115117
import static org.codehaus.groovy.syntax.Types.BITWISE_OR;
@@ -2203,41 +2205,55 @@ public static boolean missesGenericsTypes(ClassNode cn) {
22032205
}
22042206

22052207
/**
2206-
* A helper method that can be used to evaluate expressions as found in annotation
2207-
* parameters. For example, it will evaluate a constant, be it referenced directly as
2208-
* an integer or as a reference to a field.
2208+
* Evaluates expressions as found in annotation parameters. For example, it
2209+
* will evaluate a constant, be it referenced directly as an integer or as a
2210+
* reference to a field.
22092211
* <p>
2210-
* If this method throws an exception, then the expression cannot be evaluated on its own.
2212+
* If the expression cannot be evaluated on its own, an exception is thrown.
22112213
*
22122214
* @param expr the expression to be evaluated
22132215
* @param config the compiler configuration
22142216
* @return the result of the expression
2217+
* @throws GroovyBugError
22152218
*/
22162219
public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config) {
2217-
// GRECLIPSE add
2220+
return evaluateExpression(expr, config, null);
2221+
}
2222+
2223+
/**
2224+
* Evaluates expressions as found in annotation parameters. For example, it
2225+
* will evaluate a constant, be it referenced directly as an integer or as a
2226+
* reference to a field.
2227+
* <p>
2228+
* If the expression cannot be evaluated on its own, an exception is thrown.
2229+
*
2230+
* @param expr the expression to be evaluated
2231+
* @param config the compiler configuration
2232+
* @param loader the compiler class loader
2233+
* @return the result of the expression
2234+
* @throws GroovyBugError
2235+
*/
2236+
public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config, /*@Nullable*/ final GroovyClassLoader loader) {
22182237
Expression ce = expr instanceof CastExpression ? ((CastExpression) expr).getExpression() : expr;
22192238
if (ce instanceof ConstantExpression) {
2220-
if (expr.getType().equals(ce.getType()))
2221-
return ((ConstantExpression) ce).getValue();
2239+
if (expr.getType().equals(getWrapper(ce.getType())) || ((ConstantExpression) ce).isNullExpression())
2240+
return ((ConstantExpression) ce).getValue(); // boolean, number, string, or null
22222241
} else if (ce instanceof ListExpression) {
22232242
if (expr.getType().isArray() && expr.getType().getComponentType().equals(STRING_TYPE))
2224-
return ((ListExpression) ce).getExpressions().stream().map(e -> evaluateExpression(e, config)).toArray(String[]::new);
2243+
return ((ListExpression) ce).getExpressions().stream().map(e -> evaluateExpression(e, config, loader)).toArray(String[]::new);
22252244
}
2226-
// GRECLIPSE end
2245+
22272246
String className = "Expression$"+UUID.randomUUID().toString().replace('-', '$');
22282247
ClassNode classNode = new ClassNode(className, Opcodes.ACC_PUBLIC, OBJECT_TYPE);
22292248
addGeneratedMethod(classNode, "eval", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new ReturnStatement(expr));
22302249

2231-
CompilerConfiguration copyConf = new CompilerConfiguration(config);
2232-
// disable preview features so class can be executed by this JVM
2233-
copyConf.setPreviewFeatures(false);
2234-
copyConf.setScriptBaseClass(null);
2235-
copyConf.setTargetBytecode(CompilerConfiguration.DEFAULT.getTargetBytecode());
2236-
/* GRECLIPSE edit -- supply the GroovyClassLoader
2237-
CompilationUnit cu = new CompilationUnit(copyConf);
2238-
*/
2239-
CompilationUnit cu = new CompilationUnit(copyConf, null, new groovy.lang.GroovyClassLoader(classNode.getClass().getClassLoader(), copyConf));
2240-
// GRECLIPSE end
2250+
// adjust configuration so class can be executed by this JVM
2251+
CompilerConfiguration cc = new CompilerConfiguration(config);
2252+
cc.setPreviewFeatures(false);
2253+
cc.setScriptBaseClass(null);
2254+
cc.setTargetBytecode(CompilerConfiguration.DEFAULT.getTargetBytecode());
2255+
2256+
CompilationUnit cu = new CompilationUnit(cc, null, loader);
22412257
try {
22422258
cu.addClassNode(classNode);
22432259
cu.compile(Phases.CLASS_GENERATION);
@@ -2248,7 +2264,8 @@ public static Object evaluateExpression(final Expression expr, final CompilerCon
22482264
} catch (ReflectiveOperationException e) {
22492265
throw new GroovyBugError(e);
22502266
} finally {
2251-
org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly(cu.getClassLoader());
2267+
if (loader == null)
2268+
closeQuietly(cu.getClassLoader());
22522269
}
22532270
}
22542271

base/org.codehaus.groovy40/src/org/codehaus/groovy/ast/ClassNode.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,9 @@ void remove(Object key, MethodNode value) {
172172
private ClassNode superClass;
173173
protected boolean isPrimaryNode;
174174
protected List<InnerClassNode> innerClasses;
175-
private List<ClassNode> permittedSubclasses = new ArrayList<>(4);
176-
private List<AnnotationNode> typeAnnotations = Collections.emptyList();
177-
private List<RecordComponentNode> recordComponents = Collections.emptyList();
175+
private List<ClassNode> permittedSubclasses = new ArrayList<>();
176+
private List<AnnotationNode> typeAnnotations = Collections.EMPTY_LIST;
177+
private List<RecordComponentNode> recordComponents = Collections.EMPTY_LIST;
178178

179179
/**
180180
* The AST Transformations to be applied during compilation.

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,15 @@ private void findCollectedAnnotations(final AnnotationNode alias, final Annotate
183183
if (annotation.getClassNode().getName().equals(AnnotationCollector.class.getName())) {
184184
Expression mode = annotation.getMember("mode");
185185
modes.put(index, Optional.ofNullable(mode)
186-
.map(exp -> evaluateExpression(exp, source.getConfiguration()))
186+
.map(exp -> evaluateExpression(exp, source.getConfiguration(), transformLoader))
187187
.map(val -> (AnnotationCollectorMode) val)
188188
.orElse(AnnotationCollectorMode.DUPLICATE)
189189
);
190190

191191
Expression processor = annotation.getMember("processor");
192192
AnnotationCollectorTransform act = null;
193193
if (processor != null) {
194-
String className = (String) evaluateExpression(processor, source.getConfiguration());
194+
String className = (String) evaluateExpression(processor, source.getConfiguration(), transformLoader);
195195
Class<?> klass = loadTransformClass(className, alias);
196196
if (klass != null) {
197197
try {
@@ -272,7 +272,7 @@ private void addTransformsToClassNode(final AnnotationNode annotation) {
272272
annotation.getClassNode().getAnnotations().stream().filter(a -> a.getClassNode().getName().equals(GroovyASTTransformationClass.class.getName())).findFirst().ifPresent(transformClassAnnotation -> {
273273

274274
String[] transformClassNames = Optional.ofNullable(transformClassAnnotation.getMember("value")).map(value -> {
275-
Object result = evaluateExpression(value, source.getConfiguration());
275+
Object result = evaluateExpression(value, source.getConfiguration(), transformLoader);
276276
if (result instanceof String[]) {
277277
return (String[]) result;
278278
} else if (result instanceof String) {
@@ -285,7 +285,7 @@ private void addTransformsToClassNode(final AnnotationNode annotation) {
285285
}).orElseGet(() -> new String[0]);
286286

287287
Class[] transformClasses = Optional.ofNullable(transformClassAnnotation.getMember("classes")).map(classes -> {
288-
Object result = evaluateExpression(classes, source.getConfiguration());
288+
Object result = evaluateExpression(classes, source.getConfiguration(), transformLoader);
289289
if (result instanceof Class[]) {
290290
return (Class[]) result;
291291
} else if (result instanceof Class) {

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java

+24-15
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.codehaus.groovy.transform.stc;
2020

21+
import groovy.lang.GroovyClassLoader;
2122
import org.apache.groovy.util.Maps;
2223
import org.codehaus.groovy.GroovyBugError;
2324
import org.codehaus.groovy.ast.ClassNode;
@@ -2195,24 +2196,34 @@ public static boolean missesGenericsTypes(ClassNode cn) {
21952196
}
21962197

21972198
/**
2198-
* A helper method that can be used to evaluate expressions as found in annotation
2199-
* parameters. For example, it will evaluate a constant, be it referenced directly as
2200-
* an integer or as a reference to a field.
2199+
* @deprecated Use {@link #evaluateExpression(Expression, CompilerConfiguration, GroovyClassLoader)} instead
2200+
*/
2201+
@Deprecated
2202+
public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config) {
2203+
return evaluateExpression(expr, config, null);
2204+
}
2205+
2206+
/**
2207+
* Evaluates expressions as found in annotation parameters. For example, it
2208+
* will evaluate a constant, be it referenced directly as an integer or as a
2209+
* reference to a field.
22012210
* <p>
2202-
* If this method throws an exception, then the expression cannot be evaluated on its own.
2211+
* If the expression cannot be evaluated on its own, an exception is thrown.
22032212
*
22042213
* @param expr the expression to be evaluated
22052214
* @param config the compiler configuration
2215+
* @param loader the compiler class loader
22062216
* @return the result of the expression
2217+
* @throws GroovyBugError
22072218
*/
2208-
public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config) {
2219+
public static Object evaluateExpression(final Expression expr, final CompilerConfiguration config, /*@Nullable*/ final GroovyClassLoader loader) {
22092220
Expression ce = expr instanceof CastExpression ? ((CastExpression) expr).getExpression() : expr;
22102221
if (ce instanceof ConstantExpression) {
2211-
if (expr.getType().equals(ce.getType()))
2212-
return ((ConstantExpression) ce).getValue();
2222+
if (expr.getType().equals(getWrapper(ce.getType())) || ((ConstantExpression) ce).isNullExpression())
2223+
return ((ConstantExpression) ce).getValue(); // boolean, number, string, or null
22132224
} else if (ce instanceof ListExpression) {
2214-
if (expr.getType().isArray() && expr.getType().getComponentType().equals(STRING_TYPE))
2215-
return ((ListExpression) ce).getExpressions().stream().map(e -> evaluateExpression(e, config)).toArray(String[]::new);
2225+
if (expr.getType().isArray() && isStringType(expr.getType().getComponentType()))
2226+
return ((ListExpression) ce).getExpressions().stream().map(e -> evaluateExpression(e, config, loader)).toArray(String[]::new);
22162227
}
22172228

22182229
String className = "Expression$"+UUID.randomUUID().toString().replace('-', '$');
@@ -2224,11 +2235,8 @@ public static Object evaluateExpression(final Expression expr, final CompilerCon
22242235
cc.setPreviewFeatures(false);
22252236
cc.setScriptBaseClass(null);
22262237
cc.setTargetBytecode(CompilerConfiguration.DEFAULT.getTargetBytecode());
2227-
/* GRECLIPSE edit -- supply GroovyClassLoader
2228-
CompilationUnit cu = new CompilationUnit(cc);
2229-
*/
2230-
CompilationUnit cu = new CompilationUnit(cc, null, new groovy.lang.GroovyClassLoader(classNode.getClass().getClassLoader(), cc));
2231-
// GRECLIPSE end
2238+
2239+
CompilationUnit cu = new CompilationUnit(cc, null, loader);
22322240
try {
22332241
cu.addClassNode(classNode);
22342242
cu.compile(Phases.CLASS_GENERATION);
@@ -2239,7 +2247,8 @@ public static Object evaluateExpression(final Expression expr, final CompilerCon
22392247
} catch (ReflectiveOperationException e) {
22402248
throw new GroovyBugError(e);
22412249
} finally {
2242-
closeQuietly(cu.getClassLoader());
2250+
if (loader == null)
2251+
closeQuietly(cu.getClassLoader());
22432252
}
22442253
}
22452254

0 commit comments

Comments
 (0)