On Tue, 4 May 2021 16:41:44 GMT, Jan Lahoda <jlah...@openjdk.org> wrote:
> This is a preview of a patch implementing JEP 406: Pattern Matching for > switch (Preview): > https://bugs.openjdk.java.net/browse/JDK-8213076 > > The current draft of the specification is here: > http://cr.openjdk.java.net/~gbierman/jep406/jep406-20210430/specs/patterns-switch-jls.html > > A summary of notable parts of the patch: > -to support cases expressions and patterns in cases, there is a new common > superinterface for expressions and patterns, `CaseLabelTree`, which > expressions and patterns implement, and a list of case labels is returned > from `CaseTree.getLabels()`. > -to support `case default`, there is an implementation of `CaseLabelTree` > that represents it (`DefaultCaseLabelTree`). It is used also to represent the > conventional `default` internally and in the newly added methods. > -in the parser, parenthesized patterns and expressions need to be > disambiguated when parsing case labels. > -Lower has been enhanced to handle `case null` for ordinary (boxed-primitive, > String, enum) switches. This is a bit tricky for boxed primitives, as there > is no value that is not part of the input domain so that could be used to > represent `case null`. Requires a bit shuffling with values. > -TransPatterns has been enhanced to handle the pattern matching switch. It > produces code that delegates to a new bootstrap method, that will classify > the input value to the switch and return the case number, to which the switch > then jumps. To support guards, the switches (and the bootstrap method) are > restartable. The bootstrap method as such is written very simply so far, but > could be much more optimized later. > -nullable type patterns are `case String s, null`/`case null, String s`/`case > null: case String s:`/`case String s: case null:`, handling of these required > a few tricks in `Attr`, `Flow` and `TransPatterns`. > > The specdiff for the change is here (to be updated): > http://cr.openjdk.java.net/~jlahoda/8265981/specdiff.preview.01/overview-summary.html src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 127: > 125: Stream.of(labels).forEach(SwitchBootstraps::verifyLabel); > 126: > 127: return new TypeSwitchCallSite(invocationType, labels); See why below MethodHandle target = MethodHandles.insertArguments(DO_SWITCH, 2, labels); return new ConstantCallsite(target); src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 134: > 132: throw new IllegalArgumentException("null label found"); > 133: } > 134: if (label.getClass() != Class.class && store `label.getClass` in a local variable, it's too bad that you can no use pattern matching here :) src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 141: > 139: } > 140: > 141: static class TypeSwitchCallSite extends ConstantCallSite { That's weird, having a callsite extending MutableCallSite is expected but having a callsite extending constant callsite is useless because you can not change it after being constructed. As an interesting trivia, the VM does not store the CallSite returned by the BSM, but only the target inside it. So there is no point of keeping a ConstantCallSite around. So `doSwitch()` should be static and takes the array of Object[] as parameter, will array will be injected with an insertArguments(). src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 157: > 155: Class<?> targetClass = target.getClass(); > 156: for (int i = startIndex; i < labels.length; i++) { > 157: if (labels[i] instanceof Class<?>) { label[i] should be stored is a local variable and using `instanceof Class<?> c` (like the other instanceof below) will make the code more readable ------------- PR: https://git.openjdk.java.net/jdk/pull/3863