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

Oscar N commented on GROOVY-11629:
----------------------------------

I think you could support parameters, variables and field references when 
they're either marked as final or are never re-assigned (effectively-final).

> Redundant null check on @NullChecked parameter when iterating on it
> -------------------------------------------------------------------
>
>                 Key: GROOVY-11629
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11629
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 5.0.0-alpha-12, 3.0.24, 4.0.26
>            Reporter: Oscar N
>            Priority: Minor
>
> When looping over a method parameter whose method is annotated with 
> @NullCheck, an additional null check performed before iterating. Here's a 
> minimal example, demonstrating the numbers parameter being checked for null 
> twice:
> {code:groovy}
> import groovy.transform.CompileStatic
> import groovy.transform.NullCheck
> void main() {
>     listNumbers([1, 2, 3])
> }
> @CompileStatic
> @NullCheck
> void listNumbers(List<Number> numbers) {
>     for (number in numbers)
>         println number
> }
> {code}
> Decompiled Java representation of the bytecode:
> {code:java}
> public void listNumbers(List<Number> numbers) {
>     if (numbers == null) {
>         throw (Throwable)(new IllegalArgumentException("numbers cannot be 
> null"));
>     } else {
>         Iterator var10000 = numbers != null ? numbers.iterator() : null;
>         Object number = null;
>         Iterator var4 = var10000;
>         if (var4 != null) {
>             while(var4.hasNext()) {
>                 number = var4.next();
>                 DefaultGroovyMethods.println(this, number);
>                 Object var6 = null;
>             }
>         }
>     }
> }
> {code}
> Bytecode:
> {code:java}
> // access flags 0x1
> // signature (Ljava/util/List<Ljava/lang/Number;>;)V
> // declaration: void listNumbers(java.util.List<java.lang.Number>)
> public listNumbers(Ljava/util/List;)V
>  L0
>   ALOAD 1
>   IFNONNULL L1
>   ICONST_1
>   GOTO L2
>  L1
>   ICONST_0
>  L2
>   IFEQ L3
>   NEW java/lang/IllegalArgumentException
>   DUP
>   LDC "numbers cannot be null"
>   INVOKESPECIAL java/lang/IllegalArgumentException.<init> 
> (Ljava/lang/String;)V
>   CHECKCAST java/lang/Throwable
>   ATHROW
>  L3
>   LINENUMBER 11 L3
>   ALOAD 1
>   DUP
>   ASTORE 2
>   IFNULL L4
>   ALOAD 2
>   INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator; (itf)
>   GOTO L5
>  L4
>   ACONST_NULL
>  L5
>   ACONST_NULL
>   ASTORE 3
>  L6
>   ASTORE 4
>   ALOAD 4
>   IFNULL L7
>  L8
>   ALOAD 4
>   INVOKEINTERFACE java/util/Iterator.hasNext ()Z (itf)
>   IFEQ L7
>   ALOAD 4
>   INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object; (itf)
>   ASTORE 3
>  L9
>   LINENUMBER 12 L9
>   ALOAD 0
>   ALOAD 3
>   INVOKESTATIC org/codehaus/groovy/runtime/DefaultGroovyMethods.println 
> (Ljava/lang/Object;Ljava/lang/Object;)V
>   ACONST_NULL
>   POP
>   GOTO L8
>  L7
>   LINENUMBER 13 L7
>   RETURN
>   LOCALVARIABLE this LRedundantNullCheck; L0 L7 0
>   LOCALVARIABLE numbers Ljava/util/List; L0 L7 1
>   LOCALVARIABLE number Ljava/lang/Object; L6 L7 3
>   MAXSTACK = 3
>   MAXLOCALS = 5
> {code}
> Note that this also happens in CompileDynamic mode.



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

Reply via email to