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

Compiler Support for JEP 354: Switch Expressions (Preview)

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P2
    • Resolution: Approved
    • Fix Version/s: 13
    • Component/s: tools
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      source
    • Compatibility Risk:
      low
    • Compatibility Risk Description:
      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.
    • Interface Kind:
      Language construct
    • Scope:
      SE

      Description

      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's not practicable to declare it a keyword. Declaring it as a restricted keyword, or equivalent approaches, lead 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 a 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 should be qualified, e.g. Thread.yield(); or this.yield(); It is still permitted to have a local variable named yield, and usage of such locals parse as normal, e.g. yield++;.

      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.

        Attachments

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

          Issue Links

            Activity

              People

              • Assignee:
                jlahoda Jan Lahoda
                Reporter:
                jlahoda Jan Lahoda
                Reviewed By:
                Alex Buckley, Gavin Bierman
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: