[
https://issues.apache.org/jira/browse/GROOVY-12253?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Paul King updated GROOVY-12253:
-------------------------------
Description:
GROOVY-12252 taught {{NullChecker}} to honour {{@Nullable}} type arguments
wherever the static type checker's inference carries them through a class or
method level type variable ({{get(0)}}, the {{xs\[0]}} subscript, GDK
{{head()}} on a {{List<@Nullable String>}}, etc.). This umbrella issue captures
the remaining generics nullness positions, targeted at Groovy 7. Sub-tasks or
linked issues can be spun off per item as work starts.
*Remaining positions*
* *Nullable type parameters and bounds* — {{<T extends @Nullable Object>}} on
generic classes and methods, i.e. whether a type _variable itself_ admits null,
and JSpecify's distinction between a nullable bound and an unspecified one.
Today the checker only sees nullness once a variable has been instantiated with
an annotated argument.
* *Wildcards at use sites* — {{List<? extends @Nullable Foo>}} and {{? super}}
forms. The bytecode reader (GROOVY-12206) already walks wildcard bounds when
attaching type annotations, so the data is present; the checker does not yet
consult it.
* *Argument positions* — checking values flowing _into_ instantiated parameter
types: {{add(null)}} on a {{List<@NonNull String>}} (or on a {{List<String>}}
within a {{@NullMarked}} scope) should be an error. GROOVY-12252 covers only
the result direction.
* *Array component positions* — distinguishing {{@Nullable String\[\]}}
(nullable elements) from {{String @Nullable \[\]}} (nullable array), for
element reads and writes. The checker currently treats top-level type-use
annotations on the declared type only.
* *Defaulting inside type arguments* — applying {{@NullMarked}} /
{{@NullUnmarked}} scope semantics to type argument positions, per the JSpecify
specification, rather than only to declarations.
*Validation*
JSpecify publishes a conformance test suite that implementations (e.g.
NullAway) run to measure and publish their conformance. As the items above
land, running the applicable subset would give a principled statement of where
the checker conforms and where it deliberately diverges (e.g. simple-name
annotation matching), in place of a hand-maintained feature list.
*Out of scope*
Contract nullness of unannotated libraries (a GDK {{find}} returning null on no
match, {{Map.get}} on a missing key) is a separate concern: it needs
{{@Nullable}} declarations on the library side (annotating the GDK) or an
external nullness model, not generics machinery, and should be raised as its
own issue.
> NullChecker: wider JSpecify generics support (umbrella: nullable bounds,
> wildcards, argument positions, array components)
> -------------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12253
> URL: https://issues.apache.org/jira/browse/GROOVY-12253
> Project: Groovy
> Issue Type: Improvement
> Components: groovy-typecheckers
> Reporter: Paul King
> Priority: Major
> Fix For: 7.x
>
>
> GROOVY-12252 taught {{NullChecker}} to honour {{@Nullable}} type arguments
> wherever the static type checker's inference carries them through a class or
> method level type variable ({{get(0)}}, the {{xs\[0]}} subscript, GDK
> {{head()}} on a {{List<@Nullable String>}}, etc.). This umbrella issue
> captures the remaining generics nullness positions, targeted at Groovy 7.
> Sub-tasks or linked issues can be spun off per item as work starts.
> *Remaining positions*
> * *Nullable type parameters and bounds* — {{<T extends @Nullable Object>}} on
> generic classes and methods, i.e. whether a type _variable itself_ admits
> null, and JSpecify's distinction between a nullable bound and an unspecified
> one. Today the checker only sees nullness once a variable has been
> instantiated with an annotated argument.
> * *Wildcards at use sites* — {{List<? extends @Nullable Foo>}} and {{?
> super}} forms. The bytecode reader (GROOVY-12206) already walks wildcard
> bounds when attaching type annotations, so the data is present; the checker
> does not yet consult it.
> * *Argument positions* — checking values flowing _into_ instantiated
> parameter types: {{add(null)}} on a {{List<@NonNull String>}} (or on a
> {{List<String>}} within a {{@NullMarked}} scope) should be an error.
> GROOVY-12252 covers only the result direction.
> * *Array component positions* — distinguishing {{@Nullable String\[\]}}
> (nullable elements) from {{String @Nullable \[\]}} (nullable array), for
> element reads and writes. The checker currently treats top-level type-use
> annotations on the declared type only.
> * *Defaulting inside type arguments* — applying {{@NullMarked}} /
> {{@NullUnmarked}} scope semantics to type argument positions, per the
> JSpecify specification, rather than only to declarations.
> *Validation*
> JSpecify publishes a conformance test suite that implementations (e.g.
> NullAway) run to measure and publish their conformance. As the items above
> land, running the applicable subset would give a principled statement of
> where the checker conforms and where it deliberately diverges (e.g.
> simple-name annotation matching), in place of a hand-maintained feature list.
> *Out of scope*
> Contract nullness of unannotated libraries (a GDK {{find}} returning null on
> no match, {{Map.get}} on a missing key) is a separate concern: it needs
> {{@Nullable}} declarations on the library side (annotating the GDK) or an
> external nullness model, not generics machinery, and should be raised as its
> own issue.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)