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 a5baebfb8d53e..ef5ac7345a216 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 @@ -1,5 +1,6 @@ package io.quarkus.annotation.processor; +import static io.quarkus.annotation.processor.Constants.ANNOTATION_CONFIG_GROUP; import static io.quarkus.annotation.processor.Constants.ANNOTATION_CONFIG_MAPPING; import static javax.lang.model.util.ElementFilter.constructorsIn; import static javax.lang.model.util.ElementFilter.fieldsIn; @@ -27,6 +28,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.TreeSet; @@ -545,11 +547,55 @@ private void processMethodConfigItem(ExecutableElement method, Properties javado private void processMethodConfigMapping(ExecutableElement method, Properties javadocProps, String className) { if (method.getModifiers().contains(Modifier.ABSTRACT)) { - final String docComment = getRequiredJavadoc(method); + // Skip toString method, because mappings can include it and generate it + if (method.getSimpleName().contentEquals("toString") && method.getParameters().size() == 0) { + return; + } + + String docComment = getRequiredJavadoc(method); javadocProps.put(className + Constants.DOT + method.getSimpleName().toString(), docComment); + + // Find groups without annotation + TypeMirror returnType = method.getReturnType(); + if (TypeKind.DECLARED.equals(returnType.getKind())) { + DeclaredType declaredType = (DeclaredType) returnType; + if (!isAnnotationPresent(declaredType.asElement(), ANNOTATION_CONFIG_GROUP)) { + TypeElement type = unwrapConfigGroup(returnType); + if (type != null && ElementKind.INTERFACE.equals(type.getKind())) { + recordMappingJavadoc(type); + configDocItemScanner.addConfigGroups(type); + } + } + } } } + private TypeElement unwrapConfigGroup(TypeMirror typeMirror) { + if (typeMirror == null) { + return null; + } + + DeclaredType declaredType = (DeclaredType) typeMirror; + String name = declaredType.asElement().toString(); + List typeArguments = declaredType.getTypeArguments(); + if (typeArguments.size() == 0) { + if (!name.startsWith("java.")) { + return (TypeElement) declaredType.asElement(); + } + } else if (typeArguments.size() == 1) { + if (name.equals(Optional.class.getName()) || + name.equals(List.class.getName()) || + name.equals(Set.class.getName())) { + return unwrapConfigGroup(typeArguments.get(0)); + } + } else if (typeArguments.size() == 2) { + if (name.equals(Map.class.getName())) { + return unwrapConfigGroup(typeArguments.get(1)); + } + } + return null; + } + private void processConfigGroup(RoundEnvironment roundEnv, TypeElement annotation) { final Set groupClassNames = new HashSet<>(); for (TypeElement i : typesIn(roundEnv.getElementsAnnotatedWith(annotation))) { diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemFinder.java b/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemFinder.java index 7cf05a5099026..39b569f7943a2 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemFinder.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemFinder.java @@ -271,7 +271,7 @@ private List recursivelyFindConfigItems(Element element, String r if (!typeArguments.isEmpty()) { // FIXME: this is super dodgy: we should check the type!! if (typeArguments.size() == 2) { - type = typeArguments.get(1).toString(); + type = getType(typeArguments.get(1)); if (isConfigGroup(type)) { name += String.format(NAMED_MAP_CONFIG_ITEM_FORMAT, configDocMapKey); List groupConfigItems = readConfigGroupItems(configPhase, rootName, name, type, @@ -354,8 +354,6 @@ private List recursivelyFindConfigItems(Element element, String r } } - final String configDescription = javaDocParser.parseConfigDescription(rawJavaDoc); - configDocKey.setKey(name); configDocKey.setType(type); configDocKey.setList(list); @@ -365,7 +363,7 @@ private List recursivelyFindConfigItems(Element element, String r configDocKey.setConfigPhase(configPhase); configDocKey.setDefaultValue(defaultValue); configDocKey.setDocMapKey(configDocMapKey); - configDocKey.setConfigDoc(configDescription); + configDocKey.setConfigDoc(javaDocParser.parseConfigDescription(rawJavaDoc)); configDocKey.setAcceptedValues(acceptedValues); configDocKey.setJavaDocSiteLink(getJavaDocSiteLink(type)); ConfigDocItem configDocItem = new ConfigDocItem(); @@ -413,6 +411,11 @@ private boolean shouldProcessElement(final Element enclosedElement) { // A ConfigMapping method if (enclosedElement.getKind().equals(ElementKind.METHOD)) { + ExecutableElement method = (ExecutableElement) enclosedElement; + // Skip toString method, because mappings can include it and generate it + if (method.getSimpleName().contentEquals("toString") && method.getParameters().size() == 0) { + return false; + } Element enclosingElement = enclosedElement.getEnclosingElement(); return enclosingElement.getModifiers().contains(ABSTRACT) && enclosedElement.getModifiers().contains(ABSTRACT); } @@ -438,7 +441,7 @@ private String simpleTypeToString(TypeMirror typeMirror) { return simpleTypeToString(typeArguments.get(0)); } - return typeMirror.toString(); + return getType(typeMirror); } private List extractEnumValues(TypeMirror realTypeMirror, boolean useHyphenatedEnumValue, String javaDocKey) {