Skip to content

Commit 35ae925

Browse files
doanduyhaitbroyer
authored andcommitted
Support alternate JavaCompilers (such as ECJ) in JavaSourcesSubject
1 parent 88dfce7 commit 35ae925

File tree

6 files changed

+82
-58
lines changed

6 files changed

+82
-58
lines changed

src/main/java/com/google/testing/compile/Compilation.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ private Compilation() {}
5555
*
5656
* @throws RuntimeException if compilation fails.
5757
*/
58-
static Result compile(Iterable<? extends Processor> processors,
58+
static Result compile(JavaCompiler compiler, Iterable<? extends Processor> processors,
5959
Set<String> options, Iterable<? extends JavaFileObject> sources) {
60-
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
6160
if (compiler == null) {
6261
throw new IllegalStateException("Java Compiler is not present. "
6362
+ "May be, you need to include tools.jar on your dependency list.");
@@ -71,7 +70,7 @@ static Result compile(Iterable<? extends Processor> processors,
7170
fileManager,
7271
diagnosticCollector,
7372
ImmutableSet.copyOf(options),
74-
ImmutableSet.<String>of(),
73+
null, // explicitly use the default behaviour because Eclipse compiler fails with empty Set
7574
sources);
7675
task.setProcessors(processors);
7776
boolean successful = task.call();
@@ -83,8 +82,7 @@ static Result compile(Iterable<? extends Processor> processors,
8382
* Parse {@code sources} into {@linkplain CompilationUnitTree compilation units}. This method
8483
* <b>does not</b> compile the sources.
8584
*/
86-
static ParseResult parse(Iterable<? extends JavaFileObject> sources) {
87-
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
85+
static ParseResult parse(JavaCompiler compiler, Iterable<? extends JavaFileObject> sources) {
8886
DiagnosticCollector<JavaFileObject> diagnosticCollector =
8987
new DiagnosticCollector<JavaFileObject>();
9088
InMemoryJavaFileManager fileManager = new InMemoryJavaFileManager(
@@ -94,7 +92,7 @@ static ParseResult parse(Iterable<? extends JavaFileObject> sources) {
9492
fileManager,
9593
diagnosticCollector,
9694
ImmutableSet.<String>of(),
97-
ImmutableSet.<String>of(),
95+
null, // explicitly use the default behaviour because Eclipse compiler fails with empty Set
9896
sources);
9997
try {
10098
Iterable<? extends CompilationUnitTree> parsedCompilationUnits = task.parse();

src/main/java/com/google/testing/compile/CompilationRule.java

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.common.base.Supplier;
2222
import com.google.common.collect.ImmutableList;
2323
import com.google.common.collect.ImmutableSet;
24+
import com.google.testing.compile.Compilation.Result;
2425

2526
import org.junit.Rule;
2627
import org.junit.rules.TestRule;
@@ -89,36 +90,36 @@ public Statement apply(final Statement base, Description description) {
8990
CompilationTask task = compiler.getTask(null, fileManager, diagnosticCollector, null,
9091
ImmutableSet.of(CompilationRule.class.getCanonicalName()), null);
9192
task.setProcessors(ImmutableList.of(new AbstractProcessor() {
92-
@Override
93-
public SourceVersion getSupportedSourceVersion() {
94-
return SourceVersion.latest();
95-
}
93+
@Override
94+
public SourceVersion getSupportedSourceVersion() {
95+
return SourceVersion.latest();
96+
}
9697

97-
@Override
98-
public Set<String> getSupportedAnnotationTypes() {
99-
return ImmutableSet.of("*");
100-
}
98+
@Override
99+
public Set<String> getSupportedAnnotationTypes() {
100+
return ImmutableSet.of("*");
101+
}
101102

102-
@Override
103-
public synchronized void init(ProcessingEnvironment processingEnv) {
104-
super.init(processingEnv);
105-
elements = processingEnv.getElementUtils();
106-
types = processingEnv.getTypeUtils();
107-
}
103+
@Override
104+
public synchronized void init(ProcessingEnvironment processingEnv) {
105+
super.init(processingEnv);
106+
elements = processingEnv.getElementUtils();
107+
types = processingEnv.getTypeUtils();
108+
}
108109

109-
@Override
110-
public boolean process(Set<? extends TypeElement> annotations,
111-
RoundEnvironment roundEnv) {
112-
// just run the test on the last round after compilation is over
113-
if (roundEnv.processingOver()) {
114-
try {
115-
base.evaluate();
116-
} catch (Throwable e) {
117-
thrown.set(e);
118-
}
119-
}
120-
return false;
110+
@Override
111+
public boolean process(Set<? extends TypeElement> annotations,
112+
RoundEnvironment roundEnv) {
113+
// just run the test on the last round after compilation is over
114+
if (roundEnv.processingOver()) {
115+
try {
116+
base.evaluate();
117+
} catch (Throwable e) {
118+
thrown.set(e);
121119
}
120+
}
121+
return false;
122+
}
122123
}));
123124
boolean successful = task.call();
124125
checkState(successful);

src/main/java/com/google/testing/compile/JavaSourcesSubject.java

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,8 @@
4343
import java.util.Set;
4444

4545
import javax.annotation.processing.Processor;
46-
import javax.tools.Diagnostic;
46+
import javax.tools.*;
4747
import javax.tools.Diagnostic.Kind;
48-
import javax.tools.FileObject;
49-
import javax.tools.JavaFileManager;
50-
import javax.tools.JavaFileObject;
5148

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

6462
JavaSourcesSubject(FailureStrategy failureStrategy, Iterable<? extends JavaFileObject> subject) {
6563
super(failureStrategy, subject);
6664
}
67-
65+
66+
@Override
67+
public ProcessedCompileTesterFactory withCompiler(JavaCompiler javaCompiler) {
68+
this.compiler = javaCompiler;
69+
return this;
70+
}
71+
6872
@Override
6973
public ProcessedCompileTesterFactory withCompilerOptions(Iterable<String> options) {
7074
Iterables.addAll(this.options, options);
@@ -154,7 +158,7 @@ private String reportFilesGenerated(Compilation.Result result) {
154158

155159
@Override
156160
public void parsesAs(JavaFileObject first, JavaFileObject... rest) {
157-
Compilation.ParseResult actualResult = Compilation.parse(getSubject());
161+
Compilation.ParseResult actualResult = Compilation.parse(compiler, getSubject());
158162
ImmutableList<Diagnostic<? extends JavaFileObject>> errors =
159163
actualResult.diagnosticsByKind().get(Kind.ERROR);
160164
if (!errors.isEmpty()) {
@@ -165,7 +169,7 @@ public void parsesAs(JavaFileObject first, JavaFileObject... rest) {
165169
}
166170
failureStrategy.fail(message.toString());
167171
}
168-
final Compilation.ParseResult expectedResult = Compilation.parse(Lists.asList(first, rest));
172+
final Compilation.ParseResult expectedResult = Compilation.parse(compiler, Lists.asList(first, rest));
169173
final FluentIterable<? extends CompilationUnitTree> actualTrees = FluentIterable.from(
170174
actualResult.compilationUnits());
171175
final FluentIterable<? extends CompilationUnitTree> expectedTrees = FluentIterable.from(
@@ -279,7 +283,7 @@ private void failWithCandidate(JavaFileObject expectedSource,
279283
@Override
280284
public SuccessfulCompilationClause compilesWithoutError() {
281285
Compilation.Result result =
282-
Compilation.compile(processors, ImmutableSet.copyOf(options), getSubject());
286+
Compilation.compile(compiler, processors, ImmutableSet.copyOf(options), getSubject());
283287
if (!result.successful()) {
284288
ImmutableList<Diagnostic<? extends JavaFileObject>> errors =
285289
result.diagnosticsByKind().get(Kind.ERROR);
@@ -297,7 +301,7 @@ public SuccessfulCompilationClause compilesWithoutError() {
297301

298302
@Override
299303
public UnsuccessfulCompilationClause failsToCompile() {
300-
Result result = Compilation.compile(processors, ImmutableSet.copyOf(options), getSubject());
304+
Result result = Compilation.compile(compiler, processors, ImmutableSet.copyOf(options), getSubject());
301305
if (result.successful()) {
302306
String message = Joiner.on('\n').join(
303307
"Compilation was expected to fail, but contained no errors.",
@@ -553,15 +557,19 @@ public SuccessfulFileClause withContents(ByteSource expectedByteSource) {
553557

554558
public static final class SingleSourceAdapter
555559
extends Subject<SingleSourceAdapter, JavaFileObject>
556-
implements CompileTester, ProcessedCompileTesterFactory {
560+
implements ProcessedCompileTesterFactory {
557561
private final JavaSourcesSubject delegate;
558562

559563
SingleSourceAdapter(FailureStrategy failureStrategy, JavaFileObject subject) {
560564
super(failureStrategy, subject);
561565
this.delegate =
562566
new JavaSourcesSubject(failureStrategy, ImmutableList.of(subject));
563567
}
564-
568+
569+
public ProcessedCompileTesterFactory withCompiler(JavaCompiler javaCompiler) {
570+
return this.delegate.withCompiler(javaCompiler);
571+
}
572+
565573
@Override
566574
public ProcessedCompileTesterFactory withCompilerOptions(Iterable<String> options) {
567575
return delegate.withCompilerOptions(options);

src/main/java/com/google/testing/compile/MoreTrees.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.Arrays;
3939

4040
import javax.annotation.Nullable;
41+
import javax.tools.ToolProvider;
4142

4243
/**
4344
* A class containing methods which are useful for gaining access to {@code Tree} instances from
@@ -52,8 +53,8 @@ static CompilationUnitTree parseLinesToTree(String... source) {
5253

5354
/** Parses the source given into a {@link CompilationUnitTree}. */
5455
static CompilationUnitTree parseLinesToTree(Iterable<String> source) {
55-
Iterable<? extends CompilationUnitTree> parseResults = Compilation.parse(ImmutableList.of(
56-
JavaFileObjects.forSourceLines("", source))).compilationUnits();
56+
Iterable<? extends CompilationUnitTree> parseResults = Compilation.parse(ToolProvider.getSystemJavaCompiler(),
57+
ImmutableList.of(JavaFileObjects.forSourceLines("", source))).compilationUnits();
5758
return Iterables.getOnlyElement(parseResults);
5859
}
5960

@@ -64,7 +65,8 @@ static Compilation.ParseResult parseLines(String... source) {
6465

6566
/** Parses the source given and produces a {@link Compilation.ParseResult}. */
6667
static Compilation.ParseResult parseLines(Iterable<String> source) {
67-
return Compilation.parse(ImmutableList.of(JavaFileObjects.forSourceLines("", source)));
68+
return Compilation.parse(ToolProvider.getSystemJavaCompiler(),
69+
ImmutableList.of(JavaFileObjects.forSourceLines("", source)));
6870
}
6971

7072
/**

src/main/java/com/google/testing/compile/ProcessedCompileTesterFactory.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,19 @@
1717

1818
import javax.annotation.CheckReturnValue;
1919
import javax.annotation.processing.Processor;
20+
import javax.tools.JavaCompiler;
2021

2122
/**
2223
* Creates {@link CompileTester} instances that test compilation with provided {@link Processor}
2324
* instances.
2425
*
2526
* @author Gregory Kick
2627
*/
27-
public interface ProcessedCompileTesterFactory {
28+
public interface ProcessedCompileTesterFactory extends CompileTester{
29+
30+
/** Specify compiler (Javac, Eclipse ECJ, ...) **/
31+
@CheckReturnValue
32+
ProcessedCompileTesterFactory withCompiler(JavaCompiler var1);
2833

2934
/** Adds options that will be passed to the compiler. */
3035
@CheckReturnValue ProcessedCompileTesterFactory withCompilerOptions(Iterable<String> options);

src/test/java/com/google/testing/compile/JavaSourcesSubjectFactoryTest.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.google.common.truth.FailureStrategy;
3030
import com.google.common.truth.TestVerb;
3131

32+
import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
3233
import org.junit.Test;
3334
import org.junit.runner.RunWith;
3435
import org.junit.runners.JUnit4;
@@ -81,6 +82,15 @@ public void compilesWithoutError() {
8182
.compilesWithoutError();
8283
}
8384

85+
@Test
86+
public void compilesWithoutErrorWithEclipseCompiler() {
87+
assertAbout(javaSource())
88+
.that(JavaFileObjects.forResource(Resources.getResource("HelloWorld.java")))
89+
.withCompiler(new EclipseCompiler())
90+
.withCompilerOptions("-nowarn", "-1.6")
91+
.compilesWithoutError();
92+
}
93+
8494
@Test
8595
public void compilesWithoutError_failureReportsFiles() {
8696
try {
@@ -116,16 +126,16 @@ public void compilesWithoutError_exceptionCreatedOrPassedThrough() {
116126
VERIFY.about(javaSource())
117127
.that(JavaFileObjects.forResource("HelloWorld.java"))
118128
.processedWith(new AbstractProcessor() {
119-
@Override
120-
public Set<String> getSupportedAnnotationTypes() {
121-
return ImmutableSet.of("*");
122-
}
123-
124-
@Override
125-
public boolean process(Set<? extends TypeElement> annotations,
126-
RoundEnvironment roundEnv) {
127-
throw e;
128-
}
129+
@Override
130+
public Set<String> getSupportedAnnotationTypes() {
131+
return ImmutableSet.of("*");
132+
}
133+
134+
@Override
135+
public boolean process(Set<? extends TypeElement> annotations,
136+
RoundEnvironment roundEnv) {
137+
throw e;
138+
}
129139
})
130140
.compilesWithoutError();
131141
fail();

0 commit comments

Comments
 (0)