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
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
@@ -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>
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
@@ -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.");
@@ -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();
@@ -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(
@@ -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();
Original file line number Diff line number Diff line change
@@ -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
@@ -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();
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
@@ -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
@@ -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);
@@ -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()) {
@@ -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(
@@ -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);
@@ -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.",
@@ -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);
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
@@ -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<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);
}

@@ -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)));
}

/**
Original file line number Diff line number Diff line change
@@ -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);
Original file line number Diff line number Diff line change
@@ -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;
@@ -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 {
@@ -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();