diff options
2 files changed, 58 insertions, 28 deletions
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java index 8959d3613b..e47a21d342 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java @@ -59,8 +59,8 @@ import org.objectweb.asm.Opcodes; /** * An header compiler implementation based on javac. * - * <p>This is a reference implementation used to develop the blaze integration, and to validate - * the real header compilation implementation. + * <p>This is a reference implementation used to develop the blaze integration, and to validate the + * real header compilation implementation. */ public class JavacTurbine implements AutoCloseable { @@ -262,8 +262,8 @@ public class JavacTurbine implements AutoCloseable { /** * Remove code attributes and private members. * - * <p>Most code will already have been removed after parsing, but the bytecode will still - * contain e.g. lowered class and instance initializers. + * <p>Most code will already have been removed after parsing, but the bytecode will still contain + * e.g. lowered class and instance initializers. */ private static byte[] processBytecode(byte[] bytes) { ClassWriter cw = new ClassWriter(0); @@ -275,18 +275,18 @@ public class JavacTurbine implements AutoCloseable { } /** - * Prune private members. + * Prune bytecode. * - * <p>Like ijar, turbine prunes private fields and members to improve caching - * and reduce output size. + * <p>Like ijar, turbine prunes private fields and members to improve caching and reduce output + * size. * - * <p>This is not always a safe optimization: it can prevent javac from emitting - * diagnostics e.g. when a public member is hidden by a private member which has - * then pruned. The impact of that is believed to be small, and as long as ijar - * continues to prune private members turbine should do the same for compatibility. + * <p>This is not always a safe optimization: it can prevent javac from emitting diagnostics e.g. + * when a public member is hidden by a private member which has then pruned. The impact of that is + * believed to be small, and as long as ijar continues to prune private members turbine should do + * the same for compatibility. * - * <p>Some of this work could be done during tree pruning, but it's not completely - * trivial to detect private members at that point (e.g. with implicit modifiers). + * <p>Some of this work could be done during tree pruning, but it's not completely trivial to + * detect private members at that point (e.g. with implicit modifiers). */ static class PrivateMemberPruner extends ClassVisitor { public PrivateMemberPruner(ClassVisitor cv) { @@ -308,6 +308,10 @@ public class JavacTurbine implements AutoCloseable { if ((access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE) { return null; } + if (name.equals("<clinit>")) { + // drop class initializers, which are going to be empty after tree pruning + return null; + } return super.visitMethod(access, name, desc, signature, exceptions); } } diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java index 7562e3f070..395835efbc 100644 --- a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java +++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java @@ -740,9 +740,6 @@ public class JavacTurbineTest { "", " // access flags 0x9", " public static valueOf(Ljava/lang/String;)LTheEnum;", - "", - " // access flags 0x8", - " static <clinit>()V", "}", "" }; @@ -991,12 +988,7 @@ public class JavacTurbineTest { @Test public void privateMembers() throws Exception { - addSourceLines( - "Hello.java", - "class Hello {", - " private void f() {}", - " private int x;", - "}"); + addSourceLines("Hello.java", "class Hello {", " private void f() {}", " private int x;", "}"); compile(); @@ -1217,14 +1209,10 @@ public class JavacTurbineTest { @Test public void ignoreStrictDepsErrors() throws Exception { - Path lib = createClassJar("deps.jar", - JavacTurbineTest.class, - Lib.class); + Path lib = createClassJar("deps.jar", JavacTurbineTest.class, Lib.class); addSourceLines( - "Hello.java", - "import " + Lib.class.getCanonicalName() + ";", - "class Hello extends Lib {}"); + "Hello.java", "import " + Lib.class.getCanonicalName() + ";", "class Hello extends Lib {}"); optionsBuilder.addIndirectJarToTarget(lib.toString(), JarOwner.create("//lib")); optionsBuilder.addClassPathEntries(ImmutableList.of(lib.toString())); @@ -1240,4 +1228,42 @@ public class JavacTurbineTest { assertThat(errOutput.toString()).contains("warning: [strict]"); assertThat(result).isNotEqualTo(Result.OK_WITH_REDUCED_CLASSPATH); } + + @Test + public void clinit() throws Exception { + addSourceLines( + "Hello.java", + "class Hello {", + " public static int x;", + " static {", + " x = 42;", + " }", + "}"); + + compile(); + + Map<String, byte[]> outputs = collectOutputs(); + + assertThat(outputs.keySet()).containsExactly("Hello.class"); + + String text = textify(outputs.get("Hello.class")); + System.err.println(">>>"); + System.err.println(text); + System.err.println(">>>"); + String[] expected = { + "// class version 51.0 (51)", + "// access flags 0x20", + "class Hello {", + "", + "", + " // access flags 0x9", + " public static I x", + "", + " // access flags 0x0", + " <init>()V", + "}", + "" + }; + assertThat(text).isEqualTo(Joiner.on('\n').join(expected)); + } } |