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:53:59 UTC
(groovy) branch GROOVY-9530 created (now 35e4f871ef)
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a change to branch GROOVY-9530
in repository https://gitbox.apache.org/repos/asf/groovy.git
at 35e4f871ef GROOVY-9530: use parsed static field value for constant inlining
This branch includes the following new commits:
new 35e4f871ef GROOVY-9530: use parsed static field value for constant inlining
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(groovy) 01/01: GROOVY-9530: use parsed static field value for constant inlining
Posted by em...@apache.org.
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
+ """
+ }
+}