[java] Add ugly lookahead for local record declarations

so that it can be distinguished from local var decl or other
statements.
This commit is contained in:
Andreas Dangel
2020-08-14 20:56:26 +02:00
parent 4d2853ccc4
commit cda155891a
3 changed files with 29 additions and 3 deletions

View File

@ -478,6 +478,21 @@ public class JavaParser {
return (jdkVersion == 14 || jdkVersion == 15) && preview;
}
private boolean isRecordDeclarationAhead() {
int amount = 1;
while (amount < 10) {
Token next = getToken(amount);
if (next.kind == IDENTIFIER && "record".equals(next.image)) {
return true;
}
// stop looking ahead at "=" or ";" or "{"
if (next.kind == ASSIGN || next.kind == LBRACE || next.kind == SEMICOLON) {
return false;
}
amount++;
}
return false;
}
// This is a semantic LOOKAHEAD to determine if we're dealing with an assert
// Note that this can't be replaced with a syntactic lookahead
@ -1886,10 +1901,10 @@ void BlockStatement():
LOOKAHEAD( { isNextTokenAnAssert() } ) AssertStatement()
| LOOKAHEAD( { isYieldStart() } ) YieldStatement()
|
LOOKAHEAD(2147483647, ( "final" | Annotation() )* Type() <IDENTIFIER>, {isRecordTypeSupported() && !isKeyword("record") || !isRecordTypeSupported()})
LOOKAHEAD(2147483647, ( "final" | Annotation() )* Type() <IDENTIFIER>, {isRecordTypeSupported() && !isRecordDeclarationAhead() || !isRecordTypeSupported()})
LocalVariableDeclaration() ";"
|
LOOKAHEAD({isRecordTypeSupported() && !isKeyword("record") || !isRecordTypeSupported()})
LOOKAHEAD(1, {isRecordTypeSupported() && !isRecordDeclarationAhead() || !isRecordTypeSupported()})
Statement()
|
// we don't need to lookahead further here

View File

@ -160,7 +160,7 @@ public class Java15PreviewTest {
public void localRecords() {
ASTCompilationUnit compilationUnit = java15p.parseResource("LocalRecords.java");
List<ASTRecordDeclaration> records = compilationUnit.findDescendantsOfType(ASTRecordDeclaration.class);
Assert.assertEquals(1, records.size());
Assert.assertEquals(5, records.size());
Assert.assertEquals("MerchantSales", records.get(0).getSimpleName());
Assert.assertTrue(records.get(0).isLocal());
}

View File

@ -23,4 +23,15 @@ public class LocalRecords {
.map(MerchantSales::merchant)
.collect(Collectors.toList());
}
void methodWithLocalRecordAndModifiers() {
final record MyRecord1(String a) {}
final static record MyRecord2(String a) {}
@Deprecated record MyRecord3(String a) {}
final @Deprecated static record MyRecord4(String a) {}
}
void methodWithLocalClass() {
class MyLocalClass {}
}
}