use of io.micronaut.inject.visitor.BeanElementVisitor in project micronaut-core by micronaut-projects.
the class BeanDefinitionInjectProcessor method process.
@Override
public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
processingOver = roundEnv.processingOver();
if (!processingOver) {
annotations = annotations.stream().filter(ann -> {
final String name = ann.getQualifiedName().toString();
String packageName = NameUtils.getPackageName(name);
return !name.equals(AnnotationUtil.KOTLIN_METADATA) && !AnnotationUtil.STEREOTYPE_EXCLUDES.contains(packageName);
}).filter(ann -> annotationUtils.hasStereotype(ann, ANNOTATION_STEREOTYPES) || isProcessedAnnotation(ann.getQualifiedName().toString())).collect(Collectors.toSet());
if (!annotations.isEmpty()) {
TypeElement groovyObjectTypeElement = elementUtils.getTypeElement("groovy.lang.GroovyObject");
TypeMirror groovyObjectType = groovyObjectTypeElement != null ? groovyObjectTypeElement.asType() : null;
// accumulate all the class elements for all annotated elements
annotations.forEach(annotation -> roundEnv.getElementsAnnotatedWith(annotation).stream().filter(element -> element.getKind() != ANNOTATION_TYPE).forEach(element -> {
TypeElement typeElement = modelUtils.classElementFor(element);
if (typeElement == null) {
return;
}
if (element.getKind() == ENUM) {
final AnnotationMetadata am = annotationUtils.getAnnotationMetadata(element);
if (isDeclaredBeanInMetadata(am)) {
error(element, "Enum types cannot be defined as beans");
}
return;
}
// skip Groovy code, handled by InjectTransform. Required for GroovyEclipse compiler
if ((groovyObjectType != null && typeUtils.isAssignable(typeElement.asType(), groovyObjectType))) {
return;
}
String name = typeElement.getQualifiedName().toString();
if (!beanDefinitions.contains(name) && !processed.contains(name) && !name.endsWith(BeanDefinitionVisitor.PROXY_SUFFIX)) {
boolean isInterface = JavaModelUtils.resolveKind(typeElement, ElementKind.INTERFACE).isPresent();
if (!isInterface) {
beanDefinitions.add(name);
} else {
if (annotationUtils.hasStereotype(typeElement, INTRODUCTION_TYPE) || annotationUtils.hasStereotype(typeElement, ConfigurationReader.class)) {
beanDefinitions.add(name);
}
}
}
}));
}
// remove already processed in previous round
for (String name : processed) {
beanDefinitions.remove(name);
}
// process remaining
int count = beanDefinitions.size();
if (count > 0) {
note("Creating bean classes for %s type elements", count);
beanDefinitions.forEach(className -> {
if (processed.add(className)) {
final TypeElement refreshedClassElement = elementUtils.getTypeElement(className);
try {
final AnnBeanElementVisitor visitor = new AnnBeanElementVisitor(refreshedClassElement);
refreshedClassElement.accept(visitor, className);
visitor.getBeanDefinitionWriters().forEach((name, writer) -> {
String beanDefinitionName = writer.getBeanDefinitionName();
if (processed.add(beanDefinitionName)) {
processBeanDefinitions(writer);
}
});
AnnotationUtils.invalidateMetadata(refreshedClassElement);
} catch (PostponeToNextRoundException e) {
processed.remove(className);
}
}
});
AnnotationUtils.invalidateCache();
}
}
/*
Since the underlying Filer expects us to write only once into a file we need to make sure it happens in the last
processing round.
*/
if (processingOver) {
try {
writeBeanDefinitionsToMetaInf();
for (BeanElementVisitor<?> visitor : BeanElementVisitor.VISITORS) {
if (visitor.isEnabled()) {
try {
visitor.finish(javaVisitorContext);
} catch (Exception e) {
javaVisitorContext.fail("Error finalizing bean element visitor [" + visitor.getClass().getName() + "]: " + e.getMessage(), null);
}
}
}
final List<AbstractBeanDefinitionBuilder> beanElementBuilders = javaVisitorContext.getBeanElementBuilders();
if (CollectionUtils.isNotEmpty(beanElementBuilders)) {
try {
AbstractBeanDefinitionBuilder.writeBeanDefinitionBuilders(classWriterOutputVisitor, beanElementBuilders);
} catch (IOException e) {
// raise a compile error
String message = e.getMessage();
error("Unexpected error: %s", message != null ? message : e.getClass().getSimpleName());
}
}
} finally {
AnnotationUtils.invalidateCache();
AbstractAnnotationMetadataBuilder.clearMutated();
JavaAnnotationMetadataBuilder.clearCaches();
}
}
return false;
}
Aggregations