use of javax.annotation.processing.RoundEnvironment in project javapoet by square.
the class AbstractTypesTest method errorTypes.
@Test
public void errorTypes() {
JavaFileObject hasErrorTypes = JavaFileObjects.forSourceLines("com.squareup.tacos.ErrorTypes", "package com.squareup.tacos;", "", "@SuppressWarnings(\"hook-into-compiler\")", "class ErrorTypes {", " Tacos tacos;", " Ingredients.Guacamole guacamole;", "}");
Compilation compilation = javac().withProcessors(new AbstractProcessor() {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
TypeElement classFile = processingEnv.getElementUtils().getTypeElement("com.squareup.tacos.ErrorTypes");
List<VariableElement> fields = fieldsIn(classFile.getEnclosedElements());
ErrorType topLevel = (ErrorType) fields.get(0).asType();
ErrorType member = (ErrorType) fields.get(1).asType();
assertThat(TypeName.get(topLevel)).isEqualTo(ClassName.get("", "Tacos"));
assertThat(TypeName.get(member)).isEqualTo(ClassName.get("Ingredients", "Guacamole"));
return false;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return Collections.singleton("*");
}
}).compile(hasErrorTypes);
assertThat(compilation).failed();
}
use of javax.annotation.processing.RoundEnvironment in project Nucleus by NucleusPowered.
the class StoreProcessor method process.
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Map<Element, String> classes = new HashMap<>();
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Store.class);
for (Element element : elements) {
// Only storing classes.
if (element.getKind().isClass()) {
Store s = element.getAnnotation(Store.class);
classes.put(element, s.isRoot() ? null : s.value());
}
}
// Get the root elements
ClassElementVisitor cev = new ClassElementVisitor();
Map<String, String> conv = classes.entrySet().stream().filter(x -> x.getValue() == null).map(x -> cev.visit(x.getKey(), true)).filter(Objects::nonNull).collect(Collectors.toMap(x -> x.pa, x -> x.cl));
final Map<String, Map<String, List<String>>> result = conv.values().stream().collect(Collectors.toMap(x -> x, x -> new HashMap<>()));
classes.entrySet().stream().filter(x -> x.getValue() != null).map(x -> {
StringTuple st = cev.visit(x.getKey(), false);
if (st != null) {
return new StringTuple(x.getValue(), st.cl);
}
return null;
}).filter(Objects::nonNull).forEach(x -> {
// Check the class vs package name
conv.entrySet().stream().filter(y -> x.cl.startsWith(y.getKey())).distinct().findFirst().ifPresent(y -> result.get(y.getValue()).computeIfAbsent(x.pa, z -> new ArrayList<>()).add(x.cl));
});
if (!classes.isEmpty()) {
// Write this file
try {
FileObject fo = this.processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "assets.nucleus", "classes.json");
try (Writer os = fo.openWriter()) {
os.write(new GsonBuilder().setPrettyPrinting().create().toJson(result));
os.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
use of javax.annotation.processing.RoundEnvironment in project requery by requery.
the class EntityProcessor method process.
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
// types to generate in this round
Map<TypeElement, EntityElement> entities = new HashMap<>();
Types types = processingEnv.getTypeUtils();
Set<TypeElement> annotationElements = new LinkedHashSet<>(annotations);
for (TypeElement annotation : annotationElements) {
for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
typeElementOf(element).ifPresent(typeElement -> {
EntityElement entity = null;
if (isEntity(typeElement)) {
// create or get the entity for the annotation
entity = computeType(entities, typeElement);
// create or get the graph for it
String model = entity.modelName();
graphs.computeIfAbsent(model, key -> new EntityGraph(types, embeddedTypes)).add(entity);
} else if (isSuperclass(typeElement)) {
entity = computeType(superTypes, typeElement);
} else if (isEmbeddable(typeElement)) {
entity = computeType(embeddedTypes, typeElement);
}
if (entity != null) {
entity.addAnnotationElement(annotation, element);
}
});
}
}
// process
boolean hasErrors = false;
Set<ElementValidator> validators = new LinkedHashSet<>();
Elements elements = processingEnv.getElementUtils();
for (EntityElement entity : entities.values()) {
// add the annotated elements from the super type (if any)
if (entity.element().getKind() == ElementKind.INTERFACE) {
Queue<TypeMirror> interfaces = new LinkedList<>(entity.element().getInterfaces());
while (!interfaces.isEmpty()) {
TypeMirror mirror = interfaces.remove();
TypeElement superElement = elements.getTypeElement(mirror.toString());
if (superElement != null) {
mergeSuperType(entity, superElement);
interfaces.addAll(superElement.getInterfaces());
}
}
}
TypeMirror typeMirror = entity.element().getSuperclass();
while (typeMirror.getKind() != TypeKind.NONE) {
TypeElement superElement = elements.getTypeElement(typeMirror.toString());
if (superElement != null) {
mergeSuperType(entity, superElement);
typeMirror = superElement.getSuperclass();
} else {
break;
}
}
// process the entity
Set<ElementValidator> results = entity.process(processingEnv);
validators.addAll(results);
}
for (EntityElement entity : embeddedTypes.values()) {
Set<ElementValidator> results = entity.process(processingEnv);
validators.addAll(results);
}
for (EntityGraph graph : graphs.values()) {
EntityGraphValidator validator = new EntityGraphValidator(processingEnv, graph);
Set<ElementValidator> results = validator.validate();
validators.addAll(results);
}
if (ElementValidator.hasErrors(validators)) {
hasErrors = true;
StringBuilder sb = new StringBuilder("Model has error(s) code generation may fail: ");
validators.forEach(validator -> sb.append(validator.toString()));
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, sb);
}
// generate
Set<SourceGenerator> generators = new LinkedHashSet<>();
if (!hasErrors || getOption(GENERATE_ALWAYS, true)) {
for (EntityDescriptor entity : entities.values()) {
EntityGraph graph = graphs.get(entity.modelName());
if (graph != null) {
generators.add(new EntityGenerator(processingEnv, graph, entity, null));
}
}
}
if (getOption(GENERATE_MODEL, true)) {
Map<String, Collection<EntityDescriptor>> packagesMap = new LinkedHashMap<>();
Set<EntityDescriptor> allEntities = graphs.values().stream().flatMap(graph -> graph.entities().stream()).collect(Collectors.toSet());
for (EntityDescriptor entity : allEntities) {
EntityGraph graph = graphs.get(entity.modelName());
String packageName = findModelPackageName(graph);
packagesMap.computeIfAbsent(packageName, key -> new LinkedHashSet<>());
packagesMap.get(packageName).addAll(graph.entities());
}
for (EntityDescriptor entity : entities.values()) {
EntityGraph graph = graphs.get(entity.modelName());
String packageName = findModelPackageName(graph);
if (entity.generatesAdditionalTypes()) {
packagesMap.remove(packageName);
}
}
generators.addAll(packagesMap.entrySet().stream().filter(entry -> !entry.getValue().isEmpty()).filter(entry -> !generatedModelPackages.contains(entry.getKey())).peek(entry -> generatedModelPackages.add(entry.getKey())).map(entry -> new ModelGenerator(processingEnv, entry.getKey(), entry.getValue())).collect(Collectors.toList()));
}
for (SourceGenerator generator : generators) {
try {
generator.generate();
} catch (IOException e) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage());
}
}
return false;
}
use of javax.annotation.processing.RoundEnvironment in project vertx-docgen by vert-x3.
the class BaseProcessor method process.
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (StackTraceElement elt : trace) {
if (elt.getClassName().startsWith("org.jetbrains")) {
return true;
}
}
if (failures.isEmpty()) {
try {
if (!roundEnv.processingOver()) {
roundEnv.getElementsAnnotatedWith(Document.class).forEach(elt -> {
try {
PackageDoc doc = new PackageDoc((PackageElement) elt);
state.put(doc, handleGen(doc));
} catch (DocGenException e) {
if (e.element == null) {
e.element = elt;
}
throw e;
}
});
if (sources != null && sources.size() > 0) {
for (String source : sources) {
// Handle wildcards
List<File> files = new ArrayList<>();
File f = new File(source);
if (!f.exists()) {
if (f.getName().contains("*")) {
StringBuilder sb = new StringBuilder();
for (char c : f.getName().toCharArray()) {
if (c == '*') {
sb.append(".*");
} else {
sb.append(Matcher.quoteReplacement(Character.toString(c)));
}
}
Pattern p = Pattern.compile(sb.toString());
File parentFile = f.getParentFile();
File[] children = parentFile.listFiles();
if (children != null) {
for (File child : children) {
if (p.matcher(child.getName()).matches()) {
files.add(child);
}
}
}
} else {
throw new FileNotFoundException("Cannot process document " + source);
}
} else {
files.add(f);
}
for (File file : files) {
if (file.isFile()) {
FileDoc fileDoc = new FileDoc(file, file.getName());
Map<DocGenerator, DocWriter> m = handleGen(fileDoc);
state.put(fileDoc, m);
} else if (file.isDirectory()) {
Files.walk(file.toPath()).map(Path::toFile).filter(File::isFile).forEach(docFile -> {
String relativePath = file.toPath().relativize(docFile.toPath()).toString();
FileDoc fileDoc = new FileDoc(docFile, relativePath);
Map<DocGenerator, DocWriter> m = handleGen(fileDoc);
state.put(fileDoc, m);
});
} else {
throw new IOException("Document " + file.getAbsolutePath() + " is not a file nor a dir");
}
}
}
sources.clear();
}
Set<String> processed = new HashSet<>();
while (true) {
Optional<ElementResolution> opt = resolutions.values().stream().filter(res -> res.elt == null && !processed.contains(res.signature)).findFirst();
if (opt.isPresent()) {
ElementResolution res = opt.get();
processed.add(res.signature);
res.tryResolve();
} else {
break;
}
}
} else {
state.forEach((doc, m) -> {
m.forEach((gen, w) -> {
String content = postProcess(gen.getName(), w.render());
write(gen, doc, content);
});
});
}
} catch (Exception e) {
Element reportedElt = (e instanceof DocGenException) ? ((DocGenException) e).element : null;
String msg = e.getMessage();
if (msg == null) {
msg = e.toString();
}
e.printStackTrace();
if (reportedElt != null) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, reportedElt);
if (reportedElt instanceof PackageElement) {
failures.put(((PackageElement) reportedElt).getQualifiedName().toString(), msg);
} else {
throw new UnsupportedOperationException("not implemented");
}
} else {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg);
}
}
}
return false;
}
use of javax.annotation.processing.RoundEnvironment in project auto by google.
the class AutoValueCompilationTest method testTypeParametersWithAnnotationsOnBounds.
// Tests that type annotations are correctly copied from the bounds of type parameters in the
// @AutoValue class to the bounds of the corresponding parameters in the generated class. For
// example, if we have `@AutoValue abstract class Foo<T extends @NullableType Object>`, then the
// generated class should be `class AutoValue_Foo<T extends @NullableType Object> extends Foo<T>`.
// Some buggy versions of javac do not report type annotations correctly in this context.
// AutoValue can't copy them if it can't see them, so we make a special annotation processor to
// detect if we are in the presence of this bug and if so we don't fail.
@Test
public void testTypeParametersWithAnnotationsOnBounds() {
@SupportedAnnotationTypes("*")
class CompilerBugProcessor extends AbstractProcessor {
boolean checkedAnnotationsOnTypeBounds;
boolean reportsAnnotationsOnTypeBounds;
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
TypeElement test = processingEnv.getElementUtils().getTypeElement("com.example.Test");
TypeParameterElement t = test.getTypeParameters().get(0);
this.checkedAnnotationsOnTypeBounds = true;
this.reportsAnnotationsOnTypeBounds = !t.getBounds().get(0).getAnnotationMirrors().isEmpty();
}
return false;
}
}
CompilerBugProcessor compilerBugProcessor = new CompilerBugProcessor();
JavaFileObject nullableTypeFileObject = JavaFileObjects.forSourceLines("foo.bar.NullableType", "package foo.bar;", "", "import java.lang.annotation.ElementType;", "import java.lang.annotation.Target;", "", "@Target(ElementType.TYPE_USE)", "public @interface NullableType {}");
JavaFileObject autoValueFileObject = JavaFileObjects.forSourceLines("com.example.Test", "package com.example;", "", "import com.google.auto.value.AutoValue;", "import foo.bar.NullableType;", "", "@AutoValue", "abstract class Test<T extends @NullableType Object & @NullableType Cloneable> {}");
Compilation compilation = javac().withProcessors(new AutoValueProcessor(), compilerBugProcessor).withOptions("-Xlint:-processing", "-implicit:none").compile(nullableTypeFileObject, autoValueFileObject);
assertThat(compilation).succeededWithoutWarnings();
assertThat(compilerBugProcessor.checkedAnnotationsOnTypeBounds).isTrue();
if (compilerBugProcessor.reportsAnnotationsOnTypeBounds) {
assertThat(compilation).generatedSourceFile("com.example.AutoValue_Test").contentsAsUtf8String().contains("class AutoValue_Test<T extends @NullableType Object & @NullableType Cloneable>" + " extends Test<T> {");
}
}
Aggregations