Skip to content

Commit

Permalink
Support alternate JavaCompilers (such as ECJ) in JavaSourcesSubject
Browse files Browse the repository at this point in the history
  • Loading branch information
doanduyhai authored and tbroyer committed Mar 13, 2016
1 parent 7a21219 commit c09dd40
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 43 deletions.
10 changes: 4 additions & 6 deletions src/main/java/com/google/testing/compile/Compilation.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ private Compilation() {}
*
* @throws RuntimeException if compilation fails.
*/
static Result compile(Iterable<? extends Processor> processors,
static Result compile(JavaCompiler compiler, Iterable<? extends Processor> processors,
Iterable<String> options, Iterable<? extends JavaFileObject> sources) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
throw new IllegalStateException("Java Compiler is not present. "
+ "May be, you need to include tools.jar on your dependency list.");
Expand All @@ -70,7 +69,7 @@ static Result compile(Iterable<? extends Processor> processors,
fileManager,
diagnosticCollector,
ImmutableList.copyOf(options),
ImmutableSet.<String>of(),
null, // explicitly use the default behaviour because Eclipse compiler fails with empty Set
sources);
task.setProcessors(processors);
boolean successful = task.call();
Expand All @@ -82,8 +81,7 @@ static Result compile(Iterable<? extends Processor> processors,
* Parse {@code sources} into {@linkplain CompilationUnitTree compilation units}. This method
* <b>does not</b> compile the sources.
*/
static ParseResult parse(Iterable<? extends JavaFileObject> sources) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
static ParseResult parse(JavaCompiler compiler, Iterable<? extends JavaFileObject> sources) {
DiagnosticCollector<JavaFileObject> diagnosticCollector =
new DiagnosticCollector<JavaFileObject>();
InMemoryJavaFileManager fileManager = new InMemoryJavaFileManager(
Expand All @@ -93,7 +91,7 @@ static ParseResult parse(Iterable<? extends JavaFileObject> sources) {
fileManager,
diagnosticCollector,
ImmutableSet.<String>of(),
ImmutableSet.<String>of(),
null, // explicitly use the default behaviour because Eclipse compiler fails with empty Set
sources);
try {
Iterable<? extends CompilationUnitTree> parsedCompilationUnits = task.parse();
Expand Down
54 changes: 27 additions & 27 deletions src/main/java/com/google/testing/compile/CompilationRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,37 +87,37 @@ public Statement apply(final Statement base, Description description) {
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 SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}

@Override
public Set<String> getSupportedAnnotationTypes() {
return ImmutableSet.of("*");
}
@Override
public Set<String> 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;
}
}));
}));
boolean successful = task.call();
checkState(successful);
Throwable t = thrown.get();
Expand Down
25 changes: 19 additions & 6 deletions src/main/java/com/google/testing/compile/JavaSourcesSubject.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a href="https://github.com/truth0/truth">Truth</a> {@link Subject} that evaluates the result
Expand All @@ -60,12 +62,19 @@
@SuppressWarnings("restriction") // Sun APIs usage intended
public final class JavaSourcesSubject
extends Subject<JavaSourcesSubject, Iterable<? extends JavaFileObject>>
implements CompileTester, ProcessedCompileTesterFactory {
implements ProcessedCompileTesterFactory {
private final List<String> options = new ArrayList<String>(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<String> options) {
Expand Down Expand Up @@ -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<Diagnostic<? extends JavaFileObject>> errors =
actualResult.diagnosticsByKind().get(Kind.ERROR);
if (!errors.isEmpty()) {
Expand All @@ -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(
Expand Down Expand Up @@ -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<Diagnostic<? extends JavaFileObject>> errors =
result.diagnosticsByKind().get(Kind.ERROR);
Expand All @@ -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.",
Expand Down Expand Up @@ -748,14 +757,18 @@ public static JavaSourcesSubject assertThat(JavaFileObject... javaFileObjects) {

public static final class SingleSourceAdapter
extends Subject<SingleSourceAdapter, JavaFileObject>
implements CompileTester, ProcessedCompileTesterFactory {
implements ProcessedCompileTesterFactory {
private final JavaSourcesSubject delegate;

SingleSourceAdapter(FailureStrategy failureStrategy, JavaFileObject subject) {
super(failureStrategy, subject);
this.delegate =
new JavaSourcesSubject(failureStrategy, ImmutableList.of(subject));
}

public JavaSourcesSubject withCompiler(JavaCompiler javaCompiler) {
return this.delegate.withCompiler(javaCompiler);
}

@Override
public JavaSourcesSubject withCompilerOptions(Iterable<String> options) {
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/com/google/testing/compile/MoreTrees.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -52,8 +53,8 @@ static CompilationUnitTree parseLinesToTree(String... source) {

/** Parses the source given into a {@link CompilationUnitTree}. */
static CompilationUnitTree parseLinesToTree(Iterable<String> 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);
}

Expand All @@ -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<String> source) {
return Compilation.parse(ImmutableList.of(JavaFileObjects.forSourceLines("", source)));
return Compilation.parse(ToolProvider.getSystemJavaCompiler(),
ImmutableList.of(JavaFileObjects.forSourceLines("", source)));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@

import javax.annotation.CheckReturnValue;
import javax.annotation.processing.Processor;
import javax.tools.JavaCompiler;

/**
* Creates {@link CompileTester} instances that test compilation with provided {@link Processor}
* instances.
*
* @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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit c09dd40

Please sign in to comment.