Skip to content

Commit 877c8e9

Browse files
committed
Ignore setting values with CONSTANTS.
1 parent acbeb99 commit 877c8e9

2 files changed

Lines changed: 52 additions & 2 deletions

File tree

src/main/java/org/ikvm/javarefplugin/MethodBodyStripper.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,19 @@ private List<JCTree.JCStatement> generateDefaultFieldAssignments(JCTree.JCClassD
5757
return statements.toList();
5858
}
5959

60-
// Collect all static fields
60+
// Collect all static fields that can be safely reassigned
61+
// (skip final fields that have an initializer - they have compile-time constant values)
6162
for (JCTree def : classTree.defs) {
6263
if (def instanceof JCTree.JCVariableDecl) {
6364
JCTree.JCVariableDecl varDecl = (JCTree.JCVariableDecl) def;
6465
if ((varDecl.mods.flags & Flags.STATIC) != 0) {
66+
// Skip if final AND has an initializer (compile-time constant)
67+
boolean isFinal = (varDecl.mods.flags & Flags.FINAL) != 0;
68+
boolean hasInitializer = varDecl.init != null;
69+
if (isFinal && hasInitializer) {
70+
continue; // Skip final fields with initializers
71+
}
72+
6573
// Generate assignment: field = defaultValue;
6674
JCTree.JCExpression defaultValue = generateDefaultValue(varDecl.vartype);
6775
JCTree.JCAssign assignment = maker.Assign(

src/test/java/org/ikvm/javarefplugin/JavaRefPluginTest.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,5 +438,47 @@ private CompilationInvocation(CompilationResult result, String output) {
438438
this.output = output;
439439
}
440440
}
441-
}
442441

442+
@Test
443+
void staticInitializerOptimizationHandlesAllFieldTypes() throws Exception {
444+
Map<String, String> sources = new LinkedHashMap<>();
445+
sources.put(
446+
"example/StaticFieldTypes.java",
447+
joinLines(
448+
"package example;",
449+
"",
450+
"public class StaticFieldTypes {",
451+
" static final long CONSTANT = 42L;",
452+
" static final String uninit;",
453+
" static int mutable;",
454+
" static {",
455+
" uninit = \"initialized\";",
456+
" mutable = 100;",
457+
" }",
458+
" public static long getConstant() { return CONSTANT; }",
459+
" public static String getUninit() { return uninit; }",
460+
" public static int getMutable() { return mutable; }",
461+
"}"
462+
)
463+
);
464+
465+
// Just verify the plugin can compile this without errors
466+
// (the key test is that final fields with initializers don't get reassigned)
467+
CompilationResult result = compile(sources);
468+
Class<?> type = result.loadClass("example.StaticFieldTypes");
469+
470+
// All methods should be stripped and throw NullPointerException
471+
InvocationTargetException constantFailure =
472+
assertThrows(InvocationTargetException.class, () -> type.getMethod("getConstant").invoke(null));
473+
assertTrue(constantFailure.getCause() instanceof NullPointerException);
474+
475+
InvocationTargetException uninitFailure =
476+
assertThrows(InvocationTargetException.class, () -> type.getMethod("getUninit").invoke(null));
477+
assertTrue(uninitFailure.getCause() instanceof NullPointerException);
478+
479+
InvocationTargetException mutableFailure =
480+
assertThrows(InvocationTargetException.class, () -> type.getMethod("getMutable").invoke(null));
481+
assertTrue(mutableFailure.getCause() instanceof NullPointerException);
482+
}
483+
484+
}

0 commit comments

Comments
 (0)