From 59bd3858ac730fe0d0691427e2b9082d4797dc25 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sat, 31 Aug 2024 15:35:30 +0200 Subject: [PATCH 1/2] Config Doc - Avoid annotations in primitive type name While this was already correctly handled for declared types, primitive types don't have an API to get the name without the annotations being present (toString() contains the annotations and there is no other way to get a string representation of the type...). Fixing it by making sure we get to the type name. This avoids having things like: @io.smallrye.config.WithConverter(io.quarkus.runtime.init.InitRuntimeConfig.BooleanConverter.class) boolean in the doc. Or Bean Validation constraints when they are used. --- .../config/discovery/ResolvedType.java | 6 ++-- .../config/resolver/ConfigResolver.java | 4 +-- .../scanner/ConfigAnnotationScanner.java | 7 +++-- .../config/scanner/ConfigMappingListener.java | 2 +- .../scanner/LegacyConfigRootListener.java | 2 +- .../processor/util/ElementUtil.java | 28 +++++++++++++++++++ 6 files changed, 38 insertions(+), 11 deletions(-) diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/discovery/ResolvedType.java b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/discovery/ResolvedType.java index f10b93b94fa68..01d845e500a40 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/discovery/ResolvedType.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/discovery/ResolvedType.java @@ -34,10 +34,8 @@ public final String toString() { return unwrappedType.toString(); } - public static ResolvedType ofPrimitive(TypeMirror unwrappedType) { - String primitiveName = unwrappedType.toString(); - - return new ResolvedType(unwrappedType, unwrappedType, primitiveName, primitiveName, primitiveName, true, false, false, + public static ResolvedType ofPrimitive(TypeMirror unwrappedType, String typeName) { + return new ResolvedType(unwrappedType, unwrappedType, typeName, typeName, typeName, true, false, false, false, false, false, false, false, false, false); } diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/resolver/ConfigResolver.java b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/resolver/ConfigResolver.java index d02e20f324b80..d6fa963d6dd12 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/resolver/ConfigResolver.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/resolver/ConfigResolver.java @@ -183,7 +183,7 @@ private void resolveProperty(ConfigRoot configRoot, Map e if (discoveryConfigProperty.getType().isMap()) { // it is a leaf pass through map, it is always optional optional = true; - typeQualifiedName = discoveryConfigProperty.getType().wrapperType().toString(); + typeQualifiedName = utils.element().getQualifiedName(discoveryConfigProperty.getType().wrapperType()); typeSimplifiedName = utils.element().simplifyGenericType(discoveryConfigProperty.getType().wrapperType()); potentiallyMappedPath += ConfigNamingUtil.getMapKey(discoveryConfigProperty.getMapKey()); @@ -191,7 +191,7 @@ private void resolveProperty(ConfigRoot configRoot, Map e .map(p -> p + ConfigNamingUtil.getMapKey(discoveryConfigProperty.getMapKey())) .collect(Collectors.toCollection(ArrayList::new)); } else if (discoveryConfigProperty.getType().isList()) { - typeQualifiedName = discoveryConfigProperty.getType().wrapperType().toString(); + typeQualifiedName = utils.element().getQualifiedName(discoveryConfigProperty.getType().wrapperType()); } PropertyPath propertyPath = new PropertyPath(potentiallyMappedPath, diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigAnnotationScanner.java b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigAnnotationScanner.java index 5ae2110b70d55..0ee2a08b30455 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigAnnotationScanner.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigAnnotationScanner.java @@ -197,7 +197,8 @@ private void scanElement(List listeners, DiscoveryRoot } } else { TypeMirror superclass = clazz.getSuperclass(); - if (superclass.getKind() != TypeKind.NONE && !superclass.toString().equals(Object.class.getName())) { + if (superclass.getKind() != TypeKind.NONE + && !utils.element().getQualifiedName(superclass).equals(Object.class.getName())) { TypeElement superclassTypeElement = (TypeElement) ((DeclaredType) superclass).asElement(); debug("Detected superclass: " + superclassTypeElement, clazz); @@ -324,7 +325,7 @@ private boolean isEnumAlreadyHandled(TypeElement clazz) { private ResolvedType resolveType(TypeMirror typeMirror) { if (typeMirror.getKind().isPrimitive()) { - return ResolvedType.ofPrimitive(typeMirror); + return ResolvedType.ofPrimitive(typeMirror, utils.element().getQualifiedName(typeMirror)); } if (typeMirror.getKind() == TypeKind.ARRAY) { ResolvedType resolvedType = resolveType(((ArrayType) typeMirror).getComponentType()); @@ -369,7 +370,7 @@ private ResolvedType resolveType(TypeMirror typeMirror) { isConfigGroup = utils.element().isAnnotationPresent(typeElement, Types.ANNOTATION_CONFIG_GROUP); } else if (typeElement.getKind() == ElementKind.CLASS) { isClass = true; - isDuration = typeMirror.toString().equals(Duration.class.getName()); + isDuration = utils.element().getQualifiedName(typeMirror).equals(Duration.class.getName()); isConfigGroup = utils.element().isAnnotationPresent(typeElement, Types.ANNOTATION_CONFIG_GROUP); } diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigMappingListener.java b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigMappingListener.java index d6f790f7ecce3..1847c8e203503 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigMappingListener.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigMappingListener.java @@ -43,7 +43,7 @@ public Optional onConfigRoot(TypeElement configRoot) { AnnotationMirror configDocFileNameAnnotation = null; for (AnnotationMirror annotationMirror : configRoot.getAnnotationMirrors()) { - String annotationName = annotationMirror.getAnnotationType().toString(); + String annotationName = utils.element().getQualifiedName(annotationMirror.getAnnotationType()); if (annotationName.equals(Types.ANNOTATION_CONFIG_ROOT)) { configRootAnnotation = annotationMirror; diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/LegacyConfigRootListener.java b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/LegacyConfigRootListener.java index 301129548fd90..6a1ca922d3da3 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/LegacyConfigRootListener.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/LegacyConfigRootListener.java @@ -44,7 +44,7 @@ public Optional onConfigRoot(TypeElement configRoot) { AnnotationMirror configDocFileNameAnnotation = null; for (AnnotationMirror annotationMirror : configRoot.getAnnotationMirrors()) { - String annotationName = annotationMirror.getAnnotationType().toString(); + String annotationName = utils.element().getQualifiedName(annotationMirror.getAnnotationType()); if (annotationName.equals(Types.ANNOTATION_CONFIG_ROOT)) { configRootAnnotation = annotationMirror; diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/util/ElementUtil.java b/core/processor/src/main/java/io/quarkus/annotation/processor/util/ElementUtil.java index a62011274c905..eaf41d1ec52a5 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/util/ElementUtil.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/util/ElementUtil.java @@ -29,6 +29,34 @@ public class ElementUtil { this.processingEnv = processingEnv; } + public String getQualifiedName(TypeMirror type) { + switch (type.getKind()) { + case BOOLEAN: + return "boolean"; + case BYTE: + return "byte"; + case CHAR: + return "char"; + case DOUBLE: + return "double"; + case FLOAT: + return "float"; + case INT: + return "int"; + case LONG: + return "long"; + case SHORT: + return "short"; + case DECLARED: + return ((TypeElement) ((DeclaredType) type).asElement()).getQualifiedName().toString(); + default: + // note that it includes annotations, which is something we don't want + // thus why all this additional work above... + // this default should never be triggered AFAIK, it's there to be extra safe + return type.toString(); + } + } + public String getBinaryName(TypeElement clazz) { return processingEnv.getElementUtils().getBinaryName(clazz).toString(); } From 01ea052235e9a6f36b762e11916d506bdddfd3a5 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sat, 31 Aug 2024 18:03:20 +0200 Subject: [PATCH 2/2] Config Doc - Fix base URL of JDK classes Apparently it has changed to include the module name so let's update it. --- .../processor/documentation/config/util/JavadocUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/util/JavadocUtil.java b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/util/JavadocUtil.java index 0e4115d278b86..8ca9e307b0ca0 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/util/JavadocUtil.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/util/JavadocUtil.java @@ -9,7 +9,7 @@ public final class JavadocUtil { static final String VERTX_JAVA_DOC_SITE = "https://vertx.io/docs/apidocs/"; - static final String OFFICIAL_JAVA_DOC_BASE_LINK = "https://docs.oracle.com/en/java/javase/17/docs/api/"; + static final String OFFICIAL_JAVA_DOC_BASE_LINK = "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/"; static final String AGROAL_API_JAVA_DOC_SITE = "https://javadoc.io/doc/io.agroal/agroal-api/latest/"; static final String LOG_LEVEL_REDIRECT_URL = "https://javadoc.io/doc/org.jboss.logmanager/jboss-logmanager/latest/org/jboss/logmanager/Level.html";