|
58 | 58 | import static javax.lang.model.type.TypeKind.ARRAY; |
59 | 59 | import static javax.lang.model.type.TypeKind.DECLARED; |
60 | 60 |
|
| 61 | +import static javax.lang.model.util.ElementFilter.methodsIn; |
| 62 | + |
61 | 63 | import static org.microbean.construct.element.AnnotationMirrors.validAnnotationInterfaceElementScalarType; |
62 | 64 |
|
63 | 65 | /** |
@@ -285,6 +287,46 @@ public SyntheticAnnotationTypeElement(final List<? extends AnnotationMirror> ann |
285 | 287 | this(annotationMirrors, new SyntheticName(fullyQualifiedName), elements); |
286 | 288 | } |
287 | 289 |
|
| 290 | + /** |
| 291 | + * Creates a new {@link SyntheticAnnotationTypeElement}, mostly, if not exclusively, for use by {@link |
| 292 | + * SyntheticAnnotationMirror} instances. |
| 293 | + * |
| 294 | + * @param e a non-{@code null} {@link TypeElement} whose {@link TypeElement#getKind() getKind()} method returns {@link |
| 295 | + * javax.lang.model.element.ElementKind#ANNOTATION_TYPE} |
| 296 | + * |
| 297 | + * @exception NullPointerException if {@code e} is {@code null} |
| 298 | + * |
| 299 | + * @exception IllegalArgumentException if the supplied {@link TypeElement}'s {@link TypeElement#getKind() getKind()} |
| 300 | + * method does not return {@link javax.lang.model.element.ElementKind#ANNOTATION_TYPE} |
| 301 | + */ |
| 302 | + public SyntheticAnnotationTypeElement(final TypeElement e) { |
| 303 | + super(); |
| 304 | + if (e.getKind() != ANNOTATION_TYPE) { |
| 305 | + throw new IllegalArgumentException("e: " + e); |
| 306 | + } |
| 307 | + this.annotationMirrors = new CopyOnWriteArrayList<>(e.getAnnotationMirrors()); |
| 308 | + Name n = e.getSimpleName(); |
| 309 | + this.sn = n instanceof SyntheticName sn ? sn : new SyntheticName(n.toString()); |
| 310 | + n = e.getQualifiedName(); |
| 311 | + this.fqn = n instanceof SyntheticName sn ? sn : new SyntheticName(n.toString()); |
| 312 | + // Deliberate: Type is an inner class and hence cannot be shared |
| 313 | + this.type = new Type(); |
| 314 | + final List<ExecutableElement> elements = methodsIn(e.getEnclosedElements()); |
| 315 | + if (elements.isEmpty()) { |
| 316 | + this.elements = List.of(); |
| 317 | + } else { |
| 318 | + final List<InternalAnnotationElement> elements0 = new ArrayList<>(elements.size()); |
| 319 | + for (final ExecutableElement ee :elements) { |
| 320 | + // Deliberate: no instanceof InternalAnnotationElement check, i.e. wrapping/copying is deliberate and necessary |
| 321 | + elements0.add(new InternalAnnotationElement(ee.getAnnotationMirrors(), |
| 322 | + ee.getReturnType(), |
| 323 | + ee.getSimpleName(), |
| 324 | + ee.getDefaultValue())); |
| 325 | + } |
| 326 | + this.elements = unmodifiableList(elements0); |
| 327 | + } |
| 328 | + } |
| 329 | + |
288 | 330 | /** |
289 | 331 | * Creates a new {@link SyntheticAnnotationTypeElement}, mostly, if not exclusively, for use by {@link |
290 | 332 | * SyntheticAnnotationMirror} instances. |
@@ -320,8 +362,8 @@ public SyntheticAnnotationTypeElement(final List<? extends AnnotationMirror> ann |
320 | 362 | this.elements = List.of(); |
321 | 363 | } else { |
322 | 364 | final List<InternalAnnotationElement> elements0 = new ArrayList<>(elements.size()); |
323 | | - for (final SyntheticAnnotationElement e : elements) { |
324 | | - elements0.add(new InternalAnnotationElement(e.annotationMirrors(), e.type(), e.name(), e.defaultValue())); |
| 365 | + for (final SyntheticAnnotationElement sae : elements) { |
| 366 | + elements0.add(new InternalAnnotationElement(sae.annotationMirrors(), sae.type(), sae.name(), sae.defaultValue())); |
325 | 367 | } |
326 | 368 | this.elements = unmodifiableList(elements0); |
327 | 369 | } |
@@ -572,7 +614,7 @@ public SyntheticAnnotationElement(final List<? extends AnnotationMirror> annotat |
572 | 614 | case ArrayType t when t.getKind() == ARRAY -> validateScalarType(t.getComponentType()); |
573 | 615 | default -> validateScalarType(type); |
574 | 616 | }; |
575 | | - if (name.equals("getClass") || name.equals("hashCode") || name.equals("toString")) { |
| 617 | + if (name.contentEquals("getClass") || name.contentEquals("hashCode") || name.contentEquals("toString")) { |
576 | 618 | // java.lang.Object-declared methods that might otherwise meet annotation element requirements |
577 | 619 | throw new IllegalArgumentException("name: " + name); |
578 | 620 | } |
@@ -728,13 +770,15 @@ private final class InternalAnnotationElement implements ExecutableElement { |
728 | 770 |
|
729 | 771 | private InternalAnnotationElement(final List<? extends AnnotationMirror> annotationMirrors, |
730 | 772 | final TypeMirror type, |
731 | | - final SyntheticName name, |
732 | | - final SyntheticAnnotationValue defaultValue) { |
| 773 | + final Name name, |
| 774 | + final AnnotationValue defaultValue) { |
733 | 775 | super(); |
734 | 776 | this.annotationMirrors = new CopyOnWriteArrayList<>(annotationMirrors); |
735 | | - this.t = new Type(type); |
736 | | - this.name = requireNonNull(name, "name"); |
737 | | - this.defaultValue = defaultValue; |
| 777 | + // This Type is NOT an inner class and cannot receive annotations so this is OK. |
| 778 | + this.t = type instanceof Type t ? t : new Type(type); |
| 779 | + this.name = name instanceof SyntheticName sn ? sn : new SyntheticName(name); |
| 780 | + this.defaultValue = |
| 781 | + defaultValue instanceof SyntheticAnnotationValue sav ? sav : new SyntheticAnnotationValue(defaultValue.getValue()); |
738 | 782 | } |
739 | 783 |
|
740 | 784 |
|
@@ -861,6 +905,7 @@ private Type(final TypeMirror type) { // the "return type" |
861 | 905 | this.type = switch (type) { |
862 | 906 | case null -> throw new NullPointerException("type"); |
863 | 907 | case ArrayType t when t.getKind() == ARRAY -> validateScalarType(t.getComponentType()); |
| 908 | + case Type t -> t.type; |
864 | 909 | default -> validateScalarType(type); |
865 | 910 | }; |
866 | 911 | } |
|
0 commit comments