mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +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;
|
wasValidRecord = true;
|
||||||
listener.handleNoName(token);
|
listener.handleNoName(token);
|
||||||
colon = token = next;
|
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.
|
// Record with named expression.
|
||||||
wasRecord = true;
|
wasRecord = true;
|
||||||
token = ensureIdentifier(
|
token = ensureIdentifier(
|
||||||
|
@ -10010,6 +10012,9 @@ class Parser {
|
||||||
listener.handleNoName(token);
|
listener.handleNoName(token);
|
||||||
colon = token = next;
|
colon = token = next;
|
||||||
} else if (optional(':', next.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 =
|
token =
|
||||||
ensureIdentifier(token, IdentifierContext.namedArgumentReference)
|
ensureIdentifier(token, IdentifierContext.namedArgumentReference)
|
||||||
.next!;
|
.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