aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/java_tools
diff options
context:
space:
mode:
authorGravatar Liam Miller-Cushon <cushon@google.com>2016-04-05 19:43:22 +0000
committerGravatar Lukacs Berki <lberki@google.com>2016-04-07 11:40:30 +0000
commiteb89cccfd3aff746b59da3feb31eb3ae528ce909 (patch)
tree7b2b2868d15d5c5cc4e1f03d89342d35c98c075e /src/java_tools
parent709984d829f7d84097e899b55fb573d777e427dc (diff)
Disable tree pruning for blacklisted annotation processors
Some annotation processors use non-standard APIs to examine the AST, and are broken by tree pruning. This change adds configuration to Turbine to allow a blacklist of processors to be provided, and disables tree pruning if any blacklisted processors are found. -- MOS_MIGRATED_REVID=119079114
Diffstat (limited to 'src/java_tools')
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptions.java19
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptionsParser.java17
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD1
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java12
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileRequest.java34
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java7
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java18
-rw-r--r--src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/BUILD7
-rw-r--r--src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java161
9 files changed, 236 insertions, 40 deletions
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptions.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptions.java
index dfe78002a7..507cec366e 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptions.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptions.java
@@ -32,6 +32,7 @@ public class TurbineOptions {
private final ImmutableList<String> sources;
private final ImmutableList<String> processorPath;
private final ImmutableSet<String> processors;
+ private final ImmutableSet<String> blacklistedProcessors;
private final String tempDir;
private final ImmutableList<String> sourceJars;
private final Optional<String> outputDeps;
@@ -50,6 +51,7 @@ public class TurbineOptions {
ImmutableList<String> sources,
ImmutableList<String> processorPath,
ImmutableSet<String> processors,
+ ImmutableSet<String> blacklistedProcessors,
String tempDir,
ImmutableList<String> sourceJars,
@Nullable String outputDeps,
@@ -66,6 +68,8 @@ public class TurbineOptions {
this.sources = checkNotNull(sources, "sources must not be null");
this.processorPath = checkNotNull(processorPath, "processorPath must not be null");
this.processors = checkNotNull(processors, "processors must not be null");
+ this.blacklistedProcessors =
+ checkNotNull(blacklistedProcessors, "blacklistedProcessors must not be null");
this.tempDir = checkNotNull(tempDir, "tempDir must not be null");
this.sourceJars = checkNotNull(sourceJars, "sourceJars must not be null");
this.outputDeps = Optional.fromNullable(outputDeps);
@@ -115,6 +119,14 @@ public class TurbineOptions {
return processors;
}
+ /**
+ * Annotation processors that require tree pruning to be disabled, for example because they use
+ * internal compiler APIs to inspect information that would be removed during pruning.
+ */
+ public ImmutableSet<String> blacklistedProcessors() {
+ return blacklistedProcessors;
+ }
+
/** Source jars for compilation. */
public ImmutableList<String> sourceJars() {
return sourceJars;
@@ -176,6 +188,7 @@ public class TurbineOptions {
private final ImmutableList.Builder<String> sources = ImmutableList.builder();
private final ImmutableList.Builder<String> processorPath = ImmutableList.builder();
private final ImmutableSet.Builder<String> processors = ImmutableSet.builder();
+ private final ImmutableSet.Builder<String> blacklistedProcessors = ImmutableSet.builder();
private String tempDir;
private final ImmutableList.Builder<String> sourceJars = ImmutableList.builder();
private final ImmutableList.Builder<String> bootClassPath = ImmutableList.builder();
@@ -197,6 +210,7 @@ public class TurbineOptions {
sources.build(),
processorPath.build(),
processors.build(),
+ blacklistedProcessors.build(),
tempDir,
sourceJars.build(),
outputDeps,
@@ -244,6 +258,11 @@ public class TurbineOptions {
return this;
}
+ public Builder addBlacklistedProcessors(Iterable<String> processors) {
+ this.blacklistedProcessors.addAll(processors);
+ return this;
+ }
+
public Builder setTempDir(String tempDir) {
this.tempDir = tempDir;
return this;
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptionsParser.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptionsParser.java
index 2c8d87ea1c..9e0ada2e21 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptionsParser.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/TurbineOptionsParser.java
@@ -33,15 +33,24 @@ import javax.annotation.Nullable;
public class TurbineOptionsParser {
/**
- * Parses a list of command-line options into a {@link TurbineOptions}, expanding any
- * {@code @params} files.
+ * Parses command line options into {@link TurbineOptions}, expanding any {@code @params}
+ * files.
*/
public static TurbineOptions parse(Iterable<String> args) throws IOException {
+ TurbineOptions.Builder builder = TurbineOptions.builder();
+ parse(builder, args);
+ return builder.build();
+ }
+
+ /**
+ * Parses command line options into a {@link TurbineOptions.Builder}, expanding any
+ * {@code @params} files.
+ */
+ public static void parse(TurbineOptions.Builder builder, Iterable<String> args)
+ throws IOException {
Deque<String> argumentDeque = new ArrayDeque<>();
expandParamsFiles(argumentDeque, args);
- TurbineOptions.Builder builder = TurbineOptions.builder();
parse(builder, argumentDeque);
- return builder.build();
}
private static final Splitter ARG_SPLITTER =
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD
index b62b34b04b..9e3e6cbeea 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/BUILD
@@ -65,6 +65,7 @@ java_library(
name = "javac_turbine_java_compiler",
srcs = ["JavacTurbineJavaCompiler.java"],
deps = [
+ ":javac_turbine_compile_request",
":tree_pruner",
"//src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/plugins:dependency",
"//third_party:jsr305",
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 0b161158d7..0ec92b3610 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
@@ -24,6 +24,7 @@ import com.google.devtools.build.buildjar.javac.plugins.dependency.DependencyMod
import com.google.devtools.build.buildjar.javac.plugins.dependency.StrictJavaDepsPlugin;
import com.google.devtools.build.java.turbine.TurbineOptions;
import com.google.devtools.build.java.turbine.TurbineOptionsParser;
+import com.google.devtools.build.java.turbine.javac.JavacTurbineCompileRequest.Prune;
import com.google.devtools.build.java.turbine.javac.ZipOutputFileManager.OutputFileObject;
import com.sun.tools.javac.util.Context;
@@ -78,7 +79,7 @@ public class JavacTurbine implements AutoCloseable {
}
/** A header compilation result. */
- enum Result {
+ public enum Result {
/** The compilation succeeded with the reduced classpath optimization. */
OK_WITH_REDUCED_CLASSPATH(true),
@@ -94,11 +95,11 @@ public class JavacTurbine implements AutoCloseable {
this.ok = ok;
}
- boolean ok() {
+ public boolean ok() {
return ok;
}
- int exitCode() {
+ public int exitCode() {
return ok ? 0 : 1;
}
}
@@ -156,6 +157,11 @@ public class JavacTurbine implements AutoCloseable {
.setBootClassPath(asPaths(turbineOptions.bootClassPath()))
.setProcessorClassPath(processorpath);
+ if (!Collections.disjoint(
+ turbineOptions.processors(), turbineOptions.blacklistedProcessors())) {
+ requestBuilder.setPrune(Prune.NO);
+ }
+
StrictJavaDeps strictDepsMode = StrictJavaDeps.valueOf(turbineOptions.strictDepsMode());
DependencyModule dependencyModule = buildDependencyModule(turbineOptions, strictDepsMode);
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileRequest.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileRequest.java
index 68f99fe9d6..284d2e2083 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileRequest.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompileRequest.java
@@ -14,8 +14,11 @@
package com.google.devtools.build.java.turbine.javac;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.buildjar.javac.plugins.dependency.StrictJavaDepsPlugin;
+import com.google.devtools.build.java.turbine.javac.JavacTurbineCompileRequest.Prune;
import java.nio.file.Path;
@@ -24,23 +27,31 @@ import javax.annotation.Nullable;
/** The input to a {@link JavacTurbineCompiler} compilation. */
class JavacTurbineCompileRequest {
+ enum Prune {
+ YES,
+ NO
+ }
+
private final ImmutableList<Path> classPath;
private final ImmutableList<Path> bootClassPath;
private final ImmutableList<Path> processorClassPath;
private final ImmutableList<String> javacOptions;
@Nullable private final StrictJavaDepsPlugin strictJavaDepsPlugin;
+ private final Prune prune;
JavacTurbineCompileRequest(
ImmutableList<Path> classPath,
ImmutableList<Path> bootClassPath,
ImmutableList<Path> processorClassPath,
ImmutableList<String> javacOptions,
- @Nullable StrictJavaDepsPlugin strictJavaDepsPlugin) {
- this.classPath = classPath;
- this.bootClassPath = bootClassPath;
- this.processorClassPath = processorClassPath;
- this.javacOptions = javacOptions;
+ @Nullable StrictJavaDepsPlugin strictJavaDepsPlugin,
+ Prune prune) {
+ this.classPath = checkNotNull(classPath);
+ this.bootClassPath = checkNotNull(bootClassPath);
+ this.processorClassPath = checkNotNull(processorClassPath);
+ this.javacOptions = checkNotNull(javacOptions);
this.strictJavaDepsPlugin = strictJavaDepsPlugin;
+ this.prune = checkNotNull(prune);
}
/** The class path; correspond's to javac -classpath. */
@@ -71,6 +82,11 @@ class JavacTurbineCompileRequest {
return strictJavaDepsPlugin;
}
+ /** Whether to perform a relaxed header-only compilation. */
+ Prune prune() {
+ return prune;
+ }
+
static JavacTurbineCompileRequest.Builder builder() {
return new Builder();
}
@@ -81,12 +97,13 @@ class JavacTurbineCompileRequest {
private ImmutableList<Path> processorClassPath;
private ImmutableList<String> javacOptions;
@Nullable private StrictJavaDepsPlugin strictDepsPlugin;
+ private Prune prune = Prune.YES;
private Builder() {}
JavacTurbineCompileRequest build() {
return new JavacTurbineCompileRequest(
- classPath, bootClassPath, processorClassPath, javacOptions, strictDepsPlugin);
+ classPath, bootClassPath, processorClassPath, javacOptions, strictDepsPlugin, prune);
}
Builder setClassPath(ImmutableList<Path> classPath) {
@@ -113,5 +130,10 @@ class JavacTurbineCompileRequest {
this.strictDepsPlugin = strictDepsPlugin;
return this;
}
+
+ Builder setPrune(Prune prune) {
+ this.prune = prune;
+ return this;
+ }
}
}
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java
index 0a59323cc8..0718ec5968 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineCompiler.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.java.turbine.javac;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.buildjar.javac.plugins.dependency.StrictJavaDepsPlugin;
+import com.google.devtools.build.java.turbine.javac.JavacTurbineCompileRequest.Prune;
import com.google.devtools.build.java.turbine.javac.JavacTurbineCompileResult.Status;
import com.google.devtools.build.java.turbine.javac.ZipOutputFileManager.OutputFileObject;
@@ -50,7 +51,7 @@ public class JavacTurbineCompiler {
try (PrintWriter pw = new PrintWriter(sw)) {
ZipOutputFileManager.preRegister(context, files);
- setupContext(context, request.strictJavaDepsPlugin());
+ setupContext(context, request.strictJavaDepsPlugin(), request.prune());
CacheFSInfo.preRegister(context);
context.put(Log.outKey, pw);
@@ -93,7 +94,7 @@ public class JavacTurbineCompiler {
return new JavacTurbineCompileResult(ImmutableMap.copyOf(files), status, sw, context);
}
- static void setupContext(Context context, @Nullable StrictJavaDepsPlugin sjd) {
- JavacTurbineJavaCompiler.preRegister(context, sjd);
+ static void setupContext(Context context, @Nullable StrictJavaDepsPlugin sjd, Prune prune) {
+ JavacTurbineJavaCompiler.preRegister(context, sjd, prune);
}
}
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java
index 874b1811a4..d49863a423 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbineJavaCompiler.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.java.turbine.javac;
import com.google.devtools.build.buildjar.javac.plugins.dependency.StrictJavaDepsPlugin;
+import com.google.devtools.build.java.turbine.javac.JavacTurbineCompileRequest.Prune;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.CompileStates.CompileState;
@@ -38,15 +39,21 @@ import javax.tools.JavaFileObject;
class JavacTurbineJavaCompiler extends JavaCompiler implements AutoCloseable {
@Nullable private final StrictJavaDepsPlugin strictJavaDeps;
+ private final boolean prune;
- public JavacTurbineJavaCompiler(Context context, @Nullable StrictJavaDepsPlugin strictJavaDeps) {
+ public JavacTurbineJavaCompiler(
+ Context context, @Nullable StrictJavaDepsPlugin strictJavaDeps, Prune prune) {
super(context);
this.strictJavaDeps = strictJavaDeps;
+ this.prune = prune == Prune.YES;
}
@Override
protected JCCompilationUnit parse(JavaFileObject javaFileObject, CharSequence charSequence) {
JCCompilationUnit result = super.parse(javaFileObject, charSequence);
+ if (!prune) {
+ return result;
+ }
TreePruner.prune(result);
return result;
}
@@ -65,6 +72,10 @@ class JavacTurbineJavaCompiler extends JavaCompiler implements AutoCloseable {
@Override
protected void flow(Env<AttrContext> env, Queue<Env<AttrContext>> results) {
+ if (!prune) {
+ super.flow(env, results);
+ return;
+ }
// skip FLOW (as if -relax was enabled, except -relax is broken for JDK >= 8)
if (!compileStates.isDone(env, CompileState.FLOW)) {
compileStates.put(env, CompileState.FLOW);
@@ -83,13 +94,14 @@ class JavacTurbineJavaCompiler extends JavaCompiler implements AutoCloseable {
* Override the default {@link JavaCompiler} implementation with {@link JavacTurbineJavaCompiler}
* for the given compilation context.
*/
- public static void preRegister(Context context, @Nullable final StrictJavaDepsPlugin sjd) {
+ public static void preRegister(
+ Context context, @Nullable final StrictJavaDepsPlugin sjd, final Prune prune) {
context.put(
compilerKey,
new Context.Factory<JavaCompiler>() {
@Override
public JavaCompiler make(Context c) {
- return new JavacTurbineJavaCompiler(c, sjd);
+ return new JavacTurbineJavaCompiler(c, sjd, prune);
}
});
}
diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/BUILD b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/BUILD
index 04419b0ad5..4132bba9df 100644
--- a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/BUILD
+++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/BUILD
@@ -1,6 +1,13 @@
java_test(
name = "JavacTurbineTest",
srcs = ["JavacTurbineTest.java"],
+ data = [
+ "//third_party/java/jdk/langtools:javac_jar",
+ ],
+ jvm_flags = [
+ # Simulates how Bazel invokes turbine
+ "-Xbootclasspath/p:$(location //third_party/java/jdk/langtools:javac_jar)",
+ ],
tags = ["jdk8"],
deps = [
"//src/java_tools/buildjar/java/com/google/devtools/build/java/turbine:turbine_options",
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 2fdc22d9d6..234f5d0865 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
@@ -15,6 +15,7 @@
package com.google.devtools.build.java.turbine.javac;
import static com.google.common.truth.Truth.assertThat;
+import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
@@ -28,7 +29,12 @@ import com.google.devtools.build.java.turbine.javac.JavacTurbine.Result;
import com.google.devtools.build.lib.view.proto.Deps;
import com.google.devtools.build.lib.view.proto.Deps.Dependency;
+import com.sun.source.tree.LiteralTree;
import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskEvent.Kind;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.api.ClientCodeWrapper.Trusted;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.file.JavacFileManager;
@@ -52,7 +58,6 @@ import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
-import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -63,6 +68,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -71,6 +77,7 @@ import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
@@ -120,7 +127,7 @@ public class JavacTurbineTest {
private void addSourceLines(String path, String... lines) throws IOException {
Path source = sourcedir.resolve(path);
sources.add(source);
- Files.write(source, Arrays.asList(lines), StandardCharsets.UTF_8);
+ Files.write(source, Arrays.asList(lines), UTF_8);
}
void compile() throws IOException {
@@ -231,7 +238,7 @@ public class JavacTurbineTest {
try {
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile("Generated", element);
try (OutputStream os = sourceFile.openOutputStream()) {
- os.write("public class Generated {}".getBytes(StandardCharsets.UTF_8));
+ os.write("public class Generated {}".getBytes(UTF_8));
}
} catch (IOException e) {
throw new IOError(e);
@@ -242,7 +249,7 @@ public class JavacTurbineTest {
.getFiler()
.createResource(StandardLocation.CLASS_OUTPUT, "com.foo", "hello.txt", element);
try (OutputStream os = file.openOutputStream()) {
- os.write("hello".getBytes(StandardCharsets.UTF_8));
+ os.write("hello".getBytes(UTF_8));
}
} catch (IOException e) {
throw new IOError(e);
@@ -455,7 +462,7 @@ public class JavacTurbineTest {
Path jar, Iterable<Path> classpath, Iterable<? extends JavaFileObject> units)
throws IOException {
final Path outdir = temp.newFolder().toPath();
- JavacFileManager fm = new JavacFileManager(new Context(), false, StandardCharsets.UTF_8);
+ JavacFileManager fm = new JavacFileManager(new Context(), false, UTF_8);
fm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Collections.singleton(outdir));
fm.setLocationFromPaths(StandardLocation.CLASS_PATH, classpath);
List<String> options = Arrays.asList("-d", outdir.toString());
@@ -795,10 +802,9 @@ public class JavacTurbineTest {
try {
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile("Generated", element);
try (OutputStream os = sourceFile.openOutputStream()) {
- os.write(
- "class Generated { public static String x = \"".getBytes(StandardCharsets.UTF_8));
+ os.write("class Generated { public static String x = \"".getBytes(UTF_8));
os.write(0xc2); // write an unpaired surrogate
- os.write("\";}}".getBytes(StandardCharsets.UTF_8));
+ os.write("\";}}".getBytes(UTF_8));
}
} catch (IOException e) {
throw new IOError(e);
@@ -936,7 +942,7 @@ public class JavacTurbineTest {
.getFiler()
.createResource(StandardLocation.CLASS_OUTPUT, "", "result.txt");
try (OutputStream os = fileObject.openOutputStream()) {
- os.write(message.getBytes(StandardCharsets.UTF_8));
+ os.write(message.getBytes(UTF_8));
}
} catch (IOException e) {
throw new IOError(e);
@@ -951,15 +957,7 @@ public class JavacTurbineTest {
addSourceLines("Hello.java", "@MyAnnotation class Hello {}");
// create a jar containing only HostClasspathProcessor
- Path processorJar = temp.newFile("libprocessor.jar").toPath();
- try (OutputStream os = Files.newOutputStream(processorJar);
- JarOutputStream jos = new JarOutputStream(os)) {
- String classFileName = HostClasspathProcessor.class.getName().replace('.', '/') + ".class";
- jos.putNextEntry(new JarEntry(classFileName));
- try (InputStream is = getClass().getClassLoader().getResourceAsStream(classFileName)) {
- ByteStreams.copy(is, jos);
- }
- }
+ Path processorJar = createClassJar("libprocessor.jar", HostClasspathProcessor.class);
optionsBuilder.addProcessors(ImmutableList.of(HostClasspathProcessor.class.getName()));
optionsBuilder.addProcessorPathEntries(ImmutableList.of(processorJar.toString()));
@@ -970,27 +968,42 @@ public class JavacTurbineTest {
Map<String, byte[]> outputs = collectOutputs();
assertThat(outputs.keySet()).contains("result.txt");
- String text = new String(outputs.get("result.txt"), StandardCharsets.UTF_8);
+ String text = new String(outputs.get("result.txt"), UTF_8);
assertThat(text)
.contains(
"java.lang.NoClassDefFoundError:"
+ " com/google/devtools/build/java/turbine/javac/JavacTurbine");
}
+ private Path createClassJar(String jarName, Class<?>... classes) throws IOException {
+ Path jarPath = temp.newFile(jarName).toPath();
+ try (OutputStream os = Files.newOutputStream(jarPath);
+ JarOutputStream jos = new JarOutputStream(os)) {
+ for (Class<?> clazz : classes) {
+ String classFileName = clazz.getName().replace('.', '/') + ".class";
+ jos.putNextEntry(new JarEntry(classFileName));
+ try (InputStream is = getClass().getClassLoader().getResourceAsStream(classFileName)) {
+ ByteStreams.copy(is, jos);
+ }
+ }
+ }
+ return jarPath;
+ }
+
@Test
public void overlappingSourceJars() throws Exception {
Path sourceJar1 = temp.newFile("srcs1.jar").toPath();
try (OutputStream os = Files.newOutputStream(sourceJar1);
JarOutputStream jos = new JarOutputStream(os)) {
jos.putNextEntry(new JarEntry("Hello.java"));
- jos.write("public class Hello {}".getBytes(StandardCharsets.UTF_8));
+ jos.write("public class Hello {}".getBytes(UTF_8));
}
Path sourceJar2 = temp.newFile("srcs2.jar").toPath();
try (OutputStream os = Files.newOutputStream(sourceJar2);
JarOutputStream jos = new JarOutputStream(os)) {
jos.putNextEntry(new JarEntry("Hello.java"));
- jos.write("public class Hello {}".getBytes(StandardCharsets.UTF_8));
+ jos.write("public class Hello {}".getBytes(UTF_8));
}
optionsBuilder.setSourceJars(ImmutableList.of(sourceJar2.toString(), sourceJar1.toString()));
@@ -1090,4 +1103,110 @@ public class JavacTurbineTest {
Map<String, byte[]> outputs = collectOutputs();
assertThat(outputs.keySet()).containsExactly("dummy");
}
+
+ /** An annotation processor that violates the contract. */
+ @SupportedAnnotationTypes("*")
+ public static class MisguidedAnnotationProcessor extends AbstractProcessor {
+
+ public final class Scanner extends TreeScanner<Void, Void> {
+ @Override
+ public Void visitLiteral(LiteralTree tree, Void unused) {
+ values.add(tree.getValue());
+ return null;
+ }
+ }
+
+ public final class Listener implements TaskListener {
+
+ public final ProcessingEnvironment processingEnv;
+
+ Listener(ProcessingEnvironment processingEnv) {
+ this.processingEnv = processingEnv;
+ }
+
+ @Override
+ public void started(TaskEvent e) {}
+
+ @Override
+ public void finished(TaskEvent e) {
+ if (e.getKind() == Kind.ANALYZE) {
+ e.getCompilationUnit().accept(new Scanner(), null);
+ } else if (e.getKind() == Kind.GENERATE) {
+ try {
+ FileObject file =
+ processingEnv
+ .getFiler()
+ .createResource(
+ StandardLocation.CLASS_OUTPUT, "", "output.txt", e.getTypeElement());
+ try (OutputStream os = file.openOutputStream()) {
+ os.write(values.toString().getBytes(UTF_8));
+ }
+ } catch (IOException exception) {
+ throw new IOError(exception);
+ }
+ }
+ }
+ }
+
+ public final Set<Object> values = new LinkedHashSet<>();
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ @Override
+ public synchronized void init(final ProcessingEnvironment processingEnv) {
+ JavacTask.instance(processingEnv).addTaskListener(new Listener(processingEnv));
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ return false;
+ }
+ }
+
+ void setupMisguidedProcessor() throws Exception {
+ addSourceLines(
+ "Hello.java",
+ "@Deprecated class Hello {",
+ " int x = 42;",
+ " String s = \"hello\";",
+ " double y = 42.1;",
+ "}");
+
+ Path processorJar =
+ createClassJar(
+ "libprocessor.jar",
+ MisguidedAnnotationProcessor.class,
+ MisguidedAnnotationProcessor.Listener.class,
+ MisguidedAnnotationProcessor.Scanner.class);
+
+ optionsBuilder.addProcessors(ImmutableList.of(MisguidedAnnotationProcessor.class.getName()));
+ optionsBuilder.addProcessorPathEntries(ImmutableList.of(processorJar.toString()));
+ }
+
+ @Test
+ public void misguidedProcessor_pruning() throws Exception {
+ setupMisguidedProcessor();
+ compile();
+ Map<String, byte[]> outputs = collectOutputs();
+
+ assertThat(outputs.keySet()).containsExactly("Hello.class", "output.txt");
+ String output = new String(outputs.get("output.txt"), UTF_8);
+ assertThat(output).isEqualTo("[]");
+ }
+
+ @Test
+ public void misguidedProcessor() throws Exception {
+ setupMisguidedProcessor();
+ optionsBuilder.addBlacklistedProcessors(
+ ImmutableList.of(MisguidedAnnotationProcessor.class.getName()));
+ compile();
+ Map<String, byte[]> outputs = collectOutputs();
+
+ assertThat(outputs.keySet()).containsExactly("Hello.class", "output.txt");
+ String output = new String(outputs.get("output.txt"), UTF_8);
+ assertThat(output).isEqualTo("[42, hello, 42.1]");
+ }
}