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 8f6b1923b22bc93dc6d7854aae0236efdfc3b197 Author: Eric Milles <[email protected]> AuthorDate: Sun Apr 20 12:08:45 2025 -0500 GROOVY-9530: load static field value under `configureClassNode(...)` --- .../apache/groovy/ast/tools/ExpressionUtils.java | 4 ++-- .../org/codehaus/groovy/vmplugin/v8/Java8.java | 23 +++++++++++++++++++++- src/test/groovy/bugs/Groovy9530.groovy | 21 ++++++++++---------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java b/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java index 1731dcbd7d..803dc7b842 100644 --- a/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java +++ b/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java @@ -278,7 +278,7 @@ public final class ExpressionUtils { if (e instanceof ConstantExpression) { return e; } - } else if (cn.isResolved()) { + }/* else if (cn.isResolved()) { // GROOVY-9530 try { var field = cn.getTypeClass().getField(pe.getPropertyAsString()); if (field != null) { @@ -287,7 +287,7 @@ public final class ExpressionUtils { } catch (Exception | LinkageError ignore) { // leave property expression and we will report later } - } + }*/ } } else if (exp instanceof VariableExpression) { VariableExpression ve = (VariableExpression) exp; 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 5e2901eb03..9a6e8bb0e6 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java @@ -62,6 +62,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.MalformedParameterizedTypeException; import java.lang.reflect.Member; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.ReflectPermission; import java.lang.reflect.Type; @@ -393,7 +394,7 @@ public class Java8 implements VMPlugin { Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { ClassNode rt = makeClassNode(compileUnit, f.getGenericType(), f.getType()); - FieldNode fn = new FieldNode(f.getName(), f.getModifiers(), rt, classNode, null); + FieldNode fn = new FieldNode(f.getName(), f.getModifiers(), rt, classNode, getValue(f)); setAnnotationMetaData(f.getAnnotations(), fn); classNode.addField(fn); } @@ -440,6 +441,26 @@ public class Java8 implements VMPlugin { } } + /** + * Returns the initial expression for given field. + * + * @return value expression or null + * @since 5.0.0 + */ + protected Expression getValue(final Field field) { + int modifiers = field.getModifiers(); + // TODO: read ConstantValue from field attributes + if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers) + && (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) + && (field.getType().isPrimitive() || field.getType().equals(String.class))) { + try { + return new ConstantExpression(field.get(null), true); + } catch (ReflectiveOperationException | LinkageError e) { + } + } + return null; + } + /** * Synthetic parameters such as those added for inner class constructors may * not be included in the parameter annotations array. This is the case when diff --git a/src/test/groovy/bugs/Groovy9530.groovy b/src/test/groovy/bugs/Groovy9530.groovy index 20f985a96c..66ae9328f4 100644 --- a/src/test/groovy/bugs/Groovy9530.groovy +++ b/src/test/groovy/bugs/Groovy9530.groovy @@ -18,28 +18,29 @@ */ package bugs -import org.junit.jupiter.api.Test +import org.codehaus.groovy.classgen.asm.AbstractBytecodeTestCase -import static groovy.test.GroovyAssert.assertScript - -final class Groovy9530 { +final class Groovy9530 extends AbstractBytecodeTestCase { static class StaticClass { public static final int STATIC_VALUE = getStaticValue() private static int getStaticValue() { - return 'resource from classpath'.length() + getClassLoader().getResources('absent thingy').toList().size() } } - @Test void testConstantInlining() { - assertScript """import bugs.Groovy9530.StaticClass + def bytecode = compile '''import bugs.Groovy9530.StaticClass class C { public static final int VALUE = StaticClass.STATIC_VALUE } - - assert C.VALUE == 23 - """ + ''' + assert bytecode.hasSequence([ + 'public final static I VALUE' + ]) + assert !bytecode.hasSequence([ + 'public final static I VALUE = 0' // no initializer should exist! + ]) } }
