Skip to content

Commit

Permalink
Support alternate JavaCompilers (such as ECJ) in CompilationRule
Browse files Browse the repository at this point in the history
ECJ expects all JavaFileObjects to be Files, so the rule no longer
uses Compilation.compile() but instead directly uses the JavaCompiler,
and processes a class rather than compiling a dummy (in-memory) source.
  • Loading branch information
tbroyer committed Mar 13, 2016
1 parent 814eca2 commit 7a21219
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 8 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@
<version>${jsr305.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.4.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
44 changes: 36 additions & 8 deletions src/main/java/com/google/testing/compile/CompilationRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -37,26 +38,55 @@
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.
*
* <p>To use this rule in a test, just add the following field: <pre><code>
* {@code @Rule} public CompilationRule compilationRule = new CompilationRule();</code></pre>
*
* <p>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<JavaCompiler> compilerSupplier;

private Elements elements;
private Types types;

public CompilationRule() {
this(new Supplier<JavaCompiler>() {
@Override
public JavaCompiler get() {
return ToolProvider.getSystemJavaCompiler();
}
});
}

public CompilationRule(Supplier<JavaCompiler> compilerSupplier) {
this.compilerSupplier = compilerSupplier;
}

@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override public void evaluate() throws Throwable {
final AtomicReference<Throwable> thrown = new AtomicReference<Throwable>();
Result result = Compilation.compile(ImmutableList.of(new AbstractProcessor() {
JavaCompiler compiler = compilerSupplier.get();
DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<JavaFileObject>();
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();
Expand Down Expand Up @@ -87,11 +117,9 @@ public boolean process(Set<? extends TypeElement> annotations,
}
return false;
}
}),
ImmutableSet.<String>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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<JavaCompiler>() {
@Override
public JavaCompiler get() {
return new EclipseCompiler();
}
});
}
}

0 comments on commit 7a21219

Please sign in to comment.