RFR: 8300543 Compiler Implementation for Pattern Matching for switch
Maurizio Cimadamore
mcimadamore at openjdk.org
Mon Apr 17 12:04:48 UTC 2023
On Fri, 17 Mar 2023 12:15:58 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:
> This is the first draft of a patch for JEP 440 and JEP 441. Changes included:
>
> - the pattern matching for switch and record patterns features are made final, together with updates to tests.
> - parenthesized patterns are removed.
> - qualified enum constants are supported for case labels.
>
> This change herein also includes removal record patterns in for each loop, which may be split into a separate PR in the future.
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 879:
> 877: }
> 878: case TYPEVAR -> components(((TypeVar) seltype).getUpperBound());
> 879: default -> {
The block here is redundant
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 890:
> 888: * for the sealed supertype.
> 889: */
> 890: private List<PatternDescription> reduceBindingPatterns(Type selectorType, List<PatternDescription> patterns) {
This method doesn't seem to work for the following case:
class Test {
sealed interface I permits A, B, C { }
sealed interface I3 permits I2 { }
sealed interface I2 extends I3 permits B, C { }
final class A implements I {}
final class B implements I, I2 {}
final class C implements I, I2 {}
int m(I i) {
return switch (i) {
case A a -> 1;
case I3 e -> 2;
};
}
}
There seems to be some ordering issue in the way we visit the patterns.
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 901:
> 899: Type clazzErasure = types.erasure(clazz.type);
> 900: if (components(selectorType).stream()
> 901: .map(c -> types.erasure(c))
Suggestion:
.map(Types::erasure)
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 914:
> 912: permitted.remove(bpOne.type.tsym);
> 913: bindings.append(it1.head);
> 914: for (var it2 = it1.tail; it2.nonEmpty(); it2 = it2.tail) {
This could be a for-each loop?
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 971:
> 969: /* implementation note:
> 970: * finding a sub-set of patterns that only differ in a single
> 971: * column is time consuming task, so this method speeds it up by:
Suggestion:
* column is time-consuming task, so this method speeds it up by:
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 974:
> 972: * - group the patterns by their record class
> 973: * - for each column (nested pattern) do:
> 974: * -- group patterns by their hashs
Suggestion:
* -- group patterns by their hash
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 976:
> 974: * -- group patterns by their hashs
> 975: * -- in each such by-hash group, find sub-sets that only differ in
> 976: * the chosen column, and tcall reduceBindingPatterns and reduceNestedPatterns
Suggestion:
* the chosen column, and call reduceBindingPatterns and reduceNestedPatterns
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 977:
> 975: * -- in each such by-hash group, find sub-sets that only differ in
> 976: * the chosen column, and tcall reduceBindingPatterns and reduceNestedPatterns
> 977: * on patterns in the chosed column, as described above
Suggestion:
* on patterns in the chosen column, as described above
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 999:
> 997: .collect(groupingBy(pd -> pd.hashCode(mismatchingCandidateFin)));
> 998: for (var candidates : groupByHashes.values()) {
> 999: var candidatesArr = candidates.toArray(s -> new RecordPattern[s]);
Could this be an array constructor reference? E.g. `RecordPattern[]::new` ?
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 1077:
> 1075: */
> 1076: private List<PatternDescription> reduceRecordPatterns(List<PatternDescription> patterns) {
> 1077: var newList = new ListBuffer<PatternDescription>();
Maybe `newPatterns` would be a better name?
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 1079:
> 1077: var newList = new ListBuffer<PatternDescription>();
> 1078: boolean modified = false;
> 1079: for (var it = patterns; it.nonEmpty(); it = it.tail) {
for-each loop here?
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 1081:
> 1079: for (var it = patterns; it.nonEmpty(); it = it.tail) {
> 1080: if (it.head instanceof RecordPattern rpOne) {
> 1081: PatternDescription nue = reduceRecordPattern(rpOne);
I find the name `nue` (here and elsewhere) particularly obscure.
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 1084:
> 1082: if (nue != rpOne) {
> 1083: newList.append(nue);
> 1084: modified |= true;
Suggestion:
modified = true;
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168552492
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168546493
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168560655
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168560880
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168551434
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168551577
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168551859
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168552121
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168553071
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168556508
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168557288
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168554679
PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1168554833
More information about the core-libs-dev
mailing list