Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8223305

Compiler Support for Switch Expressions (Second Preview)

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P2 P2
    • 13
    • tools
    • None
    • source
    • low
    • Hide
      The impact on source code is threefold:

      1. Unqualified invocations of methods called `yield` (e.g., `yield(1);`) will henceforth be parsed as `yield` statements, not as method invocations. Consequently, unqualified invocations of methods called `yield` will not be possible, but such invocations are believed to be rare. The code's original intent can be recovered by qualifying the method invocation (e.g., `this.yield(1);`) which is a local change.

      2. Declarations of the type `yield` are no longer permitted (as for `var`). Since the name `yield` does not follow the JLS conventions for type names, this should be a very rare case.

      3. Code that uses the value `break` statement (a preview feature in Java SE 12) to yield a value from a `switch` expression must be changed to use a `yield` statement instead. Because the value `break` statement was a preview feature, developers were aware of the possibility of change.
      Show
      The impact on source code is threefold: 1. Unqualified invocations of methods called `yield` (e.g., `yield(1);`) will henceforth be parsed as `yield` statements, not as method invocations. Consequently, unqualified invocations of methods called `yield` will not be possible, but such invocations are believed to be rare. The code's original intent can be recovered by qualifying the method invocation (e.g., `this.yield(1);`) which is a local change. 2. Declarations of the type `yield` are no longer permitted (as for `var`). Since the name `yield` does not follow the JLS conventions for type names, this should be a very rare case. 3. Code that uses the value `break` statement (a preview feature in Java SE 12) to yield a value from a `switch` expression must be changed to use a `yield` statement instead. Because the value `break` statement was a preview feature, developers were aware of the possibility of change.
    • Language construct
    • SE

      Summary

      Switch expressions were a preview feature in Java SE 12 (see JEP 325 and the CSR). Based on experience with the feature, the value break statement which yields a value from a switch expression should be replaced by a yield statement.

      Problem

      The value break statement is confusing to developers because it overloads the break with label statement. For example, break L; would be a labeled break statement in a for loop (transferring control out of the loop without yielding any value) but would be a value break statement in a switch expression (yielding the value of variable L as the result of the switch). In addition, the need for a value break statement in a switch expression is quite rare -- only when the RHS of a case ... -> is a block rather than an expression -- but the reuse of the break keyword reminds developers of the almost universal need for break in a switch statement; this tends to hurt understanding of switch expressions more broadly.

      Solution

      The value break statement is replaced by a new yield statement.

      As yield is a valid identifier, it is not practicable to start treating it as a keyword. Even treating it as a restricted keyword leads to the potential problem that parsing a yield statement might require unlimited lookahead to determine if the character sequence yield should be tokenized as a keyword or as an identifier.

      We propose a simpler strategy, building on the approach taken when adding var in JDK 10: var and now yield are considered restricted identifiers. Restricted identifiers are not valid type identifiers, i.e., you cannot declare a type called var or yield.

      In addition we consider yield to be an invalid name for an unqualified method invocation. This means that the phrase yield (3); will be parsed as a yield statement and not as an unqualified invocation of a yield method. Invocations of methods called yield must be qualified, e.g., Thread.yield(); or this.yield();. It is still permitted to declare an instance variable or local variable called yield, and to use such a variable without qualification, even in a statement context such as yield++; or yield = 1;. For such usages, the compiler is expected to perform limited lookahead and disambiguate between YieldStatement and ExpressionStatement.

      Analysis of the Java SE API reveals only one method named yield; the occurrence of a method named yield in other large codebases is similarly rare.

      This update will require corresponding changes in the JDK-specific Compiler Tree API.

      Specification

      The updated JLS changes for switch expressions is attached, and also available online.

      The specdiff for the Trees API changes is attached, and also available online.

        1. jep354-jls-20190528.html
          288 kB
        2. specdiff.01.zip
          4.26 MB
        3. specdiff.01a.zip
          4.29 MB

            jlahoda Jan Lahoda
            jlahoda Jan Lahoda
            Alex Buckley, Gavin Bierman
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: