private void compile(Class<? extends AbstractProcessor> processorClass, List<String> classes) throws IOException { List<String> options = new ArrayList<String>(); options.add("-s"); options.add("src/test/java"); options.add("-proc:only"); options.add("-processor"); options.add(processorClass.getName()); options.add("-sourcepath"); options.add("src/test/java"); options.addAll(getAPTOptions()); options.addAll(classes); ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream err = new ByteArrayOutputStream(); int compilationResult = compiler.run(null, out, err, options.toArray(new String[options.size()])); // Processor.elementCache.clear(); if (compilationResult != 0) { Assert.fail("Compilation Failed:\n " + new String(err.toByteArray(), "UTF-8")); } }
/** * Test that the ijar tool preserves EnclosingMethod attributes and doesn't * prevent annotation processors from accessing all the elements in a package. */ @Test public void testEnclosingMethod() throws IOException { JavaCompiler.CompilationTask task = makeCompilationTask("third_party/ijar/test/package-info.java"); task.setProcessors(Arrays.asList(new AbstractProcessor() { @Override public Set<String> getSupportedAnnotationTypes() { return Collections.singleton("*"); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { roundEnv.getElementsAnnotatedWith(java.lang.Override.class); return true; } })); if (!task.call()) { fail(getFailedCompilationMessage()); } }
public boolean generateInfoClasses(AbstractProcessor processor, List<Class<?>> sourceClasses) throws Exception { ImmutableSet<? extends AbstractProcessor> processors = ImmutableSet.of(processor); List<Diagnostic<? extends JavaFileObject>> diagnostics = compileWithProcessors( sourceClasses, processors ); boolean failed = false; for (Diagnostic<?> diagnostic : diagnostics) { failed = failed | (diagnostic.getKind().equals(Kind.ERROR)); System.out.println(String.format("[%s] %s [%s,%s]", diagnostic.getKind(), diagnostic.getMessage(Locale.getDefault()), diagnostic.getLineNumber(), diagnostic.getColumnNumber() )); } return failed; }
@Test public void testModelInfoClassGeneration() throws Exception { AbstractProcessor fieldNameProcessor = createFieldNameProcessor(outputClasses); // TODO hacky - can this be avoided? MetaApiInfoClassGenerator.addPath("./src/test/java/"); boolean hasFailed = generator.generateInfoClasses(fieldNameProcessor, sourceClasses); assertFalse("generation of model info classes failed", hasFailed); File file; for (Class<?> outputClass : outputClasses) { file = new File(filePathFrom(outputClass)); assertTrue("file " + outputClass.getSimpleName() + "Info.java should exist but does not", file.exists()); } }
private AbstractProcessor createFieldNameProcessor(Iterable<Class<?>> classesToOutput) { SourceGenerator<ModelTypeInfo, ModelMethodInfo> classGenerator = new ModelClassInfoSourceGenerator(); HierarchyExtractor hierarchyExtractor = new ReflectionBasedHierarchyExtractor(); SourceFileWriter<ModelTypeInfo> writer = new JavaxSourceFileWriter<>(); TypeParser<ModelTypeInfo, ModelMethodInfo> typeParser = new ModelTypeParser( javadocParser, classesToOutput ); return new FieldNameProcessor( classGenerator, hierarchyExtractor, writer, typeParser, classesToOutput ); }
@Test public void testModelInfoClassGeneration() throws Exception { AbstractProcessor fieldNameProcessor = createFieldNameProcessor(sourceClasses); // TODO hacky - can this be avoided? MetaApiInfoClassGenerator.addPath("./src/test/java/"); boolean hasFailed = generator.generateInfoClasses(fieldNameProcessor, sourceClasses); assertFalse("generation of model info classes failed", hasFailed); File file; for (Class<?> outputClass : sourceClasses) { file = new File(filePathFrom(outputClass)); assertTrue("file " + outputClass.getSimpleName() + "EndpointInfo.java should exist but does not", file.exists()); } }
protected void check() throws Exception { String[] options = { "--should-stop:at=ATTR", "--debug:verboseResolution=success,failure,applicable,inapplicable,deferred-inference,predef" }; AbstractProcessor[] processors = { new ResolveCandidateFinder(), null }; @SuppressWarnings("unchecked") DiagnosticListener<? super JavaFileObject>[] diagListeners = new DiagnosticListener[] { new DiagnosticHandler(false), new DiagnosticHandler(true) }; for (int i = 0 ; i < options.length ; i ++) { JavacTask ct = (JavacTask)comp.getTask(null, fm, diagListeners[i], Arrays.asList(options[i]), null, Arrays.asList(jfo)); if (processors[i] != null) { ct.setProcessors(Collections.singleton(processors[i])); } ct.analyze(); } //check diags for (Diagnostic<? extends JavaFileObject> diag : diags) { for (DiagnosticProcessor proc : diagProcessors) { if (proc.matches(diag)) { proc.process(diag); break; } } } //check all candidates have been used up for (Map.Entry<ElementKey, Candidate> entry : candidatesMap.entrySet()) { if (!seenCandidates.contains(entry.getKey())) { error("Redundant @Candidate annotation on method " + entry.getKey().elem + " sig = " + entry.getKey().elem.asType()); } } }
protected void check() throws Exception { String[] options = { "-XDshouldStopPolicy=ATTR", "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference,predef" }; AbstractProcessor[] processors = { new ResolveCandidateFinder(), null }; @SuppressWarnings("unchecked") DiagnosticListener<? super JavaFileObject>[] diagListeners = new DiagnosticListener[] { new DiagnosticHandler(false), new DiagnosticHandler(true) }; for (int i = 0 ; i < options.length ; i ++) { JavacTask ct = (JavacTask)comp.getTask(null, fm, diagListeners[i], Arrays.asList(options[i]), null, Arrays.asList(jfo)); if (processors[i] != null) { ct.setProcessors(Collections.singleton(processors[i])); } ct.analyze(); } //check diags for (Diagnostic<? extends JavaFileObject> diag : diags) { for (DiagnosticProcessor proc : diagProcessors) { if (proc.matches(diag)) { proc.process(diag); break; } } } //check all candidates have been used up for (Map.Entry<ElementKey, Candidate> entry : candidatesMap.entrySet()) { if (!seenCandidates.contains(entry.getKey())) { error("Redundant @Candidate annotation on method " + entry.getKey().elem + " sig = " + entry.getKey().elem.asType()); } } }
private static AbstractProcessor createWrappedInstance() { ClassLoader cl = Main.createShadowClassLoader(); try { Class<?> mc = cl.loadClass("lombok.core.AnnotationProcessor"); return (AbstractProcessor) mc.newInstance(); } catch (Throwable t) { if (t instanceof Error) throw (Error) t; if (t instanceof RuntimeException) throw (RuntimeException) t; throw new RuntimeException(t); } }
static void assertProcess(BiConsumer<ProcessingEnvironment, RoundEnvironment> test) { File f = null; try { f = Files.createTempFile("test", ".java").toFile(); try (PrintWriter writer = new PrintWriter(f)) { writer.print("class Empty {}"); } } catch (IOException e) { throw new AssertionError(e); } JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, Locale.getDefault(), Charset.defaultCharset()); JavaCompiler.CompilationTask task = compiler.getTask(new PrintWriter(System.out), fileManager, diagnostics, Collections.singletonList("-proc:only"), Collections.emptyList(), fileManager.getJavaFileObjectsFromFiles(Collections.singletonList(f))); task.setLocale(Locale.getDefault()); task.setProcessors(Collections.singleton(new AbstractProcessor() { @Override public Set<String> getSupportedAnnotationTypes() { return Collections.singleton("*"); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { test.accept(processingEnv, roundEnv); return true; } })); assertTrue(task.call()); }
@Test public void testGen() throws Exception { AtomicInteger count = new AtomicInteger(); AbstractProcessor proc = new AbstractProcessor() { @Override public Set<String> getSupportedAnnotationTypes() { return Collections.singleton("*"); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (count.getAndIncrement() == 0) { try { Filer filer = processingEnv.getFiler(); Element elt = processingEnv.getElementUtils().getTypeElement("gen.GeneratedClass"); JavaFileObject src = filer.createSourceFile("io.vertx.test.gen.GeneratedClass", elt); try (Writer writer = src.openWriter()) { writer.append("package io.vertx.test.gen;\npublic class GeneratedClass {\n}"); } } catch (Exception e) { e.printStackTrace(); } } return true; } }; Compiler<TestGenProcessor> compiler = buildCompiler(new TestGenProcessor(), "io.vertx.test.gen"); compiler.addProcessor(proc); compiler.assertCompile(); assertEquals(3, count.get()); }
@Test public void testCallbackIssuedAfterEnterWithAPs() throws IOException { // We add an unrelated source file here to make the compiler do something compiler.addSourceFileContents("Bar.java", "class Bar { }"); compiler.setProcessors( ImmutableList.of( new AbstractProcessor() { @Override public Set<String> getSupportedAnnotationTypes() { return Collections.singleton("*"); } @Override public boolean process( Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { Filer filer = processingEnv.getFiler(); // We wait until the last possible momemt to generate Foo; if the callback is able to // get an element for it, that means it ran after the enter phase try (OutputStream outputStream = filer.createSourceFile("Foo").openOutputStream()) { outputStream.write("class Foo { }".getBytes()); } catch (IOException e) { throw new AssertionError(e); } } return false; } })); addCallback("callback"); compiler.compile(); assertThat(callbacksIssued, Matchers.contains("callback: Bar, Foo")); }
private List<Diagnostic<? extends JavaFileObject>> compileWithProcessors( Iterable<Class<?>> classes, ImmutableSet<? extends AbstractProcessor> processors) throws Exception { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<JavaFileObject>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager( diagnosticCollector, DEFAULT_LOCALE, DEFAULT_CHARSET ); Iterable<? extends JavaFileObject> sourceCompilationUnits = transformToCompilationUnits( classes, fileManager ); CompilationTask task = compiler.getTask(new OutputStreamWriter(System.out), fileManager, diagnosticCollector, Arrays.asList( "-proc:only", "-s", "./src/main/java" ), null, sourceCompilationUnits ); task.setProcessors(processors); task.call(); try { fileManager.close(); } catch (IOException ioe) { throw new RuntimeException(ioe); } return diagnosticCollector.getDiagnostics(); }
private AbstractProcessor createFieldNameProcessor(Iterable<Class<?>> classesToOutput) { SourceGenerator<EndpointTypeInfo, EndpointMethodInfo> classGenerator = new EndpointClassInfoSourceGenerator(); SourceFileWriter<EndpointTypeInfo> writer = new JavaxSourceFileWriter<>(); TypeParser<EndpointTypeInfo, EndpointMethodInfo> typeParser = new EndpointTypeParser( javadocParser); return new ControllerAnnotationProcessor( classGenerator, writer, typeParser, classesToOutput ); }
private JavaCompiler.CompilationTask processAnnotations(String[] testSourceFileNames, ElasticSearchDocumentAnnotationProcessor annotationProcessor) throws URISyntaxException { // Get an instance of java compiler JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // Get a new instance of the standard file manager implementation StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); // Get the list of java file objects, in this case we have only // one file, TestClass.java // http://stackoverflow.com/a/676102/693752 List<File> listSourceFiles = new ArrayList<>(); for (String sourceFileName : testSourceFileNames) { URL filename = ClassLoader.getSystemResource(sourceFileName); listSourceFiles.add(new File(filename.toURI())); } Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(listSourceFiles); // Create the compilation task List<String> options = new ArrayList<>(Arrays.asList("-d", sandBoxDir.getAbsolutePath())); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, compilationUnits1); if (annotationProcessor != null) { // Create a list to hold annotation processors LinkedList<AbstractProcessor> processors = new LinkedList<AbstractProcessor>(); // Add an annotation processor to the list processors.add(annotationProcessor); // Set the annotation processor to the compiler task task.setProcessors(processors); } return task; }
private JavaCompiler.CompilationTask processAnnotations(String[] testSourceFileNames, ElasticSearchTypeAnnotationProcessor annotationProcessor) throws URISyntaxException { // Get an instance of java compiler JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // Get a new instance of the standard file manager implementation StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); // Get the list of java file objects, in this case we have only // one file, TestClass.java // http://stackoverflow.com/a/676102/693752 List<File> listSourceFiles = new ArrayList<>(); for (String sourceFileName : testSourceFileNames) { URL filename = ClassLoader.getSystemResource(sourceFileName); listSourceFiles.add(new File(filename.toURI())); } Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(listSourceFiles); // Create the compilation task List<String> options = new ArrayList<>(Arrays.asList("-d", sandBoxDir.getAbsolutePath())); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, compilationUnits1); if (annotationProcessor != null) { // Create a list to hold annotation processors LinkedList<AbstractProcessor> processors = new LinkedList<AbstractProcessor>(); // Add an annotation processor to the list processors.add(annotationProcessor); // Set the annotation processor to the compiler task task.setProcessors(processors); } return task; }
@Test public void testWrappedInitCall() { AbstractProcessor processorSpy = Mockito.spy(AbstractProcessor.class); Messager messager = Mockito.spy(Messager.class); ProcessingEnvironment processingEnvironment = Mockito.spy(ProcessingEnvironment.class); Mockito.when(processingEnvironment.getMessager()).thenReturn(messager); Processor unit = AnnotationProcessorWrapper.wrapProcessor(processorSpy); unit.init(processingEnvironment); Mockito.verify(processorSpy).init(processingEnvironment); }
@Test public void testWrappedProcessCall() { AbstractProcessor processorSpy = Mockito.spy(AbstractProcessor.class); Messager messager = Mockito.spy(Messager.class); ProcessingEnvironment processingEnvironment = Mockito.spy(ProcessingEnvironment.class); Mockito.when(processingEnvironment.getMessager()).thenReturn(messager); Processor unit = AnnotationProcessorWrapper.wrapProcessor(processorSpy); unit.init(processingEnvironment); Set<? extends TypeElement> set = new HashSet<TypeElement>(); RoundEnvironment roundEnvironment = Mockito.mock(RoundEnvironment.class); unit.process(set, roundEnvironment); Mockito.verify(messager).printMessage(Diagnostic.Kind.NOTE, AbstractAnnotationProcessorTest.TEST_EXECUTION_MESSAGE); Mockito.verify(processorSpy).process(set, roundEnvironment); }
@Test public void testWrappedCompletionsCall() { AbstractProcessor processorSpy = Mockito.spy(AbstractProcessor.class); Element element = Mockito.mock(Element.class); AnnotationMirror annotationMirror = Mockito.mock(AnnotationMirror.class); ExecutableElement executableElement = Mockito.mock(ExecutableElement.class); String str = "XX"; Processor unit = AnnotationProcessorWrapper.wrapProcessor(processorSpy); unit.getCompletions(element, annotationMirror, executableElement, str); Mockito.verify(processorSpy).getCompletions(element, annotationMirror, executableElement, str); }
public DataClassBuilderHandler(AbstractProcessor processor, ProcessingEnvironment processingEnvironment) { super(processor, processingEnvironment, DataClassBuilder.class, ElementKind.INTERFACE, ElementKind.CLASS); }
public BaseAnnotationHandler(AbstractProcessor processor, ProcessingEnvironment processingEnvironment, Class<T> handledAnnotation, ElementKind... handledKinds) { this.processor = processor; this.env = processingEnvironment; this.handledAnnotation = handledAnnotation; this.handledKinds = handledKinds; }
@Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { final AtomicReference<Throwable> thrown = new AtomicReference<Throwable>(); boolean successful = compile(ImmutableList.of(new AbstractProcessor() { @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } @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 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; } })); checkState(successful); Throwable t = thrown.get(); if (t != null) { throw t; } } }; }
public ParameterizedCheckerTest(File testFile, Class<? extends AbstractProcessor> checker, String checkerDir, String... checkerOptions) { super(checker, checkerDir, checkerOptions); this.testFile = testFile; }
private void runTest(TestRunnable r) throws Exception { testCompiler.addSourceFile(getSourceFile("Foo.java")); if (testMode == WITH_DEPS) { testCompiler.addClasspathSourceFile(getSourceFile("Dependency.java")); testCompiler.addClasspathSourceFile(getSourceFile("DependencyException.java")); testCompiler.addClasspathSourceFile(getSourceFile("DependencyInterface.java")); } else { testCompiler.useFrontendOnlyJavacTask(); } testCompiler.setProcessors( Collections.singletonList( new AbstractProcessor() { @Override public Set<String> getSupportedOptions() { return Collections.emptySet(); } @Override public Set<String> getSupportedAnnotationTypes() { return Collections.singleton("*"); } @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.RELEASE_8; } @Override public boolean process( Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { try { r.run(); } catch (Exception e) { throw new AssertionError(e); } } return false; } })); elements = testCompiler.getElements(); testCompiler.enter(); }
@Test public void testAnnotationProcessorGetsNewElementsEachRound() throws Exception { final AtomicBoolean processorRan = new AtomicBoolean(false); initCompiler(ImmutableMap.of("Foo.java", "public class Foo { }")); testCompiler.setProcessors( ImmutableList.of( new AbstractProcessor() { private Elements elementsFromEnvironment; private TypeElement element; @Override public Set<String> getSupportedAnnotationTypes() { return Collections.singleton("*"); } @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); elementsFromEnvironment = processingEnv.getElementUtils(); } @Override public boolean process( Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { TypeElement newElement = elementsFromEnvironment.getTypeElement("Foo"); assertNotNull(newElement); assertNotSame(newElement, element); element = newElement; processorRan.set(roundEnv.processingOver()); return false; } })); testCompiler.compile(); assertTrue(processorRan.get()); }
@Test(expected = IllegalArgumentException.class) public void createWrapperWithNullValuedInstance() { Processor unit = AnnotationProcessorWrapper.wrapProcessor((AbstractProcessor) null); }
@Test public void testWrappedSupportedOptionsCall() { AbstractProcessor processorSpy = Mockito.spy(AbstractProcessor.class); Processor unit = AnnotationProcessorWrapper.wrapProcessor(processorSpy); unit.getSupportedOptions(); Mockito.verify(processorSpy).getSupportedOptions(); }
@Test public void testWrappedSupportedAnnotationTypesCall() { AbstractProcessor processorSpy = Mockito.spy(AbstractProcessor.class); Processor unit = AnnotationProcessorWrapper.wrapProcessor(processorSpy); unit.getSupportedAnnotationTypes(); Mockito.verify(processorSpy).getSupportedAnnotationTypes(); }
@Test public void testWrappedSupportedSourceVersionCall() { AbstractProcessor processorSpy = Mockito.spy(AbstractProcessor.class); Processor unit = AnnotationProcessorWrapper.wrapProcessor(processorSpy); unit.getSupportedSourceVersion(); Mockito.verify(processorSpy).getSupportedSourceVersion(); }
/** * Creates a new checker test. * * @param checker the class for the checker to use * @param checkerDir the path to the directory of test inputs * @param checkerOptions options to pass to the compiler when running tests */ public CheckerTest(Class<? extends AbstractProcessor> checker, String checkerDir, String... checkerOptions) { this.checkerName = checker.getName(); this.checkerDir = "tests" + File.separator + checkerDir; this.checkerOptions = Arrays.asList(checkerOptions); }