Skip to content

Commit 8f6b192

Browse files
committed
GROOVY-9530: load static field value under configureClassNode(...)
1 parent cb7facb commit 8f6b192

3 files changed

Lines changed: 35 additions & 13 deletions

File tree

src/main/java/org/apache/groovy/ast/tools/ExpressionUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ public static Expression transformInlineConstants(final Expression exp, final Cl
278278
if (e instanceof ConstantExpression) {
279279
return e;
280280
}
281-
} else if (cn.isResolved()) {
281+
}/* else if (cn.isResolved()) { // GROOVY-9530
282282
try {
283283
var field = cn.getTypeClass().getField(pe.getPropertyAsString());
284284
if (field != null) {
@@ -287,7 +287,7 @@ public static Expression transformInlineConstants(final Expression exp, final Cl
287287
} catch (Exception | LinkageError ignore) {
288288
// leave property expression and we will report later
289289
}
290-
}
290+
}*/
291291
}
292292
} else if (exp instanceof VariableExpression) {
293293
VariableExpression ve = (VariableExpression) exp;

src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import java.lang.reflect.MalformedParameterizedTypeException;
6363
import java.lang.reflect.Member;
6464
import java.lang.reflect.Method;
65+
import java.lang.reflect.Modifier;
6566
import java.lang.reflect.ParameterizedType;
6667
import java.lang.reflect.ReflectPermission;
6768
import java.lang.reflect.Type;
@@ -393,7 +394,7 @@ public void configureClassNode(final CompileUnit compileUnit, final ClassNode cl
393394
Field[] fields = clazz.getDeclaredFields();
394395
for (Field f : fields) {
395396
ClassNode rt = makeClassNode(compileUnit, f.getGenericType(), f.getType());
396-
FieldNode fn = new FieldNode(f.getName(), f.getModifiers(), rt, classNode, null);
397+
FieldNode fn = new FieldNode(f.getName(), f.getModifiers(), rt, classNode, getValue(f));
397398
setAnnotationMetaData(f.getAnnotations(), fn);
398399
classNode.addField(fn);
399400
}
@@ -440,6 +441,26 @@ public void configureClassNode(final CompileUnit compileUnit, final ClassNode cl
440441
}
441442
}
442443

444+
/**
445+
* Returns the initial expression for given field.
446+
*
447+
* @return value expression or null
448+
* @since 5.0.0
449+
*/
450+
protected Expression getValue(final Field field) {
451+
int modifiers = field.getModifiers();
452+
// TODO: read ConstantValue from field attributes
453+
if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)
454+
&& (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers))
455+
&& (field.getType().isPrimitive() || field.getType().equals(String.class))) {
456+
try {
457+
return new ConstantExpression(field.get(null), true);
458+
} catch (ReflectiveOperationException | LinkageError e) {
459+
}
460+
}
461+
return null;
462+
}
463+
443464
/**
444465
* Synthetic parameters such as those added for inner class constructors may
445466
* not be included in the parameter annotations array. This is the case when

src/test/groovy/bugs/Groovy9530.groovy

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,29 @@
1818
*/
1919
package bugs
2020

21-
import org.junit.jupiter.api.Test
21+
import org.codehaus.groovy.classgen.asm.AbstractBytecodeTestCase
2222

23-
import static groovy.test.GroovyAssert.assertScript
24-
25-
final class Groovy9530 {
23+
final class Groovy9530 extends AbstractBytecodeTestCase {
2624

2725
static class StaticClass {
2826
public static final int STATIC_VALUE = getStaticValue()
2927

3028
private static int getStaticValue() {
31-
return 'resource from classpath'.length()
29+
getClassLoader().getResources('absent thingy').toList().size()
3230
}
3331
}
3432

35-
@Test
3633
void testConstantInlining() {
37-
assertScript """import bugs.Groovy9530.StaticClass
34+
def bytecode = compile '''import bugs.Groovy9530.StaticClass
3835
class C {
3936
public static final int VALUE = StaticClass.STATIC_VALUE
4037
}
41-
42-
assert C.VALUE == 23
43-
"""
38+
'''
39+
assert bytecode.hasSequence([
40+
'public final static I VALUE'
41+
])
42+
assert !bytecode.hasSequence([
43+
'public final static I VALUE = 0' // no initializer should exist!
44+
])
4445
}
4546
}

0 commit comments

Comments
 (0)