All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.micronaut.annotation.processing.MixinVisitorProcessor Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2017-2025 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.micronaut.annotation.processing;

import io.micronaut.annotation.processing.visitor.JavaClassElement;
import io.micronaut.annotation.processing.visitor.JavaElementFactory;
import io.micronaut.annotation.processing.visitor.JavaNativeElement;
import io.micronaut.context.annotation.Mixin;
import io.micronaut.context.visitor.VisitorUtils;
import io.micronaut.core.annotation.AnnotationValue;
import io.micronaut.core.annotation.Generated;
import io.micronaut.inject.annotation.AbstractAnnotationMetadataBuilder;
import io.micronaut.inject.processing.ProcessingException;
import io.micronaut.inject.visitor.ElementPostponedToNextRoundException;
import io.micronaut.inject.visitor.VisitorContext;

import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 

The annotation processed used to process the mixins first.

* * @author Denis Stepanov * @since 4.9 */ @SupportedOptions({ AbstractInjectAnnotationProcessor.MICRONAUT_PROCESSING_INCREMENTAL, AbstractInjectAnnotationProcessor.MICRONAUT_PROCESSING_ANNOTATIONS, VisitorContext.MICRONAUT_PROCESSING_PROJECT_DIR, VisitorContext.MICRONAUT_PROCESSING_GROUP, VisitorContext.MICRONAUT_PROCESSING_MODULE }) public class MixinVisitorProcessor extends AbstractInjectAnnotationProcessor { @Override public Set getSupportedAnnotationTypes() { return Set.of(Mixin.class.getName()); } @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!(annotations.size() == 1 && Generated.class.getName().equals(annotations.iterator().next().getQualifiedName().toString()))) { for (Object nativeType : postponedTypes.values()) { AbstractAnnotationMetadataBuilder.clearMutated(nativeType); } var elements = new LinkedHashSet(); postponedTypes.keySet().stream().map(elementUtils::getTypeElement).filter(Objects::nonNull).forEach(elements::add); postponedTypes.clear(); JavaElementFactory elementFactory = javaVisitorContext.getElementFactory(); JavaElementAnnotationMetadataFactory elementAnnotationMetadataFactory = javaVisitorContext.getElementAnnotationMetadataFactory(); for (TypeElement annotation : annotations) { modelUtils.resolveTypeElements( roundEnv.getElementsAnnotatedWith(annotation) ).forEach(elements::add); } List javaClassElements = elements.stream() .map(typeElement -> elementFactory.newSourceClassElement(typeElement, elementAnnotationMetadataFactory)) .toList(); for (JavaClassElement mixin : javaClassElements) { try { AnnotationValue mixinAnnotation = mixin.getAnnotation(Mixin.class); if (mixinAnnotation == null) { continue; } String target = mixinAnnotation.stringValue("target").orElse(mixinAnnotation.stringValue().orElse(null)); if (target == null || Object.class.getName().equals(target)) { continue; } TypeElement targetTypeElement = elementUtils.getTypeElement(target); if (targetTypeElement == null) { continue; } JavaClassElement mixinTarget = elementFactory.newSourceClassElement(targetTypeElement, elementAnnotationMetadataFactory); VisitorUtils.applyMixin(mixinAnnotation, mixin, mixinTarget); } catch (ProcessingException e) { var originatingElement = (JavaNativeElement) e.getOriginatingElement(); if (originatingElement == null) { originatingElement = mixin.getNativeType(); } error(originatingElement.element(), e.getMessage()); } catch (PostponeToNextRoundException e) { postponedTypes.put(mixin.getCanonicalName(), e.getNativeErrorElement()); } catch (ElementPostponedToNextRoundException e) { Object nativeType = e.getOriginatingElement().getNativeType(); Element element = PostponeToNextRoundException.resolvedFailedElement(nativeType); if (element != null) { postponedTypes.put(mixin.getCanonicalName(), element); } else { // should never happen. throw e; } } } } if (roundEnv.processingOver()) { javaVisitorContext.finish(); } return false; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy