-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[JEP441] Add support for switch pattern matching #4375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JEP441] Add support for switch pattern matching #4375
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes are generated
|
||
public static Kind valueOf(int kind) { | ||
switch(kind) { | ||
case 150: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.guard
field which contains the guard expression if any