aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/TreePruner.java31
-rw-r--r--src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/TreePrunerTest.java21
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));