On Mon, 17 May 2021 19:01:01 GMT, Jan Lahoda <jlah...@openjdk.org> wrote:

>> Good work. There's a lot to take in here. I think overall, it holds up well 
>> - I like how case labels have been extended to accommodate for patterns. In 
>> the front-end, I think there are some questions over the split between Attr 
>> and Flow - maybe it is unavoidable, but I'm not sure why some control-flow 
>> analysis happens in Attr instead of Flow and I left some questions to make 
>> sure I understand what's happening.
>> 
>> In the backend it's mostly good work - but overall the structure of the 
>> code, both in Lower and in TransPattern is getting very difficult to follow, 
>> given there are many different kind of switches each with its own little 
>> twist attached to it. It would be nice, I think (maybe in a separate 
>> cleanup?) if the code paths serving the different switch kinds could be made 
>> more separate, so that, when reading the code we can worry only about one 
>> possible code shape. That would make the code easier to document as well.
>
> @mcimadamore, @forax, thanks a lot for comments! I tried to apply the 
> requested changes in recent commits 
> (https://github.com/openjdk/jdk/pull/3863/commits/3fc2502a33cec20f39fe571eb25538ee3b459a9b
>  
> https://github.com/openjdk/jdk/pull/3863/commits/aeddb85e65bf77ed62dc7fa1ad00c29646d02c99
>  ).
> 
> I've also tried to update the implementation for the latest spec changes here:
> https://github.com/openjdk/jdk/pull/3863/commits/54ba974e1aac00bbde1c3bd2627f01caaaeda09b
> 
> The spec changes are: total patterns are nullable; pattern matching ("new") 
> statement switches must be complete (as switch expressions).
> 
> Any further feedback is welcome!

Hi @lahodaj  👋 ,

I tried `javac` built from this PR and for the following `Example.java`


class Example {
        void example(Object o) {
                switch (o) {
                case String s && s.length() == 0 ->
                        System.out.println("1st case");
                case String s && s.length() == 1 ->          // line 6
                        System.out.println("2nd case");      // line 7
                case String s ->                             // line 8
                        System.out.println("3rd case");      // line 9
                default ->                                   // line 10
                        System.out.println("default case");  // line 11
                }
        }
}


execution of


javac --enable-preview --release 17 Example.java
javap -v -p Example.class


produces


  void example(java.lang.Object);
    descriptor: (Ljava/lang/Object;)V
    flags: (0x0000)
    Code:
      stack=2, locals=7, args_size=2
         0: aload_1
         1: dup
         2: invokestatic  #7                  // Method 
java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
         5: pop
         6: astore_2
         7: iconst_0
         8: istore_3
         9: aload_2
        10: iload_3
        11: invokedynamic #13,  0             // InvokeDynamic 
#0:typeSwitch:(Ljava/lang/Object;I)I
        16: tableswitch   { // 0 to 2
                       0: 44
                       1: 74
                       2: 105
                 default: 122
            }
        44: aload_2
        45: checkcast     #17                 // class java/lang/String
        48: astore        4
        50: aload         4
        52: invokevirtual #19                 // Method 
java/lang/String.length:()I
        55: ifeq          63
        58: iconst_1
        59: istore_3
        60: goto          9
        63: getstatic     #23                 // Field 
java/lang/System.out:Ljava/io/PrintStream;
        66: ldc           #29                 // String 1st case
        68: invokevirtual #31                 // Method 
java/io/PrintStream.println:(Ljava/lang/String;)V
        71: goto          133
        74: aload_2
        75: checkcast     #17                 // class java/lang/String
        78: astore        5
        80: aload         5
        82: invokevirtual #19                 // Method 
java/lang/String.length:()I
        85: iconst_1
        86: if_icmpeq     94
        89: iconst_2
        90: istore_3
        91: goto          9
        94: getstatic     #23                 // Field 
java/lang/System.out:Ljava/io/PrintStream;
        97: ldc           #37                 // String 2nd case
        99: invokevirtual #31                 // Method 
java/io/PrintStream.println:(Ljava/lang/String;)V
       102: goto          133
       105: aload_2
       106: checkcast     #17                 // class java/lang/String
       109: astore        6
       111: getstatic     #23                 // Field 
java/lang/System.out:Ljava/io/PrintStream;
       114: ldc           #39                 // String 3rd case
       116: invokevirtual #31                 // Method 
java/io/PrintStream.println:(Ljava/lang/String;)V
       119: goto          133
       122: getstatic     #23                 // Field 
java/lang/System.out:Ljava/io/PrintStream;
       125: ldc           #41                 // String default case
       127: invokevirtual #31                 // Method 
java/io/PrintStream.println:(Ljava/lang/String;)V
       130: goto          133
       133: return
      LineNumberTable:
        line 3: 0
        line 4: 44
        line 5: 63
        line 4: 71
        line 6: 74
        line 7: 94
        line 6: 102
        line 8: 105
        line 9: 111
        line 8: 119
        line 11: 122
        line 8: 130
        line 13: 133


I believe `LineNumberTable` entries `line 6: 102`, `line 8: 119` and `line 8: 
130` should not be present.
Otherwise debugger misleadingly will be showing
line `6` after step from line `7`,
line `8` after step from line `9`
and even more misleadingly line `8` after step from line `11`.

This also affects [JaCoCo](https://github.com/jacoco/jacoco) Java Code Coverage 
tool (I'm one of its developers), which relies on LineNumberTable to provide 
code coverage highlighting and these entries cause misleading highlighting - 
partial coverage of line `8` when default case was not executed.

Should I create separate ticket about this in https://bugs.openjdk.java.net/ or 
this comment here is enough?

-------------

PR: https://git.openjdk.java.net/jdk/pull/3863

Reply via email to