Add support for annotation processors with TestCompiler
Closes gh-28582
This commit is contained in:
parent
4128a71657
commit
45ef21f900
|
@ -18,10 +18,13 @@ package org.springframework.aot.test.generator.compile;
|
|||
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaCompiler;
|
||||
|
@ -43,6 +46,7 @@ import org.springframework.lang.Nullable;
|
|||
* Utility that can be used to dynamically compile and test Java source code.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Scott Frederick
|
||||
* @since 6.0
|
||||
* @see #forSystem()
|
||||
*/
|
||||
|
@ -57,13 +61,18 @@ public final class TestCompiler {
|
|||
|
||||
private final ResourceFiles resourceFiles;
|
||||
|
||||
private final List<Processor> processors;
|
||||
|
||||
|
||||
private TestCompiler(@Nullable ClassLoader classLoader, JavaCompiler compiler,
|
||||
SourceFiles sourceFiles, ResourceFiles resourceFiles) {
|
||||
SourceFiles sourceFiles, ResourceFiles resourceFiles,
|
||||
List<Processor> processors) {
|
||||
|
||||
this.classLoader = classLoader;
|
||||
this.compiler = compiler;
|
||||
this.sourceFiles = sourceFiles;
|
||||
this.resourceFiles = resourceFiles;
|
||||
this.processors = processors;
|
||||
}
|
||||
|
||||
|
||||
|
@ -83,7 +92,7 @@ public final class TestCompiler {
|
|||
*/
|
||||
public static TestCompiler forCompiler(JavaCompiler javaCompiler) {
|
||||
return new TestCompiler(null, javaCompiler, SourceFiles.none(),
|
||||
ResourceFiles.none());
|
||||
ResourceFiles.none(), Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,7 +119,7 @@ public final class TestCompiler {
|
|||
*/
|
||||
public TestCompiler withSources(SourceFile... sourceFiles) {
|
||||
return new TestCompiler(this.classLoader, this.compiler,
|
||||
this.sourceFiles.and(sourceFiles), this.resourceFiles);
|
||||
this.sourceFiles.and(sourceFiles), this.resourceFiles, this.processors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,7 +129,7 @@ public final class TestCompiler {
|
|||
*/
|
||||
public TestCompiler withSources(Iterable<SourceFile> sourceFiles) {
|
||||
return new TestCompiler(this.classLoader, this.compiler,
|
||||
this.sourceFiles.and(sourceFiles), this.resourceFiles);
|
||||
this.sourceFiles.and(sourceFiles), this.resourceFiles, this.processors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,7 +139,7 @@ public final class TestCompiler {
|
|||
*/
|
||||
public TestCompiler withSources(SourceFiles sourceFiles) {
|
||||
return new TestCompiler(this.classLoader, this.compiler,
|
||||
this.sourceFiles.and(sourceFiles), this.resourceFiles);
|
||||
this.sourceFiles.and(sourceFiles), this.resourceFiles, this.processors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,7 +149,7 @@ public final class TestCompiler {
|
|||
*/
|
||||
public TestCompiler withResources(ResourceFile... resourceFiles) {
|
||||
return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles,
|
||||
this.resourceFiles.and(resourceFiles));
|
||||
this.resourceFiles.and(resourceFiles), this.processors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,7 +159,7 @@ public final class TestCompiler {
|
|||
*/
|
||||
public TestCompiler withResources(Iterable<ResourceFile> resourceFiles) {
|
||||
return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles,
|
||||
this.resourceFiles.and(resourceFiles));
|
||||
this.resourceFiles.and(resourceFiles), this.processors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,9 +169,32 @@ public final class TestCompiler {
|
|||
*/
|
||||
public TestCompiler withResources(ResourceFiles resourceFiles) {
|
||||
return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles,
|
||||
this.resourceFiles.and(resourceFiles));
|
||||
this.resourceFiles.and(resourceFiles), this.processors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new {@link TestCompiler} instance with additional annotation processors.
|
||||
* @param processors the additional annotation processors
|
||||
* @return a new {@link TestCompiler} instance
|
||||
*/
|
||||
public TestCompiler withProcessors(Processor... processors) {
|
||||
List<Processor> mergedProcessors = new ArrayList<>(this.processors);
|
||||
mergedProcessors.addAll(Arrays.asList(processors));
|
||||
return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles,
|
||||
this.resourceFiles, mergedProcessors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new {@link TestCompiler} instance with additional annotation processors.
|
||||
* @param processors the additional annotation processors
|
||||
* @return a new {@link TestCompiler} instance
|
||||
*/
|
||||
public TestCompiler withProcessors(Iterable<Processor> processors) {
|
||||
List<Processor> mergedProcessors = new ArrayList<>(this.processors);
|
||||
processors.forEach(mergedProcessors::add);
|
||||
return new TestCompiler(this.classLoader, this.compiler, this.sourceFiles,
|
||||
this.resourceFiles, mergedProcessors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile content from this instance along with the additional provided
|
||||
|
@ -244,6 +276,9 @@ public final class TestCompiler {
|
|||
Errors errors = new Errors();
|
||||
CompilationTask task = this.compiler.getTask(null, fileManager, errors, null,
|
||||
null, compilationUnits);
|
||||
if (!this.processors.isEmpty()) {
|
||||
task.setProcessors(this.processors);
|
||||
}
|
||||
boolean result = task.call();
|
||||
if (!result || errors.hasReportedErrors()) {
|
||||
throw new CompilationException(errors.toString(), this.sourceFiles, this.resourceFiles);
|
||||
|
|
|
@ -16,8 +16,17 @@
|
|||
|
||||
package org.springframework.aot.test.generator.compile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import com.example.PublicInterface;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -33,9 +42,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|||
|
||||
/**
|
||||
* Tests for {@link TestCompiler}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class TestCompilerTests {
|
||||
|
||||
|
@ -140,6 +149,29 @@ class TestCompilerTests {
|
|||
this::assertHasResource);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withProcessorsArrayAddsProcessors() {
|
||||
SourceFile sourceFile = SourceFile.of(HELLO_WORLD);
|
||||
TestProcessor processor = new TestProcessor();
|
||||
TestCompiler.forSystem().withSources(sourceFile).withProcessors(processor).compile((compiled -> {
|
||||
assertThat(processor.getProcessedAnnotations()).isNotEmpty();
|
||||
assertThat(processor.getProcessedAnnotations()).satisfiesExactly(element ->
|
||||
assertThat(element.getQualifiedName().toString()).isEqualTo("java.lang.Deprecated"));
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void withProcessorsAddsProcessors() {
|
||||
SourceFile sourceFile = SourceFile.of(HELLO_WORLD);
|
||||
TestProcessor processor = new TestProcessor();
|
||||
List<Processor> processors = List.of(processor);
|
||||
TestCompiler.forSystem().withSources(sourceFile).withProcessors(processors).compile((compiled -> {
|
||||
assertThat(processor.getProcessedAnnotations()).isNotEmpty();
|
||||
assertThat(processor.getProcessedAnnotations()).satisfiesExactly(element ->
|
||||
assertThat(element.getQualifiedName().toString()).isEqualTo("java.lang.Deprecated"));
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void compileWithWritableContent() {
|
||||
WritableContent content = appendable -> appendable.append(HELLO_WORLD);
|
||||
|
@ -217,4 +249,20 @@ class TestCompilerTests {
|
|||
"META-INF/myfile")).hasContent("test");
|
||||
}
|
||||
|
||||
@SupportedAnnotationTypes("java.lang.Deprecated")
|
||||
static class TestProcessor extends AbstractProcessor {
|
||||
|
||||
private final List<TypeElement> processedAnnotations = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
this.processedAnnotations.addAll(annotations);
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<TypeElement> getProcessedAnnotations() {
|
||||
return this.processedAnnotations;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue