Skip to content

Commit

Permalink
Issue checkstyle#13988: Support unnamed variables
Browse files Browse the repository at this point in the history
  • Loading branch information
nrmancuso committed Feb 4, 2024
1 parent 680e6b8 commit a645157
Show file tree
Hide file tree
Showing 13 changed files with 2,141 additions and 16 deletions.
6 changes: 0 additions & 6 deletions config/projects-to-test/openjdk21-excluded.files
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@
<property name="fileNamePattern" value="[\\/]test[\\/]langtools[\\/]tools[\\/]javac[\\/]unnamedclass[\\/]NestedEnum.java$"/>
</module>

<!-- until https://github.com/checkstyle/checkstyle/issues/13988 -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="[\\/]test[\\/]langtools[\\/]tools[\\/]javac[\\/]patterns[\\/]Unnamed.java$"/>
</module>


<!-- non-compilable -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="[\\/]test[\\/]langtools[\\/]tools[\\/]javac[\\/]diags[\\/]examples[\\/]UnnamedClassNoMain.java$"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2239,8 +2239,8 @@ public DetailAstImpl visitRecordPatternDef(JavaLanguageParser.RecordPatternDefCo
}

@Override
public DetailAstImpl visitTypePattern(
JavaLanguageParser.TypePatternContext ctx) {
public DetailAstImpl visitTypePatternDef(
JavaLanguageParser.TypePatternDefContext ctx) {
final DetailAstImpl type = visit(ctx.type);
final DetailAstImpl patternVariableDef = createImaginary(TokenTypes.PATTERN_VARIABLE_DEF);
patternVariableDef.addChild(createModifiers(ctx.mods));
Expand All @@ -2249,6 +2249,11 @@ public DetailAstImpl visitTypePattern(
return patternVariableDef;
}

@Override
public DetailAstImpl visitUnnamedPatternDef(JavaLanguageParser.UnnamedPatternDefContext ctx) {
return create(TokenTypes.UNNAMED_PATTERN_DEF, ctx.start);
}

@Override
public DetailAstImpl visitRecordPattern(JavaLanguageParser.RecordPatternContext ctx) {
final DetailAstImpl recordPattern = createImaginary(TokenTypes.RECORD_PATTERN_DEF);
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/com/puppycrawl/tools/checkstyle/api/TokenTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -6743,6 +6743,46 @@ public final class TokenTypes {
public static final int EMBEDDED_EXPRESSION_END =
JavaLanguageLexer.EMBEDDED_EXPRESSION_END;

/**
* An unnamed pattern variable definition. Appears as part of a pattern definition.
* <p>For example:</p>
* <pre>
* if (r instanceof R(_)) {}
* </pre>
* <p>parses as:</p>
* <pre>
* LITERAL_IF -&gt; if
* |--LPAREN -&gt; (
* |--EXPR -&gt; EXPR
* | `--LITERAL_INSTANCEOF -&gt; instanceof
* | |--IDENT -&gt; r
* | `--RECORD_PATTERN_DEF -&gt; RECORD_PATTERN_DEF
* | |--MODIFIERS -&gt; MODIFIERS
* | |--TYPE -&gt; TYPE
* | | `--IDENT -&gt; R
* | |--LPAREN -&gt; (
* | |--RECORD_PATTERN_COMPONENTS -&gt; RECORD_PATTERN_COMPONENTS
* | | `--UNNAMED_PATTERN_DEF -&gt; _
* | `--RPAREN -&gt; )
* |--RPAREN -&gt; )
* `--SLIST -&gt; {
* `--RCURLY -&gt; }
* </pre>
*
* @see #RECORD_PATTERN_COMPONENTS
* @see #RECORD_PATTERN_DEF
* @see #LITERAL_SWITCH
* @see #LITERAL_INSTANCEOF
* @see #SWITCH_RULE
* @see #LITERAL_WHEN
* @see #PATTERN_VARIABLE_DEF
* @see #PATTERN_DEF
*
* @since 10.14.0
*/
public static final int UNNAMED_PATTERN_DEF =
JavaLanguageLexer.UNNAMED_PATTERN_DEF;

/** Prevent instantiation. */
private TokenTypes() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ tokens {
STRING_TEMPLATE_BEGIN, STRING_TEMPLATE_MID, STRING_TEMPLATE_END,
STRING_TEMPLATE_CONTENT, EMBEDDED_EXPRESSION_BEGIN, EMBEDDED_EXPRESSION,
EMBEDDED_EXPRESSION_END
EMBEDDED_EXPRESSION_END,
LITERAL_UNDERSCORE, UNNAMED_PATTERN_DEF
}

@header {
Expand Down Expand Up @@ -213,6 +215,7 @@ LITERAL_NON_SEALED: 'non-sealed';
LITERAL_SEALED: 'sealed';
LITERAL_PERMITS: 'permits';
LITERAL_WHEN: 'when';
LITERAL_UNDERSCORE: '_';

// Literals
DECIMAL_LITERAL_LONG: ('0' | [1-9] (Digits? | '_'+ Digits)) [lL];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,8 @@ primaryPattern
;

typePattern
: mods+=modifier* type=typeType[true] id
: mods+=modifier* type=typeType[true] id #typePatternDef
| LITERAL_UNDERSCORE #unnamedPatternDef
;

recordPattern
Expand All @@ -929,7 +930,8 @@ permittedSubclassesAndInterfaces
;

// Handle the 'keyword as identifier' problem
id : LITERAL_RECORD
id: LITERAL_UNDERSCORE
| LITERAL_RECORD
| LITERAL_YIELD
| LITERAL_NON_SEALED
| LITERAL_SEALED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public void testOrderOfProperties() {

@Test
public void testAcceptableTokensMakeSense() {
final int expectedTokenTypesTotalNumber = 194;
final int expectedTokenTypesTotalNumber = 195;
assertWithMessage("Total number of TokenTypes has changed, acceptable tokens in"
+ " IllegalTokenTextCheck need to be reconsidered.")
.that(TokenUtil.getTokenTypesTotalNumber())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,12 @@ public void testTokenNumbering() {
assertWithMessage(message)
.that(JavaLanguageLexer.EMBEDDED_EXPRESSION_END)
.isEqualTo(223);
assertWithMessage(message)
.that(JavaLanguageLexer.LITERAL_UNDERSCORE)
.isEqualTo(224);
assertWithMessage(message)
.that(JavaLanguageLexer.UNNAMED_PATTERN_DEF)
.isEqualTo(225);

final int tokenCount = (int) Arrays.stream(JavaLanguageLexer.class.getDeclaredFields())
.filter(GeneratedJavaTokenTypesTest::isPublicStaticFinalInt)
Expand All @@ -746,7 +752,7 @@ public void testTokenNumbering() {
+ " 'GeneratedJavaTokenTypesTest' and verified"
+ " that their old numbering didn't change")
.that(tokenCount)
.isEqualTo(235);
.isEqualTo(237);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,22 @@ public void testBasicStringTemplateWithTabs() throws Exception {
"InputStringTemplateBasicWithTabs.java"));
}

@Test
public void testUnnamedVariableBasic() throws Exception {
verifyAst(
getNonCompilablePath(
"ExpectedUnnamedVariableBasic.txt"),
getNonCompilablePath(
"InputUnnamedVariableBasic.java"));
}

@Test
public void testUnnamedVariableSwitch() throws Exception {
verifyAst(
getNonCompilablePath(
"ExpectedUnnamedVariableSwitch.txt"),
getNonCompilablePath(
"InputUnnamedVariableSwitch.java"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ public void testGetTokenTypesTotalNumber() {

assertWithMessage("Invalid token total number")
.that(tokenTypesTotalNumber)
.isEqualTo(194);
.isEqualTo(195);
}

@Test
Expand All @@ -238,10 +238,10 @@ public void testGetAllTokenIds() {

assertWithMessage("Invalid token length")
.that(allTokenIds.length)
.isEqualTo(194);
.isEqualTo(195);
assertWithMessage("invalid sum")
.that(sum)
.isEqualTo(20917);
.isEqualTo(21142);
}

@Test
Expand Down
Loading

0 comments on commit a645157

Please sign in to comment.