/*
 * Copyright 2017-2020 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.inject.visitor;

import edu.umd.cs.findbugs.annotations.NonNull;
import io.micronaut.core.annotation.Experimental;
import io.micronaut.core.order.Ordered;
import io.micronaut.core.reflect.GenericTypeUtils;
import io.micronaut.core.util.CollectionUtils;
import io.micronaut.inject.ast.ClassElement;
import io.micronaut.inject.ast.ConstructorElement;
import io.micronaut.inject.ast.FieldElement;
import io.micronaut.inject.ast.MethodElement;

import java.util.Collections;
import java.util.Set;

Provides a hook into the compilation process to allow user defined functionality to be created at compile time.
Author:James Kleeh
Type parameters:
  • <C> – The annotation required on the class. Use Object for all classes.
  • <E> – The annotation required on the element. Use Object for all elements.
Since:1.0
/** * Provides a hook into the compilation process to allow user defined functionality to be created at compile time. * * @param <C> The annotation required on the class. Use {@link Object} for all classes. * @param <E> The annotation required on the element. Use {@link Object} for all elements. * @author James Kleeh * @since 1.0 */
public interface TypeElementVisitor<C, E> extends Ordered {
Executed when a class is encountered that matches the generic.
Params:
  • element – The element
  • context – The visitor context
/** * Executed when a class is encountered that matches the <C> generic. * * @param element The element * @param context The visitor context */
default void visitClass(ClassElement element, VisitorContext context) { // no-op }
Executed when a method is encountered that matches the generic.
Params:
  • element – The element
  • context – The visitor context
/** * Executed when a method is encountered that matches the <E> generic. * * @param element The element * @param context The visitor context */
default void visitMethod(MethodElement element, VisitorContext context) { // no-op }
Executed when a constructor is encountered that matches the generic.
Params:
  • element – The element
  • context – The visitor context
/** * Executed when a constructor is encountered that matches the <C> generic. * * @param element The element * @param context The visitor context */
default void visitConstructor(ConstructorElement element, VisitorContext context) { // no-op }
Executed when a field is encountered that matches the generic.
Params:
  • element – The element
  • context – The visitor context
/** * Executed when a field is encountered that matches the <E> generic. * * @param element The element * @param context The visitor context */
default void visitField(FieldElement element, VisitorContext context) { // no-op }
Called once when visitor processing starts.
Params:
  • visitorContext – The visitor context
/** * Called once when visitor processing starts. * * @param visitorContext The visitor context */
default void start(VisitorContext visitorContext) { // no-op }
Called once when visitor processing finishes.
Params:
  • visitorContext – The visitor context
/** * Called once when visitor processing finishes. * * @param visitorContext The visitor context */
default void finish(VisitorContext visitorContext) { // no-op }
Returns:The supported default annotation names.
/** * @return The supported default annotation names. */
default Set<String> getSupportedAnnotationNames() { Class<?>[] classes = GenericTypeUtils.resolveInterfaceTypeArguments(getClass(), TypeElementVisitor.class); if (classes.length == 2) { Class<?> classType = classes[0]; if (classType == Object.class) { return Collections.singleton("*"); } else { Class<?> methodType = classes[1]; if (methodType != Object.class) { return CollectionUtils.setOf(classType.getName(), methodType.getName()); } else { return CollectionUtils.setOf(classType.getName()); } } } return Collections.singleton("*"); }
Called once when processor loads. Used to expose visitors custom processor options.
Returns:Set with custom options
/** * Called once when processor loads. * * Used to expose visitors custom processor options. * * @return Set with custom options */
@Experimental default Set<String> getSupportedOptions() { return Collections.emptySet(); }
Returns:The visitor kind.
/** * @return The visitor kind. */
default @NonNull VisitorKind getVisitorKind() { return VisitorKind.AGGREGATING; }
Implementors of the TypeElementVisitor interface should specify what kind of visitor it is. If the visitor looks at multiple Element and builds a file that references multiple Element (meaning it doesn't have an originating element) then AGGREGATING should be used If the visitor generates classes from an originating Element then ISOLATING should be used.
/** * Implementors of the {@link TypeElementVisitor} interface should specify what kind of visitor it is. * * If the visitor looks at multiple {@link io.micronaut.inject.ast.Element} and builds a file that references * multiple {@link io.micronaut.inject.ast.Element} (meaning it doesn't have an originating element) then * {@link VisitorKind#AGGREGATING} should be used * * If the visitor generates classes from an originating {@link io.micronaut.inject.ast.Element} then {@link VisitorKind#ISOLATING} should be used. */
enum VisitorKind {
A visitor that generates a file for each visited element and calls.
/** * A visitor that generates a file for each visited element and calls. */
ISOLATING,
A visitor that generates a one or more files in the TypeElementVisitor.finish(VisitorContext) method computed from visiting multiple Element instances.
/** * A visitor that generates a one or more files in the {@link #finish(VisitorContext)} method computed from visiting multiple {@link io.micronaut.inject.ast.Element} instances. */
AGGREGATING } }