Skip to content

Commit

Permalink
[Sealed Types] Permits clause handling in scanner and parser is unnec…
Browse files Browse the repository at this point in the history
…essarily complicated (#2653)

* Fixes #2652
  • Loading branch information
srikanth-sankaran authored Jul 2, 2024
1 parent 0c6b25a commit bf0427a
Show file tree
Hide file tree
Showing 36 changed files with 654 additions and 697 deletions.
37 changes: 9 additions & 28 deletions org.eclipse.jdt.core.compiler.batch/grammar/java.g
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ $Terminals
abstract assert boolean break byte case catch char class
continue const default do double else enum extends false final finally float
for goto if implements import instanceof int
interface long native new non-sealed null package private
interface long native new non-sealed null package permits private
protected public return short static strictfp super switch
synchronized this throw throws transient true try void
volatile while module open requires transitive exports opens to uses provides with
Expand Down Expand Up @@ -120,7 +120,6 @@ $Terminals
RestrictedIdentifierYield
RestrictedIdentifierrecord
RestrictedIdentifiersealed
RestrictedIdentifierpermits
BeginCaseElement
RestrictedIdentifierWhen
UNDERSCORE
Expand Down Expand Up @@ -233,7 +232,6 @@ Goal ::= '->' YieldStatement
Goal ::= '->' SwitchLabelCaseLhs
-- JSR 360 Restricted
Goal ::= RestrictedIdentifiersealed Modifiersopt
Goal ::= RestrictedIdentifierpermits PermittedSubclasses
-- jsr 427 --
Goal ::= BeginCaseElement Pattern
Goal ::= RestrictedIdentifierWhen Expression
Expand Down Expand Up @@ -702,7 +700,7 @@ ClassDeclaration ::= ClassHeader ClassBody
/.$putCase consumeClassDeclaration(); $break ./
/:$readableName ClassDeclaration:/

ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt ClassHeaderPermittedSubclassesopt
ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt PermittedTypesopt
/.$putCase consumeClassHeader(); $break ./
/:$readableName ClassHeader:/

Expand Down Expand Up @@ -1056,7 +1054,7 @@ InterfaceDeclaration ::= InterfaceHeader InterfaceBody
/.$putCase consumeInterfaceDeclaration(); $break ./
/:$readableName InterfaceDeclaration:/

InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt InterfaceHeaderPermittedSubClassesAndSubInterfacesopt
InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt PermittedTypesopt
/.$putCase consumeInterfaceHeader(); $break ./
/:$readableName InterfaceHeader:/

Expand Down Expand Up @@ -2412,29 +2410,11 @@ ClassHeaderImplementsopt ::= $empty
ClassHeaderImplementsopt -> ClassHeaderImplements
/:$readableName ClassHeaderImplements:/

ClassHeaderPermittedSubclassesopt ::= $empty
ClassHeaderPermittedSubclassesopt -> ClassHeaderPermittedSubclasses
/:$readableName ClassHeaderPermittedSubclasses:/
/:$compliance 15:/

-- Production name hardcoded in parser. Must be ::= and not ->
PermittedSubclasses ::= ClassTypeList
/:$readableName PermittedSubclasses:/

ClassHeaderPermittedSubclasses ::= RestrictedIdentifierpermits ClassTypeList
/.$putCase consumeClassHeaderPermittedSubclasses(); $break ./
/:$readableName ClassHeaderPermittedSubclasses:/
/:$compliance 15:/

InterfaceHeaderPermittedSubClassesAndSubInterfacesopt ::= $empty
InterfaceHeaderPermittedSubClassesAndSubInterfacesopt -> InterfaceHeaderPermittedSubClassesAndSubInterfaces
/:$readableName InterfaceHeaderPermittedSubClassesAndSubInterfaces:/
/:$compliance 15:/

InterfaceHeaderPermittedSubClassesAndSubInterfaces ::= RestrictedIdentifierpermits ClassTypeList
/.$putCase consumeInterfaceHeaderPermittedSubClassesAndSubInterfaces(); $break ./
/:$readableName InterfaceHeaderPermittedSubClassesAndSubInterfaces:/
/:$compliance 15:/
PermittedTypesopt -> $empty
PermittedTypesopt ::= 'permits' ClassTypeList
/.$putCase consumePermittedTypes(); $break ./
/:$readableName PermittedTypes:/
/:$compliance 17:/

InterfaceMemberDeclarationsopt ::= $empty
/. $putCase consumeEmptyInterfaceMemberDeclarationsopt(); $break ./
Expand Down Expand Up @@ -3220,3 +3200,4 @@ UNDERSCORE ::= '_'
$end
-- need a carriage return after the $end


Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ protected Object parseQualifiedName(boolean reset, boolean allowModule) throws I
case TerminalTokens.TokenNamenon_sealed:
case TerminalTokens.TokenNamenull:
case TerminalTokens.TokenNamepackage:
case TerminalTokens.TokenNameRestrictedIdentifierpermits:
case TerminalTokens.TokenNamepermits:
case TerminalTokens.TokenNameprivate:
case TerminalTokens.TokenNameprotected:
case TerminalTokens.TokenNamepublic:
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ public interface ParserBasicInformation {
// BEGIN_AUTOGENERATED_REGION

ERROR_SYMBOL = 140,
MAX_NAME_LENGTH = 53,
NUM_STATES = 1262,
MAX_NAME_LENGTH = 41,
NUM_STATES = 1257,

NT_OFFSET = 140,
SCOPE_UBOUND = 321,
SCOPE_SIZE = 322,
LA_STATE_OFFSET = 18370,
LA_STATE_OFFSET = 18382,
MAX_LA = 1,
NUM_RULES = 956,
NUM_RULES = 950,
NUM_TERMINALS = 140,
NUM_NON_TERMINALS = 440,
NUM_SYMBOLS = 580,
START_STATE = 1508,
EOFT_SYMBOL = 38,
EOLT_SYMBOL = 38,
ACCEPT_ACTION = 18369,
ERROR_ACTION = 18370;
NUM_NON_TERMINALS = 436,
NUM_SYMBOLS = 576,
START_STATE = 1355,
EOFT_SYMBOL = 39,
EOLT_SYMBOL = 39,
ACCEPT_ACTION = 18381,
ERROR_ACTION = 18382;
}
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
case -1 :
case TokenNameextends :
case TokenNameimplements :
case TokenNameRestrictedIdentifierpermits:
case TokenNamepermits:
case TokenNameGREATER :
case TokenNameRIGHT_SHIFT :
case TokenNameUNSIGNED_RIGHT_SHIFT :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3514,7 +3514,7 @@ else if ((data[index] == 'o')
&& (data[++index] == 'i')
&& (data[++index] == 't')
&& (data[++index] == 's')) {
return disambiguatedRestrictedIdentifierpermits(TokenNameRestrictedIdentifierpermits);
return disambiguatedToken(TokenNamepermits, this);
} else
return TokenNameIdentifier;
}
Expand Down Expand Up @@ -4285,7 +4285,7 @@ public String toStringAction(int act) {
return "null"; //$NON-NLS-1$
case TokenNamepackage :
return "package"; //$NON-NLS-1$
case TokenNameRestrictedIdentifierpermits:
case TokenNamepermits:
return "permits"; //$NON-NLS-1$
case TokenNameprivate :
return "private"; //$NON-NLS-1$
Expand Down Expand Up @@ -4554,7 +4554,7 @@ public static boolean isKeyword(int token) {
case TerminalTokens.TokenNameRestrictedIdentifierYield:
case TerminalTokens.TokenNameRestrictedIdentifierrecord:
case TerminalTokens.TokenNameRestrictedIdentifiersealed:
case TerminalTokens.TokenNameRestrictedIdentifierpermits:
case TerminalTokens.TokenNamepermits:
case TerminalTokens.TokenNameRestrictedIdentifierWhen:
// making explicit - not a (restricted) keyword but restricted identifier.
//$FALL-THROUGH$
Expand Down Expand Up @@ -4624,7 +4624,6 @@ private static class Goal {
static int YieldStatementRule = 0;
static int SwitchLabelCaseLhsRule = 0;
static int[] RestrictedIdentifierSealedRule;
static int[] RestrictedIdentifierPermitsRule;
static int[] PatternRules;

static Goal LambdaParameterListGoal;
Expand All @@ -4635,18 +4634,15 @@ private static class Goal {
static Goal YieldStatementGoal;
static Goal SwitchLabelCaseLhsGoal;
static Goal RestrictedIdentifierSealedGoal;
static Goal RestrictedIdentifierPermitsGoal;
static Goal PatternGoal;

static int[] RestrictedIdentifierSealedFollow = { TokenNameclass, TokenNameinterface,
TokenNameenum, TokenNameRestrictedIdentifierrecord };// Note: enum/record allowed as error flagging rules.
static int[] RestrictedIdentifierPermitsFollow = { TokenNameLBRACE };
static int[] PatternCaseLabelFollow = {TokenNameCOLON, TokenNameARROW, TokenNameCOMMA, TokenNameBeginCaseExpr, TokenNameRestrictedIdentifierWhen};

static {

List<Integer> ridSealed = new ArrayList<>(2);
List<Integer> ridPermits = new ArrayList<>();
List<Integer> patternStates = new ArrayList<>();
for (int i = 1; i <= ParserBasicInformation.NUM_RULES; i++) { // 0 == $acc
// TODO: Change to switch
Expand All @@ -4671,9 +4667,6 @@ private static class Goal {
if ("Modifiersopt".equals(Parser.name[Parser.non_terminal_index[Parser.lhs[i]]])) //$NON-NLS-1$
ridSealed.add(i);
else
if ("PermittedSubclasses".equals(Parser.name[Parser.non_terminal_index[Parser.lhs[i]]])) //$NON-NLS-1$
ridPermits.add(i);
else
if ("SwitchLabelCaseLhs".equals(Parser.name[Parser.non_terminal_index[Parser.lhs[i]]])) //$NON-NLS-1$
SwitchLabelCaseLhsRule = i;
else
Expand All @@ -4690,7 +4683,6 @@ private static class Goal {
patternStates.add(i);
}
RestrictedIdentifierSealedRule = ridSealed.stream().mapToInt(Integer :: intValue).toArray(); // overkill but future-proof
RestrictedIdentifierPermitsRule = ridPermits.stream().mapToInt(Integer :: intValue).toArray();
PatternRules = patternStates.stream().mapToInt(Integer :: intValue).toArray();

LambdaParameterListGoal = new Goal(TokenNameARROW, new int[] { TokenNameARROW }, LambdaParameterListRule);
Expand All @@ -4701,7 +4693,6 @@ private static class Goal {
YieldStatementGoal = new Goal(TokenNameARROW, new int [0], YieldStatementRule);
SwitchLabelCaseLhsGoal = new Goal(TokenNameARROW, new int [0], SwitchLabelCaseLhsRule);
RestrictedIdentifierSealedGoal = new Goal(TokenNameRestrictedIdentifiersealed, RestrictedIdentifierSealedFollow, RestrictedIdentifierSealedRule);
RestrictedIdentifierPermitsGoal = new Goal(TokenNameRestrictedIdentifierpermits, RestrictedIdentifierPermitsFollow, RestrictedIdentifierPermitsRule);
PatternGoal = new Goal(TokenNameBeginCaseElement, PatternCaseLabelFollow, PatternRules);
}

Expand Down Expand Up @@ -4961,7 +4952,7 @@ protected final boolean maybeAtReferenceExpression() { // Did the '<' we saw jus
case TokenNamesuper: // ? super Context<N>
case TokenNameAND: // T extends Object & Comparable<? super T>
case TokenNameimplements: // class A implements I<Z>
case TokenNameRestrictedIdentifierpermits: // class A permits I<Z>
case TokenNamepermits: // class A permits I<Z>
case TokenNamethrows: // throws Y<Z>
case TokenNameAT: // @Deprecated <T> void foo() {}
case TokenNameinstanceof: // if (o instanceof List<E>[])
Expand All @@ -4987,7 +4978,7 @@ private final boolean maybeAtEllipsisAnnotationsStart() { // Did the '@' we saw
case TokenNameextends:
case TokenNamesuper:
case TokenNameimplements:
case TokenNameRestrictedIdentifierpermits:
case TokenNamepermits:
case TokenNameDOT:
case TokenNameLBRACE:
case TokenNameinstanceof:
Expand Down Expand Up @@ -5055,7 +5046,7 @@ private boolean mayBeAtASealedRestricedIdentifier(int restrictedIdentifier) {
switch (restrictedIdentifier) {
case TokenNameRestrictedIdentifiersealed:
break;
case TokenNameRestrictedIdentifierpermits:
case TokenNamepermits:
break;
}
return true;
Expand Down Expand Up @@ -5191,20 +5182,7 @@ private boolean disambiguateYieldWithLookAhead() {
}
return false; // IIE event;
}
int disambiguatedRestrictedIdentifierpermits(int restrictedIdentifierToken) {
// and here's the kludge
if (restrictedIdentifierToken != TokenNameRestrictedIdentifierpermits)
return restrictedIdentifierToken;
if (!JavaFeature.RECORDS.isSupported(this.complianceLevel, this.previewEnabled))
return TokenNameIdentifier;

return disambiguatesRestrictedIdentifierWithLookAhead(this::mayBeAtASealedRestricedIdentifier,
restrictedIdentifierToken, Goal.RestrictedIdentifierPermitsGoal);
}
int disambiguatedRestrictedIdentifiersealed(int restrictedIdentifierToken) {
// and here's the kludge
if (restrictedIdentifierToken != TokenNameRestrictedIdentifiersealed)
return restrictedIdentifierToken;
if (!JavaFeature.RECORDS.isSupported(this.complianceLevel, this.previewEnabled))
return TokenNameIdentifier;

Expand Down Expand Up @@ -5289,6 +5267,12 @@ private VanguardParser getNewVanguardParser(char[] src) {
return vp;
}
int disambiguatedToken(int token, Scanner scanner) {
if (token == TokenNamepermits) {
if (scanner.sourceLevel < ClassFileConstants.JDK17)
return TokenNameIdentifier;
return scanner.activeParser == null || !scanner.activeParser.automatonWillShift(TokenNamepermits) ?
TokenNameIdentifier : TokenNamepermits;
}
final VanguardParser parser = getVanguardParser();
parser.scanner.caseStartPosition = this.caseStartPosition;
if (token == TokenNameARROW && mayBeAtCaseLabelExpr() && scanner.caseStartPosition < scanner.startPosition) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public interface TerminalTokens {
static boolean isRestrictedKeyword(int tokenType) {
return switch (tokenType) {
case TokenNameRestrictedIdentifierYield, TokenNameRestrictedIdentifierrecord,TokenNameRestrictedIdentifierWhen,
TokenNameRestrictedIdentifiersealed, TokenNameRestrictedIdentifierpermits -> true;
TokenNameRestrictedIdentifiersealed, TokenNamepermits -> true;
default -> false;
};
}
Expand All @@ -65,7 +65,7 @@ static int getRestrictedKeyword(String text) {
case "record" -> TokenNameRestrictedIdentifierrecord; //$NON-NLS-1$
case "when" -> TokenNameRestrictedIdentifierWhen; //$NON-NLS-1$
case "sealed" -> TokenNameRestrictedIdentifiersealed; //$NON-NLS-1$
case "permits" -> TokenNameRestrictedIdentifierpermits; //$NON-NLS-1$
case "permits" -> TokenNamepermits; //$NON-NLS-1$
default -> TokenNameNotAToken;
};
}
Expand Down Expand Up @@ -96,7 +96,7 @@ static int getRestrictedKeyword(String text) {
TokenNamefor = 86,
TokenNamegoto = 139,
TokenNameif = 87,
TokenNameimplements = 135,
TokenNameimplements = 134,
TokenNameimport = 112,
TokenNameinstanceof = 16,
TokenNameint = 113,
Expand All @@ -107,12 +107,13 @@ static int getRestrictedKeyword(String text) {
TokenNamenon_sealed = 47,
TokenNamenull = 57,
TokenNamepackage = 91,
TokenNamepermits = 135,
TokenNameprivate = 48,
TokenNameprotected = 49,
TokenNamepublic = 50,
TokenNamereturn = 88,
TokenNameshort = 115,
TokenNamestatic = 39,
TokenNamestatic = 38,
TokenNamestrictfp = 51,
TokenNamesuper = 36,
TokenNameswitch = 65,
Expand All @@ -129,7 +130,7 @@ static int getRestrictedKeyword(String text) {
TokenNamemodule = 119,
TokenNameopen = 124,
TokenNamerequires = 125,
TokenNametransitive = 131,
TokenNametransitive = 130,
TokenNameexports = 126,
TokenNameopens = 127,
TokenNameto = 136,
Expand Down Expand Up @@ -200,15 +201,14 @@ static int getRestrictedKeyword(String text) {
TokenNameBeginTypeArguments = 90,
TokenNameElidedSemicolonAndRightBrace = 72,
TokenNameAT308 = 28,
TokenNameAT308DOTDOTDOT = 132,
TokenNameAT308DOTDOTDOT = 131,
TokenNameBeginCaseExpr = 73,
TokenNameRestrictedIdentifierYield = 81,
TokenNameRestrictedIdentifierrecord = 76,
TokenNameRestrictedIdentifiersealed = 43,
TokenNameRestrictedIdentifierpermits = 130,
TokenNameBeginCaseElement = 133,
TokenNameRestrictedIdentifierWhen = 134,
TokenNameBeginCaseElement = 132,
TokenNameRestrictedIdentifierWhen = 133,
TokenNameUNDERSCORE = 34,
TokenNameEOF = 38,
TokenNameEOF = 39,
TokenNameERROR = 140;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ ClassHeaderImplements=ClassHeaderImplements
ClassHeaderImplementsopt=ClassHeaderImplements
ClassHeaderName1=ClassHeaderName
ClassHeaderName=ClassHeaderName
ClassHeaderPermittedSubclasses=ClassHeaderPermittedSubclasses
ClassHeaderPermittedSubclassesopt=ClassHeaderPermittedSubclasses
ClassInstanceCreationExpression=ClassInstanceCreationExpression
ClassInstanceCreationExpressionName=ClassInstanceCreationExpressionName
ClassMemberDeclaration=ClassMemberDeclaration
Expand Down Expand Up @@ -191,8 +189,6 @@ InterfaceHeaderExtends=InterfaceHeaderExtends
InterfaceHeaderExtendsopt=InterfaceHeaderExtends
InterfaceHeaderName1=InterfaceHeaderName
InterfaceHeaderName=InterfaceHeaderName
InterfaceHeaderPermittedSubClassesAndSubInterfaces=InterfaceHeaderPermittedSubClassesAndSubInterfaces
InterfaceHeaderPermittedSubClassesAndSubInterfacesopt=InterfaceHeaderPermittedSubClassesAndSubInterfaces
InterfaceMemberDeclaration=InterfaceMemberDeclaration
InterfaceMemberDeclarations=InterfaceMemberDeclarations
InterfaceMemberDeclarationsopt=InterfaceMemberDeclarations
Expand Down Expand Up @@ -254,7 +250,7 @@ PackageDeclarationName=PackageDeclarationName
ParenthesizedCastNameAndBounds=ParenthesizedCastNameAndBounds
ParenthesizedLambdaParameterList=ParenthesizedLambdaParameterList
Pattern=Pattern
PermittedSubclasses=PermittedSubclasses
PermittedTypesopt=PermittedTypes
PostDecrementExpression=PostDecrementExpression
PostIncrementExpression=PostIncrementExpression
PostfixExpression=Expression
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5221,7 +5221,7 @@ private boolean isRestrictedIdentifier(int token) {
case TerminalTokens.TokenNameRestrictedIdentifierYield:
case TerminalTokens.TokenNameRestrictedIdentifierrecord:
case TerminalTokens.TokenNameRestrictedIdentifiersealed:
case TerminalTokens.TokenNameRestrictedIdentifierpermits:
case TerminalTokens.TokenNamepermits:
case TerminalTokens.TokenNameRestrictedIdentifierWhen:
return true;
default: return false;
Expand Down Expand Up @@ -5284,7 +5284,7 @@ private boolean isKeyword(int token) {
case TerminalTokens.TokenNameRestrictedIdentifierYield:
case TerminalTokens.TokenNameRestrictedIdentifierrecord:
case TerminalTokens.TokenNameRestrictedIdentifiersealed:
case TerminalTokens.TokenNameRestrictedIdentifierpermits:
case TerminalTokens.TokenNamepermits:
case TerminalTokens.TokenNameRestrictedIdentifierWhen:
// making explicit - not a (restricted) keyword but restricted identifier.
//$FALL-THROUGH$
Expand Down
Loading

0 comments on commit bf0427a

Please sign in to comment.