[ 
https://issues.apache.org/jira/browse/GROOVY-12209?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18100013#comment-18100013
 ] 

ASF GitHub Bot commented on GROOVY-12209:
-----------------------------------------

paulk-asert opened a new pull request, #2747:
URL: https://github.com/apache/groovy/pull/2747

   … results




> NullChecker: track nullness through ?., ?:, and ternary results
> ---------------------------------------------------------------
>
>                 Key: GROOVY-12209
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12209
>             Project: Groovy
>          Issue Type: Improvement
>          Components: groovy-typecheckers
>            Reporter: Paul King
>            Priority: Major
>
> The incubating {{groovy.typecheckers.NullChecker}} tracks nullability per 
> *variable*, and already handles several expression forms: dereferencing a 
> {{@Nullable}}-returning method call is flagged, strict mode merges 
> null-literal branches of ternaries, and elvis assignments over null-literal 
> fallbacks are tracked (see {{testNullableMethodReturnDereference}}, 
> {{testStrictTernary*}}, {{testStrictElvis*}}).
> However, nullness of expression *results* is not propagated in general — the 
> null-literal flows work while nullable-expression flows don't. Confirmed gaps:
> * Safe-navigation results: the documented behaviour is unchanged — 
> {{input?.length()}} stays OK, since {{?.}} guards the receiver it is applied 
> to. The gap is the *result* of a safe navigation used as an unguarded 
> receiver afterwards: {{a?.b.c}} parses as {{(a?.b).c}} and throws NPE at 
> runtime when {{a}} is null, so it should be flagged ({{a?.b}} is nullable by 
> definition, even when {{b}} is {{@NonNull}}), while {{a?.b?.c}} is fine. 
> Currently only {{VariableExpression}} and {{MethodCallExpression}} receivers 
> are checked in {{checkDereference}}, so a {{PropertyExpression}} receiver 
> passes silently.
> * Nullable expressions as arguments: {{isKnownNullable}} recognizes variables 
> only, so passing a {{@Nullable}}-returning call or a safe-navigation result 
> directly to a {{@NonNull}} parameter (e.g. {{process(repo.findById(id))}}) is 
> not caught — only when first assigned to a variable.
> * Ternary/elvis over nullable non-literals: {{cond ? maybeNull : other}} and 
> {{x ?: maybeNullCall()}} where a branch is a nullable *variable or call* 
> (rather than a null literal) are not merged into the result's nullness.
> * {{@Nullable}} getters dereferenced via property syntax mid-chain: {{x.a.b}} 
> where {{getA()}} is {{@Nullable}} is caught when written as {{x.getA().b}} 
> but not in property form.
> * Cast and parenthesized expressions should be transparent to nullness in 
> {{isKnownNullable}} (they already are in {{isNullExpr}}).
> Together with broadened guard recognition (companion issue), this moves the 
> checker from "annotated variables" coverage to "annotated APIs used 
> idiomatically" coverage — values obtained from framework calls and used 
> inline, which is where most real null-mishandling occurs.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to