mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 13:35:05 +00:00
[parser] Fix issue 52954 about nested record destructuring with shorthand
Fixes https://github.com/dart-lang/sdk/issues/52954 Change-Id: I41e229380ccc16aa8bab0696fa79ca701a43220f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/317681 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
1e3689cfa7
commit
a445fae681
|
@ -9942,7 +9942,9 @@ class Parser {
|
|||
wasValidRecord = true;
|
||||
listener.handleNoName(token);
|
||||
colon = token = next;
|
||||
} else if (optional(':', next.next!)) {
|
||||
} else if (!optional('(', next) && optional(':', next.next!)) {
|
||||
// We don't allow `next` to be `(` here because
|
||||
// `((:a, :b), :c, :d)` (and similar) is fine.
|
||||
// Record with named expression.
|
||||
wasRecord = true;
|
||||
token = ensureIdentifier(
|
||||
|
@ -10010,6 +10012,9 @@ class Parser {
|
|||
listener.handleNoName(token);
|
||||
colon = token = next;
|
||||
} else if (optional(':', next.next!)) {
|
||||
// This is different from `parseParenthesizedPatternOrRecordPattern`
|
||||
// because this isn't valid because of the missing name:
|
||||
// `var Point((:x, :y), :z) = Point((x: 1, y: 2), 3);`
|
||||
token =
|
||||
ensureIdentifier(token, IdentifierContext.namedArgumentReference)
|
||||
.next!;
|
||||
|
|
5
pkg/front_end/parser_testcases/patterns/issue_52954.dart
Normal file
5
pkg/front_end/parser_testcases/patterns/issue_52954.dart
Normal file
|
@ -0,0 +1,5 @@
|
|||
main() {
|
||||
final record = ((a: 1, b: 2), 3);
|
||||
final ((:a, :b), c) = record;
|
||||
print("a = $a; b = $b, c = $c");
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
beginCompilationUnit(main)
|
||||
beginMetadataStar(main)
|
||||
endMetadataStar(0)
|
||||
beginTopLevelMember(main)
|
||||
beginTopLevelMethod(, null, null)
|
||||
handleNoType()
|
||||
handleIdentifier(main, topLevelFunctionDeclaration)
|
||||
handleNoTypeVariables(()
|
||||
beginFormalParameters((, MemberKind.TopLevelMethod)
|
||||
endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
|
||||
handleAsyncModifier(null, null)
|
||||
beginBlockFunctionBody({)
|
||||
beginMetadataStar(final)
|
||||
endMetadataStar(0)
|
||||
handleNoType(final)
|
||||
beginVariablesDeclaration(record, null, final)
|
||||
handleIdentifier(record, localVariableDeclaration)
|
||||
beginInitializedIdentifier(record)
|
||||
beginVariableInitializer(=)
|
||||
beginParenthesizedExpressionOrRecordLiteral(()
|
||||
beginParenthesizedExpressionOrRecordLiteral(()
|
||||
handleIdentifier(a, namedRecordFieldReference)
|
||||
handleLiteralInt(1)
|
||||
handleNamedRecordField(:)
|
||||
handleIdentifier(b, namedRecordFieldReference)
|
||||
handleLiteralInt(2)
|
||||
handleNamedRecordField(:)
|
||||
endRecordLiteral((, 2, null)
|
||||
handleLiteralInt(3)
|
||||
endRecordLiteral((, 2, null)
|
||||
endVariableInitializer(=)
|
||||
endInitializedIdentifier(record)
|
||||
endVariablesDeclaration(1, ;)
|
||||
beginMetadataStar(final)
|
||||
endMetadataStar(0)
|
||||
beginPattern(final)
|
||||
beginPattern(()
|
||||
handleNoName(()
|
||||
beginPattern(:)
|
||||
handleNoType(a)
|
||||
handleDeclaredVariablePattern(null, a, false)
|
||||
endPattern(a)
|
||||
handlePatternField(:)
|
||||
handleNoName(,)
|
||||
beginPattern(:)
|
||||
handleNoType(b)
|
||||
handleDeclaredVariablePattern(null, b, false)
|
||||
endPattern(b)
|
||||
handlePatternField(:)
|
||||
handleRecordPattern((, 2)
|
||||
endPattern())
|
||||
handlePatternField(null)
|
||||
beginPattern(,)
|
||||
handleNoType(c)
|
||||
handleDeclaredVariablePattern(null, c, false)
|
||||
endPattern(c)
|
||||
handlePatternField(null)
|
||||
handleRecordPattern((, 2)
|
||||
endPattern())
|
||||
handleIdentifier(record, expression)
|
||||
handleNoTypeArguments(;)
|
||||
handleNoArguments(;)
|
||||
handleSend(record, ;)
|
||||
handlePatternVariableDeclarationStatement(final, =, ;)
|
||||
handleIdentifier(print, expression)
|
||||
handleNoTypeArguments(()
|
||||
beginArguments(()
|
||||
beginLiteralString("a = )
|
||||
handleIdentifier(a, expression)
|
||||
handleNoTypeArguments(; b = )
|
||||
handleNoArguments(; b = )
|
||||
handleSend(a, ; b = )
|
||||
handleInterpolationExpression($, null)
|
||||
handleStringPart(; b = )
|
||||
handleIdentifier(b, expression)
|
||||
handleNoTypeArguments(, c = )
|
||||
handleNoArguments(, c = )
|
||||
handleSend(b, , c = )
|
||||
handleInterpolationExpression($, null)
|
||||
handleStringPart(, c = )
|
||||
handleIdentifier(c, expression)
|
||||
handleNoTypeArguments(")
|
||||
handleNoArguments(")
|
||||
handleSend(c, ")
|
||||
handleInterpolationExpression($, null)
|
||||
handleStringPart(")
|
||||
endLiteralString(3, ))
|
||||
endArguments(1, (, ))
|
||||
handleSend(print, ;)
|
||||
handleExpressionStatement(;)
|
||||
endBlockFunctionBody(3, {, })
|
||||
endTopLevelMethod(main, null, })
|
||||
endTopLevelDeclaration()
|
||||
endCompilationUnit(1, )
|
|
@ -0,0 +1,249 @@
|
|||
parseUnit(main)
|
||||
skipErrorTokens(main)
|
||||
listener: beginCompilationUnit(main)
|
||||
syntheticPreviousToken(main)
|
||||
parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
|
||||
parseMetadataStar()
|
||||
listener: beginMetadataStar(main)
|
||||
listener: endMetadataStar(0)
|
||||
parseTopLevelMemberImpl()
|
||||
listener: beginTopLevelMember(main)
|
||||
isReservedKeyword(()
|
||||
parseTopLevelMethod(, null, null, , Instance of 'NoType', null, main, false)
|
||||
listener: beginTopLevelMethod(, null, null)
|
||||
listener: handleNoType()
|
||||
ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
|
||||
listener: handleIdentifier(main, topLevelFunctionDeclaration)
|
||||
parseMethodTypeVar(main)
|
||||
listener: handleNoTypeVariables(()
|
||||
parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
|
||||
parseFormalParameters(main, MemberKind.TopLevelMethod)
|
||||
parseFormalParametersRest((, MemberKind.TopLevelMethod)
|
||||
listener: beginFormalParameters((, MemberKind.TopLevelMethod)
|
||||
listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
|
||||
parseAsyncModifierOpt())
|
||||
listener: handleAsyncModifier(null, null)
|
||||
inPlainSync()
|
||||
parseFunctionBody(), false, false)
|
||||
listener: beginBlockFunctionBody({)
|
||||
notEofOrValue(}, final)
|
||||
parseStatement({)
|
||||
parseStatementX({)
|
||||
parseExpressionStatementOrDeclarationAfterModifiers(final, {, null, final, null, null)
|
||||
skipOuterPattern(final)
|
||||
skipObjectPatternRest(record)
|
||||
looksLikeLocalFunction(record)
|
||||
listener: beginMetadataStar(final)
|
||||
listener: endMetadataStar(0)
|
||||
listener: handleNoType(final)
|
||||
listener: beginVariablesDeclaration(record, null, final)
|
||||
parseVariablesDeclarationRest(final, true)
|
||||
parseOptionallyInitializedIdentifier(final)
|
||||
ensureIdentifier(final, localVariableDeclaration)
|
||||
listener: handleIdentifier(record, localVariableDeclaration)
|
||||
listener: beginInitializedIdentifier(record)
|
||||
parseVariableInitializerOpt(record)
|
||||
listener: beginVariableInitializer(=)
|
||||
parseExpression(=)
|
||||
looksLikeOuterPatternEquals(=)
|
||||
skipOuterPattern(=)
|
||||
parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(=, true, ConstantPatternContext.none)
|
||||
parsePrimary(=, expression, ConstantPatternContext.none)
|
||||
parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=, ConstantPatternContext.none)
|
||||
parseParenthesizedExpressionOrRecordLiteral(=, null, ConstantPatternContext.none)
|
||||
listener: beginParenthesizedExpressionOrRecordLiteral(()
|
||||
parseExpression(()
|
||||
looksLikeOuterPatternEquals(()
|
||||
skipOuterPattern(()
|
||||
parsePrecedenceExpression((, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression((, true, ConstantPatternContext.none)
|
||||
parsePrimary((, expression, ConstantPatternContext.none)
|
||||
parseParenthesizedExpressionFunctionLiteralOrRecordLiteral((, ConstantPatternContext.none)
|
||||
parseParenthesizedExpressionOrRecordLiteral((, null, ConstantPatternContext.none)
|
||||
listener: beginParenthesizedExpressionOrRecordLiteral(()
|
||||
ensureIdentifier((, namedRecordFieldReference)
|
||||
listener: handleIdentifier(a, namedRecordFieldReference)
|
||||
parseExpression(:)
|
||||
looksLikeOuterPatternEquals(:)
|
||||
skipOuterPattern(:)
|
||||
parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(:, true, ConstantPatternContext.none)
|
||||
parsePrimary(:, expression, ConstantPatternContext.none)
|
||||
parseLiteralInt(:)
|
||||
listener: handleLiteralInt(1)
|
||||
listener: handleNamedRecordField(:)
|
||||
ensureIdentifier(,, namedRecordFieldReference)
|
||||
listener: handleIdentifier(b, namedRecordFieldReference)
|
||||
parseExpression(:)
|
||||
looksLikeOuterPatternEquals(:)
|
||||
skipOuterPattern(:)
|
||||
parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(:, true, ConstantPatternContext.none)
|
||||
parsePrimary(:, expression, ConstantPatternContext.none)
|
||||
parseLiteralInt(:)
|
||||
listener: handleLiteralInt(2)
|
||||
listener: handleNamedRecordField(:)
|
||||
ensureCloseParen(2, ()
|
||||
listener: endRecordLiteral((, 2, null)
|
||||
parseExpression(,)
|
||||
looksLikeOuterPatternEquals(,)
|
||||
skipOuterPattern(,)
|
||||
parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(,, true, ConstantPatternContext.none)
|
||||
parsePrimary(,, expression, ConstantPatternContext.none)
|
||||
parseLiteralInt(,)
|
||||
listener: handleLiteralInt(3)
|
||||
ensureCloseParen(3, ()
|
||||
listener: endRecordLiteral((, 2, null)
|
||||
listener: endVariableInitializer(=)
|
||||
listener: endInitializedIdentifier(record)
|
||||
ensureSemicolon())
|
||||
listener: endVariablesDeclaration(1, ;)
|
||||
notEofOrValue(}, final)
|
||||
parseStatement(;)
|
||||
parseStatementX(;)
|
||||
parseExpressionStatementOrDeclarationAfterModifiers(final, ;, null, final, null, null)
|
||||
skipOuterPattern(final)
|
||||
listener: beginMetadataStar(final)
|
||||
listener: endMetadataStar(0)
|
||||
parsePatternVariableDeclarationStatement(final, ;, final)
|
||||
parsePattern(final, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(final)
|
||||
parsePrimaryPattern(final, PatternContext.declaration)
|
||||
parseParenthesizedPatternOrRecordPattern(final, PatternContext.declaration)
|
||||
parsePattern((, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(()
|
||||
parsePrimaryPattern((, PatternContext.declaration)
|
||||
parseParenthesizedPatternOrRecordPattern((, PatternContext.declaration)
|
||||
listener: handleNoName(()
|
||||
parsePattern(:, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(:)
|
||||
parsePrimaryPattern(:, PatternContext.declaration)
|
||||
parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType')
|
||||
listener: handleNoType(a)
|
||||
listener: handleDeclaredVariablePattern(null, a, false)
|
||||
listener: endPattern(a)
|
||||
listener: handlePatternField(:)
|
||||
listener: handleNoName(,)
|
||||
parsePattern(:, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(:)
|
||||
parsePrimaryPattern(:, PatternContext.declaration)
|
||||
parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType')
|
||||
listener: handleNoType(b)
|
||||
listener: handleDeclaredVariablePattern(null, b, false)
|
||||
listener: endPattern(b)
|
||||
listener: handlePatternField(:)
|
||||
ensureCloseParen(b, ()
|
||||
listener: handleRecordPattern((, 2)
|
||||
listener: endPattern())
|
||||
listener: handlePatternField(null)
|
||||
parsePattern(,, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(,)
|
||||
parsePrimaryPattern(,, PatternContext.declaration)
|
||||
parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'NoType')
|
||||
listener: handleNoType(c)
|
||||
listener: handleDeclaredVariablePattern(null, c, false)
|
||||
listener: endPattern(c)
|
||||
listener: handlePatternField(null)
|
||||
ensureCloseParen(c, ()
|
||||
listener: handleRecordPattern((, 2)
|
||||
listener: endPattern())
|
||||
parseExpression(=)
|
||||
looksLikeOuterPatternEquals(=)
|
||||
skipOuterPattern(=)
|
||||
skipObjectPatternRest(record)
|
||||
parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(=, true, ConstantPatternContext.none)
|
||||
parsePrimary(=, expression, ConstantPatternContext.none)
|
||||
parseSendOrFunctionLiteral(=, expression, ConstantPatternContext.none)
|
||||
parseSend(=, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier(=)
|
||||
ensureIdentifier(=, expression)
|
||||
listener: handleIdentifier(record, expression)
|
||||
listener: handleNoTypeArguments(;)
|
||||
parseArgumentsOpt(record)
|
||||
listener: handleNoArguments(;)
|
||||
listener: handleSend(record, ;)
|
||||
ensureSemicolon(record)
|
||||
listener: handlePatternVariableDeclarationStatement(final, =, ;)
|
||||
notEofOrValue(}, print)
|
||||
parseStatement(;)
|
||||
parseStatementX(;)
|
||||
parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
|
||||
looksLikeLocalFunction(print)
|
||||
parseExpressionStatement(;)
|
||||
parseExpression(;)
|
||||
looksLikeOuterPatternEquals(;)
|
||||
skipOuterPattern(;)
|
||||
skipObjectPatternRest(print)
|
||||
parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(;, true, ConstantPatternContext.none)
|
||||
parsePrimary(;, expression, ConstantPatternContext.none)
|
||||
parseSendOrFunctionLiteral(;, expression, ConstantPatternContext.none)
|
||||
looksLikeFunctionBody(;)
|
||||
parseSend(;, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier(;)
|
||||
ensureIdentifier(;, expression)
|
||||
listener: handleIdentifier(print, expression)
|
||||
listener: handleNoTypeArguments(()
|
||||
parseArgumentsOpt(print)
|
||||
parseArguments(print)
|
||||
parseArgumentsRest(()
|
||||
listener: beginArguments(()
|
||||
parseExpression(()
|
||||
looksLikeOuterPatternEquals(()
|
||||
skipOuterPattern(()
|
||||
parsePrecedenceExpression((, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression((, true, ConstantPatternContext.none)
|
||||
parsePrimary((, expression, ConstantPatternContext.none)
|
||||
parseLiteralString(()
|
||||
parseSingleLiteralString(()
|
||||
listener: beginLiteralString("a = )
|
||||
parseIdentifierExpression($)
|
||||
parseSend($, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier($)
|
||||
ensureIdentifier($, expression)
|
||||
listener: handleIdentifier(a, expression)
|
||||
listener: handleNoTypeArguments(; b = )
|
||||
parseArgumentsOpt(a)
|
||||
listener: handleNoArguments(; b = )
|
||||
listener: handleSend(a, ; b = )
|
||||
listener: handleInterpolationExpression($, null)
|
||||
parseStringPart(a)
|
||||
listener: handleStringPart(; b = )
|
||||
parseIdentifierExpression($)
|
||||
parseSend($, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier($)
|
||||
ensureIdentifier($, expression)
|
||||
listener: handleIdentifier(b, expression)
|
||||
listener: handleNoTypeArguments(, c = )
|
||||
parseArgumentsOpt(b)
|
||||
listener: handleNoArguments(, c = )
|
||||
listener: handleSend(b, , c = )
|
||||
listener: handleInterpolationExpression($, null)
|
||||
parseStringPart(b)
|
||||
listener: handleStringPart(, c = )
|
||||
parseIdentifierExpression($)
|
||||
parseSend($, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier($)
|
||||
ensureIdentifier($, expression)
|
||||
listener: handleIdentifier(c, expression)
|
||||
listener: handleNoTypeArguments(")
|
||||
parseArgumentsOpt(c)
|
||||
listener: handleNoArguments(")
|
||||
listener: handleSend(c, ")
|
||||
listener: handleInterpolationExpression($, null)
|
||||
parseStringPart(c)
|
||||
listener: handleStringPart(")
|
||||
listener: endLiteralString(3, ))
|
||||
listener: endArguments(1, (, ))
|
||||
listener: handleSend(print, ;)
|
||||
ensureSemicolon())
|
||||
listener: handleExpressionStatement(;)
|
||||
notEofOrValue(}, })
|
||||
listener: endBlockFunctionBody(3, {, })
|
||||
listener: endTopLevelMethod(main, null, })
|
||||
listener: endTopLevelDeclaration()
|
||||
reportAllErrorTokens(main)
|
||||
listener: endCompilationUnit(1, )
|
|
@ -0,0 +1,13 @@
|
|||
main() {
|
||||
final record = ((a: 1, b: 2), 3);
|
||||
final ((:a, :b), c) = record;
|
||||
print("a = $a; b = $b, c = $c");
|
||||
}
|
||||
|
||||
|
||||
main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
|
||||
final[KeywordToken] record[StringToken] =[SimpleToken] ([BeginToken]([BeginToken]a[StringToken]:[SimpleToken] 1[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 2[StringToken])[SimpleToken],[SimpleToken] 3[StringToken])[SimpleToken];[SimpleToken]
|
||||
final[KeywordToken] ([BeginToken]([BeginToken]:[SimpleToken]a[StringToken],[SimpleToken] :[SimpleToken]b[StringToken])[SimpleToken],[SimpleToken] c[StringToken])[SimpleToken] =[SimpleToken] record[StringToken];[SimpleToken]
|
||||
print[StringToken]([BeginToken]"a = [StringToken]$[SimpleToken]a[StringToken]; b = [StringToken]$[SimpleToken]b[StringToken], c = [StringToken]$[SimpleToken]c[StringToken]"[StringToken])[SimpleToken];[SimpleToken]
|
||||
}[SimpleToken]
|
||||
[SimpleToken]
|
|
@ -0,0 +1,13 @@
|
|||
main() {
|
||||
final record = ((a: 1, b: 2), 3);
|
||||
final ((:a, :b), c) = record;
|
||||
print("a = $a; b = $b, c = $c");
|
||||
}
|
||||
|
||||
|
||||
main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
|
||||
final[KeywordToken] record[StringToken] =[SimpleToken] ([BeginToken]([BeginToken]a[StringToken]:[SimpleToken] 1[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 2[StringToken])[SimpleToken],[SimpleToken] 3[StringToken])[SimpleToken];[SimpleToken]
|
||||
final[KeywordToken] ([BeginToken]([BeginToken]:[SimpleToken]a[StringToken],[SimpleToken] :[SimpleToken]b[StringToken])[SimpleToken],[SimpleToken] c[StringToken])[SimpleToken] =[SimpleToken] record[StringToken];[SimpleToken]
|
||||
print[StringToken]([BeginToken]"a = [StringToken]$[SimpleToken]a[StringToken]; b = [StringToken]$[SimpleToken]b[StringToken], c = [StringToken]$[SimpleToken]c[StringToken]"[StringToken])[SimpleToken];[SimpleToken]
|
||||
}[SimpleToken]
|
||||
[SimpleToken]
|
|
@ -0,0 +1,8 @@
|
|||
files:
|
||||
- issue_52954.dart
|
||||
- issue_52954_prime.dart
|
||||
filters:
|
||||
- ignoreListenerArguments
|
||||
ignored:
|
||||
- handleNoName
|
||||
- handleIdentifier
|
|
@ -0,0 +1,5 @@
|
|||
main() {
|
||||
final record = ((a: 1, b: 2), 3);
|
||||
final ((a: a, :b), c) = record;
|
||||
print("a = $a; b = $b, c = $c");
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
beginCompilationUnit(main)
|
||||
beginMetadataStar(main)
|
||||
endMetadataStar(0)
|
||||
beginTopLevelMember(main)
|
||||
beginTopLevelMethod(, null, null)
|
||||
handleNoType()
|
||||
handleIdentifier(main, topLevelFunctionDeclaration)
|
||||
handleNoTypeVariables(()
|
||||
beginFormalParameters((, MemberKind.TopLevelMethod)
|
||||
endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
|
||||
handleAsyncModifier(null, null)
|
||||
beginBlockFunctionBody({)
|
||||
beginMetadataStar(final)
|
||||
endMetadataStar(0)
|
||||
handleNoType(final)
|
||||
beginVariablesDeclaration(record, null, final)
|
||||
handleIdentifier(record, localVariableDeclaration)
|
||||
beginInitializedIdentifier(record)
|
||||
beginVariableInitializer(=)
|
||||
beginParenthesizedExpressionOrRecordLiteral(()
|
||||
beginParenthesizedExpressionOrRecordLiteral(()
|
||||
handleIdentifier(a, namedRecordFieldReference)
|
||||
handleLiteralInt(1)
|
||||
handleNamedRecordField(:)
|
||||
handleIdentifier(b, namedRecordFieldReference)
|
||||
handleLiteralInt(2)
|
||||
handleNamedRecordField(:)
|
||||
endRecordLiteral((, 2, null)
|
||||
handleLiteralInt(3)
|
||||
endRecordLiteral((, 2, null)
|
||||
endVariableInitializer(=)
|
||||
endInitializedIdentifier(record)
|
||||
endVariablesDeclaration(1, ;)
|
||||
beginMetadataStar(final)
|
||||
endMetadataStar(0)
|
||||
beginPattern(final)
|
||||
beginPattern(()
|
||||
handleIdentifier(a, namedRecordFieldReference)
|
||||
beginPattern(:)
|
||||
handleNoType(a)
|
||||
handleDeclaredVariablePattern(null, a, false)
|
||||
endPattern(a)
|
||||
handlePatternField(:)
|
||||
handleNoName(,)
|
||||
beginPattern(:)
|
||||
handleNoType(b)
|
||||
handleDeclaredVariablePattern(null, b, false)
|
||||
endPattern(b)
|
||||
handlePatternField(:)
|
||||
handleRecordPattern((, 2)
|
||||
endPattern())
|
||||
handlePatternField(null)
|
||||
beginPattern(,)
|
||||
handleNoType(c)
|
||||
handleDeclaredVariablePattern(null, c, false)
|
||||
endPattern(c)
|
||||
handlePatternField(null)
|
||||
handleRecordPattern((, 2)
|
||||
endPattern())
|
||||
handleIdentifier(record, expression)
|
||||
handleNoTypeArguments(;)
|
||||
handleNoArguments(;)
|
||||
handleSend(record, ;)
|
||||
handlePatternVariableDeclarationStatement(final, =, ;)
|
||||
handleIdentifier(print, expression)
|
||||
handleNoTypeArguments(()
|
||||
beginArguments(()
|
||||
beginLiteralString("a = )
|
||||
handleIdentifier(a, expression)
|
||||
handleNoTypeArguments(; b = )
|
||||
handleNoArguments(; b = )
|
||||
handleSend(a, ; b = )
|
||||
handleInterpolationExpression($, null)
|
||||
handleStringPart(; b = )
|
||||
handleIdentifier(b, expression)
|
||||
handleNoTypeArguments(, c = )
|
||||
handleNoArguments(, c = )
|
||||
handleSend(b, , c = )
|
||||
handleInterpolationExpression($, null)
|
||||
handleStringPart(, c = )
|
||||
handleIdentifier(c, expression)
|
||||
handleNoTypeArguments(")
|
||||
handleNoArguments(")
|
||||
handleSend(c, ")
|
||||
handleInterpolationExpression($, null)
|
||||
handleStringPart(")
|
||||
endLiteralString(3, ))
|
||||
endArguments(1, (, ))
|
||||
handleSend(print, ;)
|
||||
handleExpressionStatement(;)
|
||||
endBlockFunctionBody(3, {, })
|
||||
endTopLevelMethod(main, null, })
|
||||
endTopLevelDeclaration()
|
||||
endCompilationUnit(1, )
|
|
@ -0,0 +1,250 @@
|
|||
parseUnit(main)
|
||||
skipErrorTokens(main)
|
||||
listener: beginCompilationUnit(main)
|
||||
syntheticPreviousToken(main)
|
||||
parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
|
||||
parseMetadataStar()
|
||||
listener: beginMetadataStar(main)
|
||||
listener: endMetadataStar(0)
|
||||
parseTopLevelMemberImpl()
|
||||
listener: beginTopLevelMember(main)
|
||||
isReservedKeyword(()
|
||||
parseTopLevelMethod(, null, null, , Instance of 'NoType', null, main, false)
|
||||
listener: beginTopLevelMethod(, null, null)
|
||||
listener: handleNoType()
|
||||
ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
|
||||
listener: handleIdentifier(main, topLevelFunctionDeclaration)
|
||||
parseMethodTypeVar(main)
|
||||
listener: handleNoTypeVariables(()
|
||||
parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
|
||||
parseFormalParameters(main, MemberKind.TopLevelMethod)
|
||||
parseFormalParametersRest((, MemberKind.TopLevelMethod)
|
||||
listener: beginFormalParameters((, MemberKind.TopLevelMethod)
|
||||
listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
|
||||
parseAsyncModifierOpt())
|
||||
listener: handleAsyncModifier(null, null)
|
||||
inPlainSync()
|
||||
parseFunctionBody(), false, false)
|
||||
listener: beginBlockFunctionBody({)
|
||||
notEofOrValue(}, final)
|
||||
parseStatement({)
|
||||
parseStatementX({)
|
||||
parseExpressionStatementOrDeclarationAfterModifiers(final, {, null, final, null, null)
|
||||
skipOuterPattern(final)
|
||||
skipObjectPatternRest(record)
|
||||
looksLikeLocalFunction(record)
|
||||
listener: beginMetadataStar(final)
|
||||
listener: endMetadataStar(0)
|
||||
listener: handleNoType(final)
|
||||
listener: beginVariablesDeclaration(record, null, final)
|
||||
parseVariablesDeclarationRest(final, true)
|
||||
parseOptionallyInitializedIdentifier(final)
|
||||
ensureIdentifier(final, localVariableDeclaration)
|
||||
listener: handleIdentifier(record, localVariableDeclaration)
|
||||
listener: beginInitializedIdentifier(record)
|
||||
parseVariableInitializerOpt(record)
|
||||
listener: beginVariableInitializer(=)
|
||||
parseExpression(=)
|
||||
looksLikeOuterPatternEquals(=)
|
||||
skipOuterPattern(=)
|
||||
parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(=, true, ConstantPatternContext.none)
|
||||
parsePrimary(=, expression, ConstantPatternContext.none)
|
||||
parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(=, ConstantPatternContext.none)
|
||||
parseParenthesizedExpressionOrRecordLiteral(=, null, ConstantPatternContext.none)
|
||||
listener: beginParenthesizedExpressionOrRecordLiteral(()
|
||||
parseExpression(()
|
||||
looksLikeOuterPatternEquals(()
|
||||
skipOuterPattern(()
|
||||
parsePrecedenceExpression((, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression((, true, ConstantPatternContext.none)
|
||||
parsePrimary((, expression, ConstantPatternContext.none)
|
||||
parseParenthesizedExpressionFunctionLiteralOrRecordLiteral((, ConstantPatternContext.none)
|
||||
parseParenthesizedExpressionOrRecordLiteral((, null, ConstantPatternContext.none)
|
||||
listener: beginParenthesizedExpressionOrRecordLiteral(()
|
||||
ensureIdentifier((, namedRecordFieldReference)
|
||||
listener: handleIdentifier(a, namedRecordFieldReference)
|
||||
parseExpression(:)
|
||||
looksLikeOuterPatternEquals(:)
|
||||
skipOuterPattern(:)
|
||||
parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(:, true, ConstantPatternContext.none)
|
||||
parsePrimary(:, expression, ConstantPatternContext.none)
|
||||
parseLiteralInt(:)
|
||||
listener: handleLiteralInt(1)
|
||||
listener: handleNamedRecordField(:)
|
||||
ensureIdentifier(,, namedRecordFieldReference)
|
||||
listener: handleIdentifier(b, namedRecordFieldReference)
|
||||
parseExpression(:)
|
||||
looksLikeOuterPatternEquals(:)
|
||||
skipOuterPattern(:)
|
||||
parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(:, true, ConstantPatternContext.none)
|
||||
parsePrimary(:, expression, ConstantPatternContext.none)
|
||||
parseLiteralInt(:)
|
||||
listener: handleLiteralInt(2)
|
||||
listener: handleNamedRecordField(:)
|
||||
ensureCloseParen(2, ()
|
||||
listener: endRecordLiteral((, 2, null)
|
||||
parseExpression(,)
|
||||
looksLikeOuterPatternEquals(,)
|
||||
skipOuterPattern(,)
|
||||
parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(,, true, ConstantPatternContext.none)
|
||||
parsePrimary(,, expression, ConstantPatternContext.none)
|
||||
parseLiteralInt(,)
|
||||
listener: handleLiteralInt(3)
|
||||
ensureCloseParen(3, ()
|
||||
listener: endRecordLiteral((, 2, null)
|
||||
listener: endVariableInitializer(=)
|
||||
listener: endInitializedIdentifier(record)
|
||||
ensureSemicolon())
|
||||
listener: endVariablesDeclaration(1, ;)
|
||||
notEofOrValue(}, final)
|
||||
parseStatement(;)
|
||||
parseStatementX(;)
|
||||
parseExpressionStatementOrDeclarationAfterModifiers(final, ;, null, final, null, null)
|
||||
skipOuterPattern(final)
|
||||
listener: beginMetadataStar(final)
|
||||
listener: endMetadataStar(0)
|
||||
parsePatternVariableDeclarationStatement(final, ;, final)
|
||||
parsePattern(final, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(final)
|
||||
parsePrimaryPattern(final, PatternContext.declaration)
|
||||
parseParenthesizedPatternOrRecordPattern(final, PatternContext.declaration)
|
||||
parsePattern((, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(()
|
||||
parsePrimaryPattern((, PatternContext.declaration)
|
||||
parseParenthesizedPatternOrRecordPattern((, PatternContext.declaration)
|
||||
ensureIdentifier((, namedRecordFieldReference)
|
||||
listener: handleIdentifier(a, namedRecordFieldReference)
|
||||
parsePattern(:, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(:)
|
||||
parsePrimaryPattern(:, PatternContext.declaration)
|
||||
parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType')
|
||||
listener: handleNoType(a)
|
||||
listener: handleDeclaredVariablePattern(null, a, false)
|
||||
listener: endPattern(a)
|
||||
listener: handlePatternField(:)
|
||||
listener: handleNoName(,)
|
||||
parsePattern(:, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(:)
|
||||
parsePrimaryPattern(:, PatternContext.declaration)
|
||||
parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType')
|
||||
listener: handleNoType(b)
|
||||
listener: handleDeclaredVariablePattern(null, b, false)
|
||||
listener: endPattern(b)
|
||||
listener: handlePatternField(:)
|
||||
ensureCloseParen(b, ()
|
||||
listener: handleRecordPattern((, 2)
|
||||
listener: endPattern())
|
||||
listener: handlePatternField(null)
|
||||
parsePattern(,, PatternContext.declaration, precedence: 1)
|
||||
listener: beginPattern(,)
|
||||
parsePrimaryPattern(,, PatternContext.declaration)
|
||||
parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'NoType')
|
||||
listener: handleNoType(c)
|
||||
listener: handleDeclaredVariablePattern(null, c, false)
|
||||
listener: endPattern(c)
|
||||
listener: handlePatternField(null)
|
||||
ensureCloseParen(c, ()
|
||||
listener: handleRecordPattern((, 2)
|
||||
listener: endPattern())
|
||||
parseExpression(=)
|
||||
looksLikeOuterPatternEquals(=)
|
||||
skipOuterPattern(=)
|
||||
skipObjectPatternRest(record)
|
||||
parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(=, true, ConstantPatternContext.none)
|
||||
parsePrimary(=, expression, ConstantPatternContext.none)
|
||||
parseSendOrFunctionLiteral(=, expression, ConstantPatternContext.none)
|
||||
parseSend(=, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier(=)
|
||||
ensureIdentifier(=, expression)
|
||||
listener: handleIdentifier(record, expression)
|
||||
listener: handleNoTypeArguments(;)
|
||||
parseArgumentsOpt(record)
|
||||
listener: handleNoArguments(;)
|
||||
listener: handleSend(record, ;)
|
||||
ensureSemicolon(record)
|
||||
listener: handlePatternVariableDeclarationStatement(final, =, ;)
|
||||
notEofOrValue(}, print)
|
||||
parseStatement(;)
|
||||
parseStatementX(;)
|
||||
parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
|
||||
looksLikeLocalFunction(print)
|
||||
parseExpressionStatement(;)
|
||||
parseExpression(;)
|
||||
looksLikeOuterPatternEquals(;)
|
||||
skipOuterPattern(;)
|
||||
skipObjectPatternRest(print)
|
||||
parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression(;, true, ConstantPatternContext.none)
|
||||
parsePrimary(;, expression, ConstantPatternContext.none)
|
||||
parseSendOrFunctionLiteral(;, expression, ConstantPatternContext.none)
|
||||
looksLikeFunctionBody(;)
|
||||
parseSend(;, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier(;)
|
||||
ensureIdentifier(;, expression)
|
||||
listener: handleIdentifier(print, expression)
|
||||
listener: handleNoTypeArguments(()
|
||||
parseArgumentsOpt(print)
|
||||
parseArguments(print)
|
||||
parseArgumentsRest(()
|
||||
listener: beginArguments(()
|
||||
parseExpression(()
|
||||
looksLikeOuterPatternEquals(()
|
||||
skipOuterPattern(()
|
||||
parsePrecedenceExpression((, 1, true, ConstantPatternContext.none)
|
||||
parseUnaryExpression((, true, ConstantPatternContext.none)
|
||||
parsePrimary((, expression, ConstantPatternContext.none)
|
||||
parseLiteralString(()
|
||||
parseSingleLiteralString(()
|
||||
listener: beginLiteralString("a = )
|
||||
parseIdentifierExpression($)
|
||||
parseSend($, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier($)
|
||||
ensureIdentifier($, expression)
|
||||
listener: handleIdentifier(a, expression)
|
||||
listener: handleNoTypeArguments(; b = )
|
||||
parseArgumentsOpt(a)
|
||||
listener: handleNoArguments(; b = )
|
||||
listener: handleSend(a, ; b = )
|
||||
listener: handleInterpolationExpression($, null)
|
||||
parseStringPart(a)
|
||||
listener: handleStringPart(; b = )
|
||||
parseIdentifierExpression($)
|
||||
parseSend($, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier($)
|
||||
ensureIdentifier($, expression)
|
||||
listener: handleIdentifier(b, expression)
|
||||
listener: handleNoTypeArguments(, c = )
|
||||
parseArgumentsOpt(b)
|
||||
listener: handleNoArguments(, c = )
|
||||
listener: handleSend(b, , c = )
|
||||
listener: handleInterpolationExpression($, null)
|
||||
parseStringPart(b)
|
||||
listener: handleStringPart(, c = )
|
||||
parseIdentifierExpression($)
|
||||
parseSend($, expression, ConstantPatternContext.none)
|
||||
isNextIdentifier($)
|
||||
ensureIdentifier($, expression)
|
||||
listener: handleIdentifier(c, expression)
|
||||
listener: handleNoTypeArguments(")
|
||||
parseArgumentsOpt(c)
|
||||
listener: handleNoArguments(")
|
||||
listener: handleSend(c, ")
|
||||
listener: handleInterpolationExpression($, null)
|
||||
parseStringPart(c)
|
||||
listener: handleStringPart(")
|
||||
listener: endLiteralString(3, ))
|
||||
listener: endArguments(1, (, ))
|
||||
listener: handleSend(print, ;)
|
||||
ensureSemicolon())
|
||||
listener: handleExpressionStatement(;)
|
||||
notEofOrValue(}, })
|
||||
listener: endBlockFunctionBody(3, {, })
|
||||
listener: endTopLevelMethod(main, null, })
|
||||
listener: endTopLevelDeclaration()
|
||||
reportAllErrorTokens(main)
|
||||
listener: endCompilationUnit(1, )
|
|
@ -0,0 +1,13 @@
|
|||
main() {
|
||||
final record = ((a: 1, b: 2), 3);
|
||||
final ((a: a, :b), c) = record;
|
||||
print("a = $a; b = $b, c = $c");
|
||||
}
|
||||
|
||||
|
||||
main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
|
||||
final[KeywordToken] record[StringToken] =[SimpleToken] ([BeginToken]([BeginToken]a[StringToken]:[SimpleToken] 1[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 2[StringToken])[SimpleToken],[SimpleToken] 3[StringToken])[SimpleToken];[SimpleToken]
|
||||
final[KeywordToken] ([BeginToken]([BeginToken]a[StringToken]:[SimpleToken] a[StringToken],[SimpleToken] :[SimpleToken]b[StringToken])[SimpleToken],[SimpleToken] c[StringToken])[SimpleToken] =[SimpleToken] record[StringToken];[SimpleToken]
|
||||
print[StringToken]([BeginToken]"a = [StringToken]$[SimpleToken]a[StringToken]; b = [StringToken]$[SimpleToken]b[StringToken], c = [StringToken]$[SimpleToken]c[StringToken]"[StringToken])[SimpleToken];[SimpleToken]
|
||||
}[SimpleToken]
|
||||
[SimpleToken]
|
|
@ -0,0 +1,13 @@
|
|||
main() {
|
||||
final record = ((a: 1, b: 2), 3);
|
||||
final ((a: a, :b), c) = record;
|
||||
print("a = $a; b = $b, c = $c");
|
||||
}
|
||||
|
||||
|
||||
main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
|
||||
final[KeywordToken] record[StringToken] =[SimpleToken] ([BeginToken]([BeginToken]a[StringToken]:[SimpleToken] 1[StringToken],[SimpleToken] b[StringToken]:[SimpleToken] 2[StringToken])[SimpleToken],[SimpleToken] 3[StringToken])[SimpleToken];[SimpleToken]
|
||||
final[KeywordToken] ([BeginToken]([BeginToken]a[StringToken]:[SimpleToken] a[StringToken],[SimpleToken] :[SimpleToken]b[StringToken])[SimpleToken],[SimpleToken] c[StringToken])[SimpleToken] =[SimpleToken] record[StringToken];[SimpleToken]
|
||||
print[StringToken]([BeginToken]"a = [StringToken]$[SimpleToken]a[StringToken]; b = [StringToken]$[SimpleToken]b[StringToken], c = [StringToken]$[SimpleToken]c[StringToken]"[StringToken])[SimpleToken];[SimpleToken]
|
||||
}[SimpleToken]
|
||||
[SimpleToken]
|
Loading…
Reference in a new issue