You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (Jira)" <ji...@apache.org> on 2026/07/28 23:38:00 UTC
[jira] [Resolved] (GROOVY-12206) Ingest type-use annotations when reading compiled classes
[ https://issues.apache.org/jira/browse/GROOVY-12206?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul King resolved GROOVY-12206.
--------------------------------
Fix Version/s: 6.0.0-beta-1
Assignee: Paul King
Resolution: Fixed
> Ingest type-use annotations when reading compiled classes
> ---------------------------------------------------------
>
> Key: GROOVY-12206
> URL: https://issues.apache.org/jira/browse/GROOVY-12206
> Project: Groovy
> Issue Type: Improvement
> Reporter: Paul King
> Assignee: Paul King
> Priority: Major
> Fix For: 6.0.0-beta-1
>
>
> Groovy currently discards type-use ({{ElementType.TYPE_USE}}) annotations when reading compiled classes, on both resolution paths:
> * The ASM decompiler ({{org.codehaus.groovy.ast.decompiled.AsmDecompiler}}) only overrides {{visitTypeAnnotation}} for record components, and even there discards the {{typeRef}}/{{TypePath}} information. The class, method, and field visitors do not collect {{RuntimeVisibleTypeAnnotations}} at all, so type annotations on method return types, parameter types, field types, supertypes, and generic-signature components of precompiled classes are dropped.
> * The reflection path ({{org.codehaus.groovy.vmplugin.v8.Java8#configureClassNode}}) never consults {{java.lang.reflect.AnnotatedType}} ({{getAnnotatedReturnType}}, {{getAnnotatedParameterTypes}}, ...), so the same information is lost for already-loaded classes.
> This matters because pure JSpecify annotations ({{org.jspecify.annotations.Nullable}} etc.) are {{@Target(TYPE_USE)}} only: in bytecode they appear exclusively in the type-annotation attributes, including on plain non-generic method returns and parameters. Libraries using declaration-targeted annotations (JSR-305 style, Spring 6's {{org.springframework.lang.Nullable}}) remain visible to Groovy today, but a library annotated with pure JSpecify (e.g. Spring Framework 7) is completely invisible to tools such as the incubating {{groovy.typecheckers.NullChecker}}.
> Proposed scope (behaviour-neutral metadata ingestion; no change to type-checking semantics):
> # Collect type annotations in the decompiler stubs for classes, methods, and fields, retaining {{typeRef}} and {{TypePath}}.
> # Surface annotations for the simple positions first (method return type, parameter types, field types, supertypes) onto the corresponding AST nodes / per-use {{ClassNode}}s.
> # Map {{TypePath}}-addressed annotations onto generic-signature components. This requires annotatable per-use ClassNodes when parsing member signatures in {{DecompiledClassNode}}/{{MemberSignatureParser}} (note {{GenericsType}} extends {{ASTNode}}, not {{AnnotatedNode}}; the annotations attach to the type-argument ClassNode as they do for source).
> # Mirror the same for the reflection path via {{AnnotatedType}}.
> Laziness should be preserved (as for existing decompiled-node attributes) so there is no memory overhead when nobody asks for the annotations.
> This is prerequisite plumbing for JSpecify-aware null checking (NullChecker now, deeper static type checker integration later), but is independently useful to any AST transform or tool that needs to see type annotations of dependencies.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)