of(),
+ null, // explicitly use the default behaviour because Eclipse compiler fails with empty Set
sources);
try {
Iterable extends CompilationUnitTree> parsedCompilationUnits = task.parse();
diff --git a/src/main/java/com/google/testing/compile/CompilationRule.java b/src/main/java/com/google/testing/compile/CompilationRule.java
index 0be82843..763d4847 100644
--- a/src/main/java/com/google/testing/compile/CompilationRule.java
+++ b/src/main/java/com/google/testing/compile/CompilationRule.java
@@ -17,9 +17,10 @@
import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.Charsets;
+import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-import com.google.testing.compile.Compilation.Result;
import org.junit.Rule;
import org.junit.rules.TestRule;
@@ -37,61 +38,88 @@
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.ToolProvider;
/**
- * A {@link JUnit4} {@link Rule} that executes tests such that a instances of {@link Elements} and
+ * A {@link JUnit4} {@link Rule} that executes tests such that instances of {@link Elements} and
* {@link Types} are available during execution.
*
* To use this rule in a test, just add the following field:
* {@code @Rule} public CompilationRule compilationRule = new CompilationRule();
*
+ * This rule uses {@link ToolProvider#getSystemJavaCompiler() javac} by default, but you can
+ * also pass a supplier of {@link JavaCompiler} to use other compilers, such as Eclipse ECJ.
+ *
* @author Gregory Kick
*/
public final class CompilationRule implements TestRule {
+ private final Supplier compilerSupplier;
+
private Elements elements;
private Types types;
+ public CompilationRule() {
+ this(new Supplier() {
+ @Override
+ public JavaCompiler get() {
+ return ToolProvider.getSystemJavaCompiler();
+ }
+ });
+ }
+
+ public CompilationRule(Supplier compilerSupplier) {
+ this.compilerSupplier = compilerSupplier;
+ }
+
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override public void evaluate() throws Throwable {
final AtomicReference thrown = new AtomicReference();
- Result result = Compilation.compile(ImmutableList.of(new AbstractProcessor() {
- @Override
- public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.latest();
- }
+ JavaCompiler compiler = compilerSupplier.get();
+ DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
+ JavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, null, Charsets.UTF_8);
+ CompilationTask task = compiler.getTask(null, fileManager, diagnosticCollector, null,
+ ImmutableSet.of(CompilationRule.class.getCanonicalName()), null);
+ task.setProcessors(ImmutableList.of(new AbstractProcessor() {
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
- @Override
- public Set getSupportedAnnotationTypes() {
- return ImmutableSet.of("*");
- }
+ @Override
+ public Set getSupportedAnnotationTypes() {
+ return ImmutableSet.of("*");
+ }
- @Override
- public synchronized void init(ProcessingEnvironment processingEnv) {
- super.init(processingEnv);
- elements = processingEnv.getElementUtils();
- types = processingEnv.getTypeUtils();
- }
+ @Override
+ public synchronized void init(ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+ elements = processingEnv.getElementUtils();
+ types = processingEnv.getTypeUtils();
+ }
- @Override
- public boolean process(Set extends TypeElement> annotations,
- RoundEnvironment roundEnv) {
- // just run the test on the last round after compilation is over
- if (roundEnv.processingOver()) {
- try {
- base.evaluate();
- } catch (Throwable e) {
- thrown.set(e);
+ @Override
+ public boolean process(Set extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ // just run the test on the last round after compilation is over
+ if (roundEnv.processingOver()) {
+ try {
+ base.evaluate();
+ } catch (Throwable e) {
+ thrown.set(e);
+ }
+ }
+ return false;
}
- }
- return false;
- }
- }),
- ImmutableSet.of(),
- // just compile _something_
- ImmutableList.of(JavaFileObjects.forSourceLines("Dummy", "final class Dummy {}")));
- checkState(result.successful(), result);
+ }));
+ boolean successful = task.call();
+ checkState(successful);
Throwable t = thrown.get();
if (t != null) {
throw t;
diff --git a/src/main/java/com/google/testing/compile/JavaSourcesSubject.java b/src/main/java/com/google/testing/compile/JavaSourcesSubject.java
index 42f7dfd9..0cda7f11 100644
--- a/src/main/java/com/google/testing/compile/JavaSourcesSubject.java
+++ b/src/main/java/com/google/testing/compile/JavaSourcesSubject.java
@@ -48,8 +48,10 @@
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.FileObject;
+import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
+import javax.tools.ToolProvider;
/**
* A Truth {@link Subject} that evaluates the result
@@ -60,12 +62,19 @@
@SuppressWarnings("restriction") // Sun APIs usage intended
public final class JavaSourcesSubject
extends Subject>
- implements CompileTester, ProcessedCompileTesterFactory {
+ implements ProcessedCompileTesterFactory {
private final List options = new ArrayList(Arrays.asList("-Xlint"));
+ private JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaSourcesSubject(FailureStrategy failureStrategy, Iterable extends JavaFileObject> subject) {
super(failureStrategy, subject);
}
+
+ @Override
+ public JavaSourcesSubject withCompiler(JavaCompiler javaCompiler) {
+ this.compiler = javaCompiler;
+ return this;
+ }
@Override
public JavaSourcesSubject withCompilerOptions(Iterable options) {
@@ -161,7 +170,7 @@ private String reportFilesGenerated(Compilation.Result result) {
@Override
public void parsesAs(JavaFileObject first, JavaFileObject... rest) {
- Compilation.ParseResult actualResult = Compilation.parse(getSubject());
+ Compilation.ParseResult actualResult = Compilation.parse(compiler, getSubject());
ImmutableList> errors =
actualResult.diagnosticsByKind().get(Kind.ERROR);
if (!errors.isEmpty()) {
@@ -172,7 +181,7 @@ public void parsesAs(JavaFileObject first, JavaFileObject... rest) {
}
failureStrategy.fail(message.toString());
}
- final Compilation.ParseResult expectedResult = Compilation.parse(Lists.asList(first, rest));
+ final Compilation.ParseResult expectedResult = Compilation.parse(compiler, Lists.asList(first, rest));
final FluentIterable extends CompilationUnitTree> actualTrees = FluentIterable.from(
actualResult.compilationUnits());
final FluentIterable extends CompilationUnitTree> expectedTrees = FluentIterable.from(
@@ -295,7 +304,7 @@ public CleanCompilationClause compilesWithoutWarnings() {
private Compilation.Result successfulCompilationResult() {
Compilation.Result result =
- Compilation.compile(processors, options, getSubject());
+ Compilation.compile(compiler, processors, options, getSubject());
if (!result.successful()) {
ImmutableList> errors =
result.diagnosticsByKind().get(Kind.ERROR);
@@ -313,7 +322,7 @@ private Compilation.Result successfulCompilationResult() {
@Override
public UnsuccessfulCompilationClause failsToCompile() {
- Result result = Compilation.compile(processors, options, getSubject());
+ Result result = Compilation.compile(compiler, processors, options, getSubject());
if (result.successful()) {
String message = Joiner.on('\n').join(
"Compilation was expected to fail, but contained no errors.",
@@ -748,7 +757,7 @@ public static JavaSourcesSubject assertThat(JavaFileObject... javaFileObjects) {
public static final class SingleSourceAdapter
extends Subject
- implements CompileTester, ProcessedCompileTesterFactory {
+ implements ProcessedCompileTesterFactory {
private final JavaSourcesSubject delegate;
SingleSourceAdapter(FailureStrategy failureStrategy, JavaFileObject subject) {
@@ -756,6 +765,10 @@ public static final class SingleSourceAdapter
this.delegate =
new JavaSourcesSubject(failureStrategy, ImmutableList.of(subject));
}
+
+ public JavaSourcesSubject withCompiler(JavaCompiler javaCompiler) {
+ return this.delegate.withCompiler(javaCompiler);
+ }
@Override
public JavaSourcesSubject withCompilerOptions(Iterable options) {
diff --git a/src/main/java/com/google/testing/compile/MoreTrees.java b/src/main/java/com/google/testing/compile/MoreTrees.java
index e3833895..2cb2f543 100644
--- a/src/main/java/com/google/testing/compile/MoreTrees.java
+++ b/src/main/java/com/google/testing/compile/MoreTrees.java
@@ -38,6 +38,7 @@
import java.util.Arrays;
import javax.annotation.Nullable;
+import javax.tools.ToolProvider;
/**
* A class containing methods which are useful for gaining access to {@code Tree} instances from
@@ -52,8 +53,8 @@ static CompilationUnitTree parseLinesToTree(String... source) {
/** Parses the source given into a {@link CompilationUnitTree}. */
static CompilationUnitTree parseLinesToTree(Iterable source) {
- Iterable extends CompilationUnitTree> parseResults = Compilation.parse(ImmutableList.of(
- JavaFileObjects.forSourceLines("", source))).compilationUnits();
+ Iterable extends CompilationUnitTree> parseResults = Compilation.parse(ToolProvider.getSystemJavaCompiler(),
+ ImmutableList.of(JavaFileObjects.forSourceLines("", source))).compilationUnits();
return Iterables.getOnlyElement(parseResults);
}
@@ -64,7 +65,8 @@ static Compilation.ParseResult parseLines(String... source) {
/** Parses the source given and produces a {@link Compilation.ParseResult}. */
static Compilation.ParseResult parseLines(Iterable source) {
- return Compilation.parse(ImmutableList.of(JavaFileObjects.forSourceLines("", source)));
+ return Compilation.parse(ToolProvider.getSystemJavaCompiler(),
+ ImmutableList.of(JavaFileObjects.forSourceLines("", source)));
}
/**
diff --git a/src/main/java/com/google/testing/compile/ProcessedCompileTesterFactory.java b/src/main/java/com/google/testing/compile/ProcessedCompileTesterFactory.java
index add8a054..11223c5b 100644
--- a/src/main/java/com/google/testing/compile/ProcessedCompileTesterFactory.java
+++ b/src/main/java/com/google/testing/compile/ProcessedCompileTesterFactory.java
@@ -17,6 +17,7 @@
import javax.annotation.CheckReturnValue;
import javax.annotation.processing.Processor;
+import javax.tools.JavaCompiler;
/**
* Creates {@link CompileTester} instances that test compilation with provided {@link Processor}
@@ -24,7 +25,11 @@
*
* @author Gregory Kick
*/
-public interface ProcessedCompileTesterFactory {
+public interface ProcessedCompileTesterFactory extends CompileTester{
+
+ /** Specify compiler (Javac, Eclipse ECJ, ...) **/
+ @CheckReturnValue
+ ProcessedCompileTesterFactory withCompiler(JavaCompiler var1);
/**
* Adds options that will be passed to the compiler. {@code -Xlint} is the first option, by
diff --git a/src/test/java/com/google/testing/compile/EclipseCompilationRuleTest.java b/src/test/java/com/google/testing/compile/EclipseCompilationRuleTest.java
new file mode 100644
index 00000000..c7cadc2d
--- /dev/null
+++ b/src/test/java/com/google/testing/compile/EclipseCompilationRuleTest.java
@@ -0,0 +1,21 @@
+package com.google.testing.compile;
+
+import javax.tools.JavaCompiler;
+
+import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import com.google.common.base.Supplier;
+
+@RunWith(JUnit4.class)
+public class EclipseCompilationRuleTest extends CompilationRuleTest {
+ {
+ compilationRule = new CompilationRule(new Supplier() {
+ @Override
+ public JavaCompiler get() {
+ return new EclipseCompiler();
+ }
+ });
+ }
+}
diff --git a/src/test/java/com/google/testing/compile/JavaSourcesSubjectFactoryTest.java b/src/test/java/com/google/testing/compile/JavaSourcesSubjectFactoryTest.java
index fb14c4ec..e75cf992 100644
--- a/src/test/java/com/google/testing/compile/JavaSourcesSubjectFactoryTest.java
+++ b/src/test/java/com/google/testing/compile/JavaSourcesSubjectFactoryTest.java
@@ -29,6 +29,7 @@
import com.google.common.truth.FailureStrategy;
import com.google.common.truth.TestVerb;
+import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -107,6 +108,15 @@ public void compilesWithoutError() {
.compilesWithoutError();
}
+ @Test
+ public void compilesWithoutErrorWithEclipseCompiler() {
+ assertAbout(javaSource())
+ .that(JavaFileObjects.forResource(Resources.getResource("HelloWorld.java")))
+ .withCompiler(new EclipseCompiler())
+ .withCompilerOptions("-nowarn", "-1.6")
+ .compilesWithoutError();
+ }
+
@Test
public void compilesWithoutWarnings() {
assertAbout(javaSource()).that(HELLO_WORLD).compilesWithoutWarnings();