Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support alternate JavaCompilers (such as ECJ) in JavaSourcesSubject #80

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@
<version>1.3.9</version>
<optional>true</optional>
</dependency>

<!--Eclipse compiler for test-->
<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
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 @@ -55,9 +55,8 @@ private Compilation() {}
*
* @throws RuntimeException if compilation fails.
*/
static Result compile(Iterable<? extends Processor> processors,
static Result compile(JavaCompiler compiler, Iterable<? extends Processor> processors,
Set<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 @@ -71,7 +70,7 @@ static Result compile(Iterable<? extends Processor> processors,
fileManager,
diagnosticCollector,
ImmutableSet.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 @@ -83,8 +82,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 @@ -94,7 +92,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
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.ToolProvider;

/**
* A {@link JUnit4} {@link Rule} that executes tests such that a instances of {@link Elements} and
Expand All @@ -56,7 +57,8 @@ 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() {
Result result = Compilation.compile(ToolProvider.getSystemJavaCompiler(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be even better if you somehow merged #71 into that one wrt passing a JavaCompiler to the CompilationRule rather than always using ToolProvider.getSystemJavaCompiler(). Sure one can easily be rebased on the other anyway…

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, as soon as @tbroyer fixes the file manager thing

ImmutableList.of(new AbstractProcessor() {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
Expand Down
32 changes: 20 additions & 12 deletions src/main/java/com/google/testing/compile/JavaSourcesSubject.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,8 @@
import java.util.Set;

import javax.annotation.processing.Processor;
import javax.tools.Diagnostic;
import javax.tools.*;
import javax.tools.Diagnostic.Kind;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;

/**
* A <a href="https://github.com/truth0/truth">Truth</a> {@link Subject} that evaluates the result
Expand All @@ -59,13 +56,20 @@
@SuppressWarnings("restriction") // Sun APIs usage intended
public final class JavaSourcesSubject
extends Subject<JavaSourcesSubject, Iterable<? extends JavaFileObject>>
implements CompileTester, ProcessedCompileTesterFactory {
implements ProcessedCompileTesterFactory {
private final Set<String> options = Sets.newHashSet();
private JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

JavaSourcesSubject(FailureStrategy failureStrategy, Iterable<? extends JavaFileObject> subject) {
super(failureStrategy, subject);
}


@Override
public ProcessedCompileTesterFactory withCompiler(JavaCompiler javaCompiler) {
this.compiler = javaCompiler;
return this;
}

@Override
public ProcessedCompileTesterFactory withCompilerOptions(Iterable<String> options) {
Iterables.addAll(this.options, options);
Expand Down Expand Up @@ -155,7 +159,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 @@ -166,7 +170,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 @@ -280,7 +284,7 @@ private void failWithCandidate(JavaFileObject expectedSource,
@Override
public SuccessfulCompilationClause compilesWithoutError() {
Compilation.Result result =
Compilation.compile(processors, ImmutableSet.copyOf(options), getSubject());
Compilation.compile(compiler, processors, ImmutableSet.copyOf(options), getSubject());
if (!result.successful()) {
ImmutableList<Diagnostic<? extends JavaFileObject>> errors =
result.diagnosticsByKind().get(Kind.ERROR);
Expand All @@ -298,7 +302,7 @@ public SuccessfulCompilationClause compilesWithoutError() {

@Override
public UnsuccessfulCompilationClause failsToCompile() {
Result result = Compilation.compile(processors, ImmutableSet.copyOf(options), getSubject());
Result result = Compilation.compile(compiler, processors, ImmutableSet.copyOf(options), getSubject());
if (result.successful()) {
String message = Joiner.on('\n').join(
"Compilation was expected to fail, but contained no errors.",
Expand Down Expand Up @@ -571,15 +575,19 @@ public SuccessfulFileClause withContents(ByteSource expectedByteSource) {

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 ProcessedCompileTesterFactory withCompiler(JavaCompiler javaCompiler) {
return this.delegate.withCompiler(javaCompiler);
}

@Override
public ProcessedCompileTesterFactory withCompilerOptions(Iterable<String> options) {
return delegate.withCompilerOptions(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. */
@CheckReturnValue ProcessedCompileTesterFactory withCompilerOptions(Iterable<String> options);
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 @@ -81,6 +82,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 compilesWithoutError_failureReportsFiles() {
try {
Expand Down Expand Up @@ -116,16 +126,16 @@ public void compilesWithoutError_exceptionCreatedOrPassedThrough() {
VERIFY.about(javaSource())
.that(JavaFileObjects.forResource("HelloWorld.java"))
.processedWith(new AbstractProcessor() {
@Override
public Set<String> getSupportedAnnotationTypes() {
return ImmutableSet.of("*");
}

@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
throw e;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return ImmutableSet.of("*");
}

@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
throw e;
}
})
.compilesWithoutError();
fail();
Expand Down