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 2025/04/19 15:54:00 UTC
(groovy) 01/01: GROOVY-9530: use parsed static field value for constant inlining
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY-9530
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 35e4f871ef1efb7b8b9eafd8c79cc702f70a69d0
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Apr 19 10:53:25 2025 -0500
GROOVY-9530: use parsed static field value for constant inlining
---
.../apache/groovy/ast/tools/ExpressionUtils.java | 39 ++++++++++---------
.../ast/decompiled/MemberSignatureParser.java | 2 +-
src/test/groovy/bugs/Groovy9530.groovy | 45 ++++++++++++++++++++++
3 files changed, 66 insertions(+), 20 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 178a96e5b6..1731dcbd7d 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java
@@ -32,8 +32,6 @@ import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.runtime.typehandling.NumberMath;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.List;
import java.util.ListIterator;
@@ -258,6 +256,7 @@ public final class ExpressionUtils {
* <li>Binary expressions - string concatenation and numeric +, -, /, *</li>
* <li>List expressions - list of constants</li>
* </ul>
+ *
* @param exp the original expression
* @param attrType the type that the final constant should be
* @return the transformed type or the original if no transformation was possible
@@ -265,26 +264,28 @@ public final class ExpressionUtils {
public static Expression transformInlineConstants(final Expression exp, final ClassNode attrType) {
if (exp instanceof PropertyExpression) {
PropertyExpression pe = (PropertyExpression) exp;
- ClassNode type = pe.getObjectExpression().getType();
- if (pe.getObjectExpression() instanceof ClassExpression && !type.isEnum()) {
- if (type.isPrimaryClassNode()) {
- FieldNode fn = type.getField(pe.getPropertyAsString());
- if (fn != null && fn.isStatic() && fn.isFinal()) {
- Expression e = transformInlineConstants(fn.getInitialValueExpression(), attrType);
- if (e != null) {
- return e;
- }
+ Expression e = pe.getObjectExpression();
+ ClassNode cn;
+ FieldNode fn;
+ if (e instanceof ClassExpression
+ && !(cn = e.getType().redirect()).isEnum()
+ && (cn.isPrimaryClassNode() || cn.isResolved())
+ && (fn = ClassNodeUtils.getField(cn, pe.getPropertyAsString())) != null
+ && fn.isStatic()
+ && fn.isFinal()) {
+ if (fn.hasInitialExpression()) {
+ e = transformInlineConstants(fn.getInitialValueExpression(), attrType);
+ if (e instanceof ConstantExpression) {
+ return e;
}
- } else if (type.isResolved()) {
+ } else if (cn.isResolved()) {
try {
- Field field = type.redirect().getTypeClass().getField(pe.getPropertyAsString());
- if (field != null && Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) {
- ConstantExpression ce = new ConstantExpression(field.get(null), true);
- configure(exp, ce);
- return ce;
+ var field = cn.getTypeClass().getField(pe.getPropertyAsString());
+ if (field != null) {
+ return configure(exp, new ConstantExpression(field.get(null), true));
}
- } catch (Exception | LinkageError e) {
- // ignore, leave property expression in place and we'll report later
+ } catch (Exception | LinkageError ignore) {
+ // leave property expression and we will report later
}
}
}
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java b/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java
index 6e25c3f9ae..48426dedbc 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/MemberSignatureParser.java
@@ -53,7 +53,7 @@ class MemberSignatureParser {
// ex: java.util.Collections#EMPTY_LIST/EMPTY_MAP/EMPTY_SET
type[0] = GenericsUtils.nonGeneric(type[0]);
}
- return new FieldNode(field.fieldName, field.accessModifiers, type[0], owner, field.value != null ? new ConstantExpression(field.value) : null);
+ return new FieldNode(field.fieldName, field.accessModifiers, type[0], owner, field.value != null ? new ConstantExpression(field.value, true) : null);
}
static MethodNode createMethodNode(final AsmReferenceResolver resolver, final MethodStub method) {
diff --git a/src/test/groovy/bugs/Groovy9530.groovy b/src/test/groovy/bugs/Groovy9530.groovy
new file mode 100644
index 0000000000..20f985a96c
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9530.groovy
@@ -0,0 +1,45 @@
+/*
+ * 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 bugs
+
+import org.junit.jupiter.api.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy9530 {
+
+ static class StaticClass {
+ public static final int STATIC_VALUE = getStaticValue()
+
+ private static int getStaticValue() {
+ return 'resource from classpath'.length()
+ }
+ }
+
+ @Test
+ void testConstantInlining() {
+ assertScript """import bugs.Groovy9530.StaticClass
+ class C {
+ public static final int VALUE = StaticClass.STATIC_VALUE
+ }
+
+ assert C.VALUE == 23
+ """
+ }
+}