MCPcopy Create free account
hub / github.com/apache/groovy / Annotations

Class Annotations

src/main/java/org/codehaus/groovy/ast/decompiled/Annotations.java:69–308  ·  view source on GitHub ↗

Utility class that converts annotation metadata extracted from bytecode into corresponding AST node representations. Handles JSR 175 (annotation) and JSR 308 (type annotation) conversions from ASM-parsed structures to Groovy AST AnnotationNode instances. Key responsibilities: Converti

Source from the content-addressed store, hash-verified

67 * @see AsmReferenceResolver
68 */
69class Annotations {
70 /**
71 * Creates an {@link AnnotationNode} from bytecode annotation metadata.
72 * Resolves the annotation class using the provided resolver and converts all annotation members
73 * to corresponding AST expressions. Returns null if the annotation class cannot be resolved
74 * (e.g., not present on classpath).
75 *
76 * <p>If resolution fails, the annotation is silently skipped to allow compilation with missing
77 * annotation types (e.g., runtime-only annotations not in classpath).
78 *
79 * @param annotation the {@link AnnotationStub} containing bytecode annotation metadata
80 * @param resolver the {@link AsmReferenceResolver} used to resolve the annotation class type
81 * @return the created {@link AnnotationNode}, or null if the annotation class cannot be resolved
82 * @see DecompiledAnnotationNode
83 */
84 static AnnotationNode createAnnotationNode(AnnotationStub annotation, AsmReferenceResolver resolver) {
85 ClassNode classNode = resolver.resolveClassNullable(Type.getType(annotation.className).getClassName());
86 if (classNode == null) {
87 // there might be annotations not present in the classpath
88 // e.g. java.lang.Synthetic (http://forge.ow2.org/tracker/?aid=307392&group_id=23&atid=100023&func=detail)
89 // so skip them
90 return null;
91 }
92
93 AnnotationNode node = new DecompiledAnnotationNode(classNode);
94 for (Map.Entry<String, Object> entry : annotation.members.entrySet()) {
95 addMemberIfFound(resolver, node, entry);
96 }
97 return node;
98 }
99
100 /**
101 * Adds a single annotation member to the given {@link AnnotationNode} if the member value
102 * can be successfully converted to an AST expression. Silently skips members with unconvertible values.
103 *
104 * @param resolver the {@link AsmReferenceResolver} used for type resolution
105 * @param node the {@link AnnotationNode} to add the member to
106 * @param entry the key-value pair from annotation member map (name → value)
107 */
108 private static void addMemberIfFound(AsmReferenceResolver resolver, AnnotationNode node, Map.Entry<String, Object> entry) {
109 Expression value = annotationValueToExpression(entry.getValue(), resolver);
110 if (value != null) {
111 node.addMember(entry.getKey(), value);
112 }
113 }
114
115 /**
116 * Converts a bytecode annotation element value to a corresponding AST expression.
117 * Handles all annotation value types according to JVMS §4.7.16:
118 * <ul>
119 * <li>{@link TypeWrapper} → {@link ClassExpression}</li>
120 * <li>{@link EnumConstantWrapper} → {@link PropertyExpression} for enum constant access</li>
121 * <li>{@link AnnotationStub} → {@link AnnotationConstantExpression} for nested annotations</li>
122 * <li>Arrays (via {@link Array.getLength()}) → {@link ListExpression} with recursive conversion</li>
123 * <li>{@link List} → {@link ListExpression} with recursive conversion</li>
124 * <li>Primitives and strings → {@link ConstantExpression}</li>
125 * </ul>
126 *

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected