diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/Constants.java b/core/processor/src/main/java/io/quarkus/annotation/processor/Constants.java index 023756d3ad612..f795a7f5e1929 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/Constants.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/Constants.java @@ -49,6 +49,7 @@ final public class Constants { public static final String ANNOTATION_TEMPLATE = "io.quarkus.runtime.annotations.Template"; public static final String ANNOTATION_RECORDER = "io.quarkus.runtime.annotations.Recorder"; + public static final String ANNOTATION_RECORD = "io.quarkus.deployment.annotations.Record"; public static final String MEMORY_SIZE_TYPE = "io.quarkus.runtime.configuration.MemorySize"; public static final String ANNOTATION_CONFIG_ITEM = "io.quarkus.runtime.annotations.ConfigItem"; diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java b/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java index cc7c803eed793..605b043ad2000 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java @@ -38,6 +38,7 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.PackageElement; @@ -304,6 +305,7 @@ private void processBuildStep(RoundEnvironment roundEnv, TypeElement annotation) final String binaryName = processingEnv.getElementUtils().getBinaryName(clazz).toString(); if (processorClassNames.add(binaryName)) { + validateRecordBuildSteps(clazz); recordConfigJavadoc(clazz); generateAccessor(clazz); final StringBuilder rbn = getRelativeBinaryName(clazz, new StringBuilder()); @@ -322,6 +324,42 @@ private void processBuildStep(RoundEnvironment roundEnv, TypeElement annotation) } } + private void validateRecordBuildSteps(TypeElement clazz) { + for (Element e : clazz.getEnclosedElements()) { + if (e.getKind() != ElementKind.METHOD) { + continue; + } + ExecutableElement ex = (ExecutableElement) e; + if (!isAnnotationPresent(ex, Constants.ANNOTATION_BUILD_STEP)) { + continue; + } + if (!isAnnotationPresent(ex, Constants.ANNOTATION_RECORD)) { + continue; + } + + boolean hasRecorder = false; + boolean allTypesResolvable = true; + for (VariableElement parameter : ex.getParameters()) { + String parameterClassName = parameter.asType().toString(); + TypeElement parameterTypeElement = processingEnv.getElementUtils().getTypeElement(parameterClassName); + if (parameterTypeElement == null) { + allTypesResolvable = false; + } else { + if (isAnnotationPresent(parameterTypeElement, Constants.ANNOTATION_RECORDER)) { + hasRecorder = true; + break; + } + } + } + + if (!hasRecorder && allTypesResolvable) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Build Step '" + clazz.getQualifiedName() + "#" + + ex.getSimpleName() + + "' which is annotated with '@Record' does not contain a method parameter whose type is annotated with '@Recorder'."); + } + } + } + private StringBuilder getRelativeBinaryName(TypeElement te, StringBuilder b) { final Element enclosing = te.getEnclosingElement(); if (enclosing instanceof TypeElement) {