Paul King created GROOVY-12208:
----------------------------------
Summary: NullChecker: broaden null-guard recognition
Key: GROOVY-12208
URL: https://issues.apache.org/jira/browse/GROOVY-12208
Project: Groovy
Issue Type: Improvement
Components: groovy-typecheckers
Reporter: Paul King
The incubating {{groovy.typecheckers.NullChecker}} currently recognizes a
limited in-body guard vocabulary: single {{x != null}} / {{x == null}} binary
comparisons (including identity forms) as {{if}} conditions, and early-exit
patterns ({{if (x == null) return/throw}}), plus safe navigation. (Separately,
the groovy-contracts bridge already infers non-nullness from {{@Requires}}
conditions including conjunctions, via {{StaticTypesMarker.INFERRED_NON_NULL}}
— this issue is about guard recognition inside method bodies, where
conjunctions and other idiomatic forms are not yet recognized.)
Idiomatic Groovy uses several other null-guard forms, each currently producing
false positives that discourage adoption:
* Groovy-truth guards: {{if (x) { x.foo() } }} — for reference types,
truthiness implies non-null within the guarded block (Groovy truth being false
for empty strings/collections does not affect nullness soundness).
* Boolean conjunctions in conditions: {{if (x != null && x.foo())}}, and
short-circuit dereferences {{x != null && x.foo()}} in expression position;
Groovy-truth conjuncts {{x && x.foo()}}.
* {{instanceof}} checks: {{if (x instanceof Foo)}} implies {{x}} is non-null
(aligns with the flow typing the static type checker already performs for
{{instanceof}}).
* {{Objects.nonNull(x)}} / {{Objects.isNull(x)}} in the positions the binary
forms are recognized today.
* {{assert x}} and {{assert x != null}} statements.
* Guard conditions in {{while}} loops and ternary conditions, mirroring the
{{if}} handling.
Each addition removes a class of false positives without changing the checker's
architecture. Test coverage should include the negated forms and else-branch
behaviour for each new guard shape, following the existing patterns in
{{NullCheckerTest}} (cf. {{testNullableWithNotNullGuard}} et al.).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)