Skip to content

Add support for match-all patterns#4867

Merged
jlerbsc merged 11 commits intojavaparser:masterfrom
johannescoetzee:johannes/unnamed-vars-patterns
Oct 9, 2025
Merged

Add support for match-all patterns#4867
jlerbsc merged 11 commits intojavaparser:masterfrom
johannescoetzee:johannes/unnamed-vars-patterns

Conversation

@johannescoetzee
Copy link
Copy Markdown
Collaborator

Resolves #4713

This PR mainly introduces support for match-all patterns, but does contain a small change to the grammar involving identifiers which was required to disambiguate match-all pattern parsing.

Major changes

MatchAllPatternExpr added

The main point of this PR is to add support for MatchAllPatternExprs. This includes a grammar change in java.jj, a new node type, and support in the ConcreteSyntaxModel. I initially went back-and-forth on the naming, but settled for MatchAllPatternExpr in the end since this is consistent with the JLS and is a good description of what it actually is. The other option was UnnamedPatternExpr, as it is often referred to in text, but in my opinion this could easily be confused with an unnamed pattern variable which is actually contained in a TypePatternExpr, e.g. String _.

While the actual MatchAllPatternExpr class and syntax are very simple, fairly large changes to the pattern type hierarchy are required. Previously, the assumption was made that (1) all patterns can be used as top-level patterns in instanceof expressions and switch entry labels, and (2) all pattern expressions have a type. While this was true for TypePatternExpr and RecordPatternExpr, this no longer holds, leading to the next major change.

Pattern type hierarchy changed

To account for the fact that not all patterns can be used as top-level patterns and not all patterns are typed, a new abstract base class ComponentPatternExpr is introduced. Following the structure in the updated Java syntax, a ComponentPatternExpr can be either a MatchAllPatternExpr, or a PatternExpr. PatternExpr remains unchanged from before and can still be a TypePatternExpr or a RecordPatternExpr.

For reference, the updated syntax is:

Pattern:
  TypePattern
  RecordPattern

TypePattern:
  LocalVariableDeclaration

RecordPattern:
  ReferenceType ( [ComponentPatternList] )

ComponentPatternList:
  ComponentPattern {, ComponentPattern }

ComponentPattern:
  Pattern
  MatchAllPattern

MatchAllPattern:
  _

Java 22 validator added

I've added a Java 22 validator class with 2 new validators: a check to ensure that match-all patterns aren't used as top-level patterns and a check to ensure that unnamed variables are only used where allowed by JEP456. The logic is quite particular, so I've added tests for all of the cases mentioned in JEP456 that should serve as decent documentation.

Other notes

Grammar change for identifiers

I had to make a change to the IDENTIFIER token to get MatchAllPatternExpr to parse correctly. The IDENTIFIER token now excludes the identifier _. It must either be an underscore followed by a non-zero number of characters, or a non-underscore character followed by zero or more other characters. In order to continue parsing Java <= 8 code where _ is an allowed identifier, I added "_" as an explicit case in the Identifier production, similar to other keywords. This disambiguates parsing for MatchAllPatternExpr without affecting identifier parsing.

Note on testing

I've added tests for everything I could think of that should be affected by this change. This includes the IfStatmentContextTests and SwitchEntryContextTests. Some of the tests added in these suites aren't for examples that should be affected by the changes here, but there was a gap in testing so I thought it good to add them. If you can think of anything that I missed, please let me know and I'll add tests for that.

Note on commits

The early commits are a bit of a mess since I didn't settle on the current naming scheme/pattern hierarchy until I'd done a significant amount of work. I initially decided to use TypedPatternExpr as the common ancestor for TypePatternExpr and RecordPatternExpr, and PatternExpr as the common ancestor for TypedPatternExpr and MatchAllPatternExpr. I later changed my mind, since TypedPatternExpr and TypePatternExpr were too close together and none of this matched the JLS. At this point it was easier to rename the classes than to redo everything, so apologies for the messy back-and-forth in the commits.

@codecov
Copy link
Copy Markdown

codecov bot commented Oct 9, 2025

Codecov Report

❌ Patch coverage is 52.00000% with 120 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.330%. Comparing base (8267d4b) to head (d1de37b).
⚠️ Report is 29 commits behind head on master.

Files with missing lines Patch % Lines
...ithub/javaparser/ast/expr/MatchAllPatternExpr.java 42.500% 21 Missing and 2 partials ⚠️
...or/language_level_validations/Java22Validator.java 69.047% 6 Missing and 7 partials ⚠️
...ava/com/github/javaparser/ast/expr/Expression.java 23.076% 10 Missing ⚠️
...va/com/github/javaparser/ast/expr/PatternExpr.java 61.111% 6 Missing and 1 partial ⚠️
...om/github/javaparser/ast/visitor/CloneVisitor.java 12.500% 7 Missing ⚠️
...aparser/ast/visitor/GenericListVisitorAdapter.java 0.000% 7 Missing ⚠️
.../javaparser/ast/visitor/GenericVisitorAdapter.java 0.000% 6 Missing ⚠️
...github/javaparser/ast/visitor/ModifierVisitor.java 0.000% 6 Missing ⚠️
...parser/resolution/types/ResolvedReferenceType.java 0.000% 6 Missing ⚠️
...thub/javaparser/ast/expr/ComponentPatternExpr.java 63.636% 4 Missing ⚠️
... and 16 more
Additional details and impacted files

Impacted file tree graph

@@               Coverage Diff               @@
##              master     #4867       +/-   ##
===============================================
- Coverage     58.354%   58.330%   -0.024%     
- Complexity      2532      2535        +3     
===============================================
  Files            671       677        +6     
  Lines          38861     39038      +177     
  Branches        7064      7088       +24     
===============================================
+ Hits           22677     22771       +94     
- Misses         13293     13368       +75     
- Partials        2891      2899        +8     
Flag Coverage Δ
AlsoSlowTests 58.330% <52.000%> (-0.024%) ⬇️
javaparser-core 58.330% <52.000%> (-0.024%) ⬇️
javaparser-symbol-solver 58.330% <52.000%> (-0.024%) ⬇️
jdk-10 57.894% <52.000%> (-0.022%) ⬇️
jdk-11 57.893% <52.000%> (-0.022%) ⬇️
jdk-12 57.893% <52.000%> (-0.022%) ⬇️
jdk-13 57.893% <52.000%> (-0.022%) ⬇️
jdk-14 58.129% <52.000%> (-0.023%) ⬇️
jdk-15 58.132% <52.000%> (-0.023%) ⬇️
jdk-16 58.106% <52.000%> (-0.023%) ⬇️
jdk-17 58.260% <52.000%> (-0.024%) ⬇️
jdk-18 58.260% <52.000%> (-0.024%) ⬇️
jdk-8 57.891% <52.000%> (-0.024%) ⬇️
jdk-9 57.892% <52.000%> (-0.022%) ⬇️
macos-latest 58.322% <52.000%> (-0.024%) ⬇️
ubuntu-latest 58.317% <52.000%> (-0.024%) ⬇️
windows-latest 58.312% <52.000%> (-0.024%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...n/java/com/github/javaparser/CommentsInserter.java 88.888% <100.000%> (ø)
...src/main/java/com/github/javaparser/JavaToken.java 92.444% <100.000%> (+0.033%) ⬆️
...ava/com/github/javaparser/ParserConfiguration.java 87.162% <100.000%> (+0.087%) ⬆️
...rc/main/java/com/github/javaparser/TokenTypes.java 84.615% <ø> (ø)
.../github/javaparser/ast/expr/RecordPatternExpr.java 68.333% <100.000%> (+1.666%) ⬆️
...b/javaparser/ast/nodeTypes/NodeWithParameters.java 94.444% <100.000%> (+0.158%) ⬆️
.../validator/postprocessors/Java22PostProcessor.java 100.000% <100.000%> (ø)
...hub/javaparser/ast/visitor/VoidVisitorAdapter.java 99.061% <100.000%> (+0.006%) ⬆️
...arser/metamodel/ComponentPatternExprMetaModel.java 100.000% <100.000%> (ø)
...thub/javaparser/metamodel/JavaParserMetaModel.java 99.705% <100.000%> (+0.002%) ⬆️
... and 35 more

... and 2 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 16f5220...d1de37b. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@johannescoetzee
Copy link
Copy Markdown
Collaborator Author

It looks like the codecov misses are just in the generated boilerplate code. If this is an issue, let me know and I'll add tests targeting this specifically.

@jlerbsc
Copy link
Copy Markdown
Collaborator

jlerbsc commented Oct 9, 2025

It's excellent work. It is indeed difficult to keep track of the changes, but overall it seems correct to me.

@jlerbsc jlerbsc merged commit ae0ee3b into javaparser:master Oct 9, 2025
34 of 35 checks passed
@jlerbsc jlerbsc added this to the next release milestone Oct 9, 2025
@jlerbsc jlerbsc added the PR: Added A PR that introduces new behaviour (e.g. functionality, tests) label Oct 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: Added A PR that introduces new behaviour (e.g. functionality, tests)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anonymous Variables and Patterns

2 participants