From 6b77a46aaf61cf957e1b62f94051b0ea19e7b863 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Wed, 24 Jan 2024 14:08:44 +0100 Subject: [PATCH 1/3] add Type.create(Class) --- core/src/main/java/org/jboss/jandex/Type.java | 50 +++++++++++++++++++ .../jboss/jandex/test/TypeFromClassTest.java | 31 ++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 core/src/test/java/org/jboss/jandex/test/TypeFromClassTest.java diff --git a/core/src/main/java/org/jboss/jandex/Type.java b/core/src/main/java/org/jboss/jandex/Type.java index 992aef40..81c361b1 100644 --- a/core/src/main/java/org/jboss/jandex/Type.java +++ b/core/src/main/java/org/jboss/jandex/Type.java @@ -198,6 +198,56 @@ public static Type create(DotName name, Kind kind) { } } + /** + * Creates a type that corresponds to the given {@code clazz}. The resulting type may be: + * + * + * @param clazz a {@link Class} + * @return a {@link Type} corresponding to the given {@code clazz} + */ + public static Type create(Class clazz) { + if (clazz.isArray()) { + int dimensions = 1; + Class componentType = clazz.getComponentType(); + while (componentType.isArray()) { + dimensions++; + componentType = componentType.getComponentType(); + } + return ArrayType.create(create(componentType), dimensions); + } + + if (clazz.isPrimitive()) { + if (clazz == Void.TYPE) { + return VoidType.VOID; + } else if (clazz == Boolean.TYPE) { + return PrimitiveType.BOOLEAN; + } else if (clazz == Byte.TYPE) { + return PrimitiveType.BYTE; + } else if (clazz == Short.TYPE) { + return PrimitiveType.SHORT; + } else if (clazz == Integer.TYPE) { + return PrimitiveType.INT; + } else if (clazz == Long.TYPE) { + return PrimitiveType.LONG; + } else if (clazz == Float.TYPE) { + return PrimitiveType.FLOAT; + } else if (clazz == Double.TYPE) { + return PrimitiveType.DOUBLE; + } else if (clazz == Character.TYPE) { + return PrimitiveType.CHAR; + } else { + throw new IllegalArgumentException("Unknown primitive type " + clazz); + } + } + + return ClassType.create(DotName.createSimple(clazz.getName())); + } + /** * Creates an instance of specified type with given type {@code annotations}. * To create the type instance, this method delegates to {@link #create(DotName, Kind)}. diff --git a/core/src/test/java/org/jboss/jandex/test/TypeFromClassTest.java b/core/src/test/java/org/jboss/jandex/test/TypeFromClassTest.java new file mode 100644 index 00000000..4fe9e14b --- /dev/null +++ b/core/src/test/java/org/jboss/jandex/test/TypeFromClassTest.java @@ -0,0 +1,31 @@ +package org.jboss.jandex.test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.jboss.jandex.ArrayType; +import org.jboss.jandex.ClassType; +import org.jboss.jandex.DotName; +import org.jboss.jandex.PrimitiveType; +import org.jboss.jandex.Type; +import org.jboss.jandex.VoidType; +import org.junit.jupiter.api.Test; + +public class TypeFromClassTest { + @Test + public void test() { + Type type = Type.create(void.class); + assertEquals(VoidType.VOID, type); + + type = Type.create(byte.class); + assertEquals(PrimitiveType.BYTE, type); + + type = Type.create(Object.class); + assertEquals(ClassType.create(DotName.OBJECT_NAME), type); + + type = Type.create(boolean[].class); + assertEquals(ArrayType.create(PrimitiveType.BOOLEAN, 1), type); + + type = Type.create(String[][].class); + assertEquals(ArrayType.create(ClassType.create(DotName.STRING_NAME), 2), type); + } +} From 14591a48064c90f46b2525770b40b96e10a1d038 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Wed, 24 Jan 2024 14:11:38 +0100 Subject: [PATCH 2/3] improve AnnotationInstanceBuilder methods that add class-valued annotation members - use `Type.create(Class)` for correct handling of non-class types - fix validation of types, multi-dimensional arrays are permitted --- .../jandex/AnnotationInstanceBuilder.java | 12 +++++------ .../test/AnnotationInstanceBuilderTest.java | 20 ++++++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/jboss/jandex/AnnotationInstanceBuilder.java b/core/src/main/java/org/jboss/jandex/AnnotationInstanceBuilder.java index c70bae3f..e0333daa 100644 --- a/core/src/main/java/org/jboss/jandex/AnnotationInstanceBuilder.java +++ b/core/src/main/java/org/jboss/jandex/AnnotationInstanceBuilder.java @@ -591,8 +591,7 @@ public AnnotationInstanceBuilder add(String name, Class value) { throw new IllegalArgumentException("Annotation member '" + name + "' already added"); } - DotName className = DotName.createSimple(value.getName()); - Type clazz = Type.create(className, Type.Kind.CLASS); + Type clazz = Type.create(value); this.values.add(AnnotationValue.createClassValue(name, clazz)); return this; } @@ -614,8 +613,7 @@ public AnnotationInstanceBuilder add(String name, Class[] values) { AnnotationValue[] array = new AnnotationValue[values.length]; for (int i = 0; i < values.length; i++) { - DotName className = DotName.createSimple(values[i].getName()); - Type clazz = Type.create(className, Type.Kind.CLASS); + Type clazz = Type.create(values[i]); array[i] = AnnotationValue.createClassValue(name, clazz); } this.values.add(AnnotationValue.createArrayValue(name, array)); @@ -673,9 +671,9 @@ private void validateType(Type type) { if (kind == Type.Kind.VOID || kind == Type.Kind.PRIMITIVE || kind == Type.Kind.CLASS) { return; } - if (kind == Type.Kind.ARRAY && type.asArrayType().dimensions() == 1) { - Type.Kind constituent = type.asArrayType().constituent().kind(); - if (constituent == Type.Kind.PRIMITIVE || constituent == Type.Kind.CLASS) { + if (kind == Type.Kind.ARRAY) { + Type.Kind element = type.asArrayType().elementType().kind(); + if (element == Type.Kind.PRIMITIVE || element == Type.Kind.CLASS) { return; } } diff --git a/core/src/test/java/org/jboss/jandex/test/AnnotationInstanceBuilderTest.java b/core/src/test/java/org/jboss/jandex/test/AnnotationInstanceBuilderTest.java index e22b762d..68371eed 100644 --- a/core/src/test/java/org/jboss/jandex/test/AnnotationInstanceBuilderTest.java +++ b/core/src/test/java/org/jboss/jandex/test/AnnotationInstanceBuilderTest.java @@ -9,8 +9,12 @@ import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.ArrayType; +import org.jboss.jandex.ClassType; import org.jboss.jandex.DotName; +import org.jboss.jandex.PrimitiveType; import org.jboss.jandex.Type; +import org.jboss.jandex.VoidType; import org.junit.jupiter.api.Test; public class AnnotationInstanceBuilderTest { @@ -129,9 +133,11 @@ private static void verify(AnnotationInstance ann) { assertEquals(SimpleEnum.class.getName(), ann.value("enArray").asEnumTypeArray()[0].toString()); assertEquals(SimpleEnum.BAZ.name(), ann.value("enArray").asEnumArray()[1]); assertEquals(SimpleEnum.class.getName(), ann.value("enArray").asEnumTypeArray()[1].toString()); - assertEquals(2, ann.value("clsArray").asClassArray().length); + assertEquals(4, ann.value("clsArray").asClassArray().length); assertEquals(String.class.getName(), ann.value("clsArray").asClassArray()[0].name().toString()); - assertEquals(Number.class.getName(), ann.value("clsArray").asClassArray()[1].name().toString()); + assertEquals(void.class.getName(), ann.value("clsArray").asClassArray()[1].name().toString()); + assertEquals(Number[].class.getName(), ann.value("clsArray").asClassArray()[2].name().toString()); + assertEquals(byte[][].class.getName(), ann.value("clsArray").asClassArray()[3].name().toString()); assertEquals(2, ann.value("nestedArray").asNestedArray().length); assertEquals("two", ann.value("nestedArray").asNestedArray()[0].value().asString()); assertEquals("three", ann.value("nestedArray").asNestedArray()[1].value().asString()); @@ -193,10 +199,10 @@ private static AnnotationInstance complexAnnotation_manual() { AnnotationValue.createEnumValue("", DotName.createSimple(SimpleEnum.class.getName()), "BAZ"), }), AnnotationValue.createArrayValue("clsArray", new AnnotationValue[] { - AnnotationValue.createClassValue("", - Type.create(DotName.createSimple("java.lang.String"), Type.Kind.CLASS)), - AnnotationValue.createClassValue("", - Type.create(DotName.createSimple("java.lang.Number"), Type.Kind.CLASS)), + AnnotationValue.createClassValue("", ClassType.create(String.class)), + AnnotationValue.createClassValue("", VoidType.VOID), + AnnotationValue.createClassValue("", ArrayType.create(ClassType.create(Number.class), 1)), + AnnotationValue.createClassValue("", ArrayType.create(PrimitiveType.BYTE, 2)), }), AnnotationValue.createArrayValue("nestedArray", new AnnotationValue[] { AnnotationValue.createNestedAnnotationValue("", simpleAnnotation_manual("two")), @@ -233,7 +239,7 @@ private static AnnotationInstance complexAnnotation_builder() { .add("chArray", new char[] { 'd', 'e' }) .add("strArray", new String[] { "fg", "hi" }) .add("enArray", new SimpleEnum[] { SimpleEnum.BAR, SimpleEnum.BAZ }) - .add("clsArray", new Class[] { String.class, Number.class }) + .add("clsArray", new Class[] { String.class, void.class, Number[].class, byte[][].class }) .add("nestedArray", new AnnotationInstance[] { simpleAnnotation_builder("two"), simpleAnnotation_builder("three") }) .build(); From d10e95df884b0e8d7a0216ff1ad6ca6352a8d40b Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Wed, 24 Jan 2024 14:09:32 +0100 Subject: [PATCH 3/3] improve javadoc of VoidType and MethodInfo --- core/src/main/java/org/jboss/jandex/MethodInfo.java | 5 ++--- core/src/main/java/org/jboss/jandex/VoidType.java | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/jboss/jandex/MethodInfo.java b/core/src/main/java/org/jboss/jandex/MethodInfo.java index 001394a0..c0fcf4be 100644 --- a/core/src/main/java/org/jboss/jandex/MethodInfo.java +++ b/core/src/main/java/org/jboss/jandex/MethodInfo.java @@ -35,9 +35,8 @@ * However, {@link #descriptorParameterTypes()} and {@link #descriptorParametersCount()} * may be used to obtain information about all parameters, including mandated and synthetic. *

- * As an exception to the rule above, in case of well known methods where no parameter - * is declared explicitly, the implicitly declared parameters are included. This currently - * applies to the implicitly declared parameters of: + * As an exception to the rule above, implicitly declared parameters are always included + * in case of methods that don't have an explicit parameter list. These are: *

    *
  • the implicitly declared {@code valueOf()} method in enums;
  • *
  • the compact constructor in records.
  • diff --git a/core/src/main/java/org/jboss/jandex/VoidType.java b/core/src/main/java/org/jboss/jandex/VoidType.java index 237c88ab..982ea9cd 100644 --- a/core/src/main/java/org/jboss/jandex/VoidType.java +++ b/core/src/main/java/org/jboss/jandex/VoidType.java @@ -19,7 +19,7 @@ package org.jboss.jandex; /** - * Specifies "void" in a method signature. + * Represents the {@code void} pseudo-type, which may appear in a method signature. * * @since 2.0 * @author Jason T. Greene