[JEP441] Add support for switch pattern matching#4375
[JEP441] Add support for switch pattern matching#4375jlerbsc merged 7 commits intojavaparser:masterfrom
Conversation
|
|
||
| String serialized = serialize(cu, false); | ||
|
|
||
| assertEquals("{\"!\":\"com.github.javaparser.ast.CompilationUnit\",\"range\":{\"beginLine\":1,\"beginColumn\":1,\"endLine\":1,\"endColumn\":23},\"tokenRange\":{\"beginToken\":{\"kind\":19,\"text\":\"class\"},\"endToken\":{\"kind\":0,\"text\":\"\"}},\"imports\":[],\"types\":[{\"!\":\"com.github.javaparser.ast.body.ClassOrInterfaceDeclaration\",\"range\":{\"beginLine\":1,\"beginColumn\":1,\"endLine\":1,\"endColumn\":23},\"tokenRange\":{\"beginToken\":{\"kind\":19,\"text\":\"class\"},\"endToken\":{\"kind\":103,\"text\":\"}\"}},\"extendedTypes\":[],\"implementedTypes\":[],\"isInterface\":\"false\",\"permittedTypes\":[],\"typeParameters\":[],\"members\":[{\"!\":\"com.github.javaparser.ast.body.FieldDeclaration\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":22},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":106,\"text\":\";\"}},\"modifiers\":[],\"variables\":[{\"!\":\"com.github.javaparser.ast.body.VariableDeclarator\",\"range\":{\"beginLine\":1,\"beginColumn\":21,\"endLine\":1,\"endColumn\":21},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"y\"},\"endToken\":{\"kind\":97,\"text\":\"y\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":21,\"endLine\":1,\"endColumn\":21},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"y\"},\"endToken\":{\"kind\":97,\"text\":\"y\"}},\"identifier\":\"y\"},\"type\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":19},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":97,\"text\":\"Y\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":19,\"endLine\":1,\"endColumn\":19},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"Y\"},\"endToken\":{\"kind\":97,\"text\":\"Y\"}},\"identifier\":\"Y\"},\"scope\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":17},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":97,\"text\":\"util\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":14,\"endLine\":1,\"endColumn\":17},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"util\"},\"endToken\":{\"kind\":97,\"text\":\"util\"}},\"identifier\":\"util\"},\"scope\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":12},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":97,\"text\":\"java\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":12},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":97,\"text\":\"java\"}},\"identifier\":\"java\"},\"annotations\":[]},\"annotations\":[]},\"annotations\":[]}}],\"annotations\":[]}],\"modifiers\":[],\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":7,\"endLine\":1,\"endColumn\":7},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"X\"},\"endToken\":{\"kind\":97,\"text\":\"X\"}},\"identifier\":\"X\"},\"annotations\":[]}]}", serialized); |
There was a problem hiding this comment.
The changes here are just some token kind values which changed due to the addition of the WHEN token
| EXPORTS(76), | ||
| PROVIDES(77), | ||
| TRANSITIVE(78), | ||
| LONG_LITERAL(79), |
There was a problem hiding this comment.
These changes are generated
|
|
||
| public static Kind valueOf(int kind) { | ||
| switch(kind) { | ||
| case 150: |
There was a problem hiding this comment.
These changes are generated
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4375 +/- ##
=============================================
- Coverage 51.929% 51.912% -0.018%
=============================================
Files 503 503
Lines 28369 28442 +73
Branches 4920 4934 +14
=============================================
+ Hits 14732 14765 +33
- Misses 11591 11625 +34
- Partials 2046 2052 +6
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 2 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
|
I just realized I forgot to update the validators. I'll update the PR with that probably this afternoon. |
| if (node == null) { | ||
| return false; | ||
| } | ||
| if (guard != null) { |
There was a problem hiding this comment.
Why this and the counterpart?
Do you have a test case that tests the deletion of a node with a guard expression?
| @Override | ||
| public Visitable visit(final InitializerDeclaration n, final Object arg) { | ||
| BlockStmt body = cloneNode(n.getBody(), arg); | ||
| NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg); |
There was a problem hiding this comment.
How does this relate to the subject of the PR?
| @Override | ||
| public R visit(final SwitchEntry n, final A arg) { | ||
| R result; | ||
| if (n.getGuard().isPresent()) { |
There was a problem hiding this comment.
I don't understand this block!
| concreteSyntaxModelByClass.put(ReturnStmt.class, sequence(comment(), token(GeneratedJavaParserConstants.RETURN), conditional(ObservableProperty.EXPRESSION, IS_PRESENT, sequence(space(), child(ObservableProperty.EXPRESSION))), semicolon())); | ||
| concreteSyntaxModelByClass.put(YieldStmt.class, sequence(comment(), token(YIELD), conditional(ObservableProperty.EXPRESSION, IS_PRESENT, sequence(space(), child(ObservableProperty.EXPRESSION))), semicolon())); | ||
| concreteSyntaxModelByClass.put(SwitchEntry.class, sequence(comment(), conditional(SWITCH_STATEMENT_ENTRY, FLAG, conditional(ObservableProperty.LABELS, IS_NOT_EMPTY, sequence(token(GeneratedJavaParserConstants.CASE), space(), list(ObservableProperty.LABELS), token(GeneratedJavaParserConstants.COLON)), sequence(token(GeneratedJavaParserConstants._DEFAULT), token(GeneratedJavaParserConstants.COLON))), conditional(ObservableProperty.LABELS, IS_NOT_EMPTY, conditional(ObservableProperty.DEFAULT, FLAG, sequence(token(GeneratedJavaParserConstants.CASE), space(), list(ObservableProperty.LABELS), comma(), space(), token(GeneratedJavaParserConstants._DEFAULT), space(), token(GeneratedJavaParserConstants.ARROW)), sequence(token(GeneratedJavaParserConstants.CASE), space(), list(ObservableProperty.LABELS), token(GeneratedJavaParserConstants.ARROW))), sequence(token(GeneratedJavaParserConstants._DEFAULT), space(), token(GeneratedJavaParserConstants.ARROW)))), newline(), indent(), list(ObservableProperty.STATEMENTS, newline(), none(), newline()), unindent())); | ||
| concreteSyntaxModelByClass.put(SwitchEntry.class, sequence(comment(), conditional(SWITCH_STATEMENT_ENTRY, FLAG, conditional(ObservableProperty.LABELS, IS_NOT_EMPTY, sequence(token(GeneratedJavaParserConstants.CASE), space(), list(ObservableProperty.LABELS), token(GeneratedJavaParserConstants.COLON)), sequence(token(GeneratedJavaParserConstants._DEFAULT), token(GeneratedJavaParserConstants.COLON))), conditional(ObservableProperty.LABELS, IS_NOT_EMPTY, conditional(ObservableProperty.DEFAULT, FLAG, sequence(token(GeneratedJavaParserConstants.CASE), space(), list(ObservableProperty.LABELS), comma(), space(), token(GeneratedJavaParserConstants._DEFAULT), space(), token(GeneratedJavaParserConstants.ARROW)), sequence(token(GeneratedJavaParserConstants.CASE), space(), list(ObservableProperty.LABELS), conditional(ObservableProperty.GUARDED_ENTRY, FLAG, sequence(space(), token(GeneratedJavaParserConstants.WHEN), space(), child(ObservableProperty.GUARD))), space(), token(GeneratedJavaParserConstants.ARROW))), sequence(token(GeneratedJavaParserConstants._DEFAULT), space(), token(GeneratedJavaParserConstants.ARROW)))), newline(), indent(), list(ObservableProperty.STATEMENTS, newline(), none(), newline()), unindent())); |
There was a problem hiding this comment.
I'm not sure that the GUARDED_ENTRY property is necessary. Can't we just use the GUARD property?
| * be expected or not. | ||
| */ | ||
| @DerivedProperty | ||
| public boolean isGuardedEntry() { |
There was a problem hiding this comment.
I'm not sure that the GUARDED_ENTRY property is necessary. Can't we just use the GUARD property?
|
Great work. I've got a few questions, but it seems fine to me, with the possible exception of the derived property introduced for the Lexical Preserving Printer. |
|
I've updated this PR with the following:
|
|
A job well done. Thanks for your time. |
|
This looks great and should resolve an issue we are facing with javaparser! Do you have any estimate as of when this will be released? 🙏 |
|
This will be integrated into the next release, which will provide support for all Java 21 non-preview features |
Switch pattern matching changes introduced in https://openjdk.org/jeps/441
This PR adds support for switch pattern matching with guards and resolves #4343 using the approach discussed in #4361 and partially implemented in #4357.
In particular, it adds support for the new
CasePattern [Guard]syntax inThe main changes in this PR are:
SwitchEntry.guardfield which contains the guard expression if any