diff options
2 files changed, 42 insertions, 10 deletions
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/TreePruner.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/TreePruner.java index ec4cbf5b37..b25d4e79ea 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/TreePruner.java +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/TreePruner.java @@ -68,15 +68,17 @@ public class TreePruner { private static final TreeScanner PRUNING_VISITOR = new TreeScanner() { + JCClassDecl enclClass = null; + @Override public void visitClassDef(JCClassDecl tree) { - if ((tree.mods.flags & Flags.ANNOTATION) == Flags.ANNOTATION) { - // Fields in annotation declarations are implicitly final. - // Field initializers that are definitely not constant expressions could still be - // pruned, but we currently don't bother. - return; + JCClassDecl prev = enclClass; + enclClass = tree; + try { + super.visitClassDef(tree); + } finally { + enclClass = prev; } - super.visitClassDef(tree); } @Override @@ -105,7 +107,7 @@ public class TreePruner { return; } // drop field initializers unless the field looks like a JLS ยง4.12.4 constant variable - if (isConstantVariable(tree)) { + if (isConstantVariable(enclClass, tree)) { return; } tree.init = null; @@ -132,8 +134,19 @@ public class TreePruner { return name.contentEquals("this") || name.contentEquals("super"); } - private static boolean isConstantVariable(JCVariableDecl tree) { - if ((tree.mods.flags & Flags.FINAL) != Flags.FINAL) { + private static boolean isFinal(JCClassDecl enclClass, JCVariableDecl tree) { + if ((tree.mods.flags & Flags.FINAL) == Flags.FINAL) { + return true; + } + if (enclClass != null && (enclClass.mods.flags & (Flags.ANNOTATION | Flags.INTERFACE)) != 0) { + // Fields in annotation declarations and interfaces are implicitly final + return true; + } + return false; + } + + private static boolean isConstantVariable(JCClassDecl enclClass, JCVariableDecl tree) { + if (!isFinal(enclClass, tree)) { return false; } if (!constantType(tree.getType())) { diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/TreePrunerTest.java b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/TreePrunerTest.java index ccf0e33ba0..9cd3acb6c5 100644 --- a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/TreePrunerTest.java +++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/TreePrunerTest.java @@ -277,7 +277,26 @@ public class TreePrunerTest { " ", " int f() default CONST;", " int CONST = 42;", - " int NONCONST = new Integer(42);", + " int NONCONST;", + "}", + }; + assertThat(prettyPrint(tree)).isEqualTo(Joiner.on('\n').join(expected)); + } + + @Test + public void interfaceDeclaration() { + String[] lines = { + "interface Intf {", + " int CONST = 42;", + " int NONCONST = new Integer(42);", + "}", + }; + JCCompilationUnit tree = parseLines(lines); + TreePruner.prune(tree); + String[] expected = { + "interface Intf {", + " int CONST = 42;", + " int NONCONST;", "}", }; assertThat(prettyPrint(tree)).isEqualTo(Joiner.on('\n').join(expected)); |