[stable] [parser] Support nullable record types in patterns Not fixed for nullable record types in https://dart-review.googlesource.com/c/sdk/+/280106. Fixes: https://github.com/dart-lang/sdk/issues/52518 Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/304642 Change-Id: I5861b9fa7a0a6b8dce1b8965f6f4ef58123133a6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305824 Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Jens Johansen <jensj@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart index 92d622d..c483831 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -7921,7 +7921,6 @@ typeInfo.isNullable && typeInfo.couldBeExpression) { assert(optional('?', token)); - assert(next.isKeywordOrIdentifier); if (!looksLikeName(next)) { reportRecoverableError( next, codes.templateExpectedIdentifier.withArguments(next)); @@ -9775,8 +9774,12 @@ return parseVariablePattern(token, patternContext); case '(': // "(" could start a record type (which has to be followed by an - // identifier though), e.g. `(int, int) foo`. - if (next.endGroup!.next!.isIdentifier) { + // identifier (or ? identifier) though), e.g. `(int, int) foo` + // or `(int, int)? bar`. + Token afterEndGroup = next.endGroup!.next!; + if (afterEndGroup.isIdentifier || + (optional("?", afterEndGroup) && + afterEndGroup.next!.isIdentifier)) { TypeInfo typeInfo = computeVariablePatternType(token); if (typeInfo is ComplexTypeInfo && typeInfo.isRecordType &&
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51169.dart b/pkg/front_end/parser_testcases/patterns/issue_51169.dart index 4a55399..8e1ea43 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51169.dart +++ b/pkg/front_end/parser_testcases/patterns/issue_51169.dart
@@ -15,3 +15,12 @@ print(b); } } + +testNullable(a) { + switch (a) { + case (foo: (int, int)? b) when b != (2, 3): + print(b); + case Class(field: (int, int)? b) when b != (2, 3): + print(b); + } +}
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51169.dart.expect b/pkg/front_end/parser_testcases/patterns/issue_51169.dart.expect index e04d78c..9ac2d3e 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51169.dart.expect +++ b/pkg/front_end/parser_testcases/patterns/issue_51169.dart.expect
@@ -235,5 +235,133 @@ endSwitchStatement(switch, }) endBlockFunctionBody(1, {, }) endTopLevelMethod(test, null, }) + endTopLevelDeclaration(testNullable) + beginMetadataStar(testNullable) + endMetadataStar(0) + beginTopLevelMember(testNullable) + beginTopLevelMethod(}, null, null) + handleNoType(}) + handleIdentifier(testNullable, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + beginMetadataStar(a) + endMetadataStar(0) + beginFormalParameter(a, MemberKind.TopLevelMethod, null, null, null) + handleNoType(() + handleIdentifier(a, formalParameterDeclaration) + handleFormalParameterWithoutValue()) + endFormalParameter(null, null, null, a, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod) + endFormalParameters(1, (, ), MemberKind.TopLevelMethod) + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + beginSwitchStatement(switch) + handleIdentifier(a, expression) + handleNoTypeArguments()) + handleNoArguments()) + handleSend(a, )) + handleParenthesizedCondition((, null, null) + beginSwitchBlock({) + beginCaseExpression(case) + handleIdentifier(foo, namedRecordFieldReference) + beginRecordType(() + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(,) + handleType(int, null) + handleNoName(,) + endRecordTypeEntry() + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments()) + handleType(int, null) + handleNoName()) + endRecordTypeEntry() + endRecordType((, ?, 2, false) + handleDeclaredVariablePattern(null, b, false) + handlePatternField(:) + handleRecordPattern((, 1) + beginSwitchCaseWhenClause(when) + handleIdentifier(b, expression) + handleNoTypeArguments(!=) + handleNoArguments(!=) + handleSend(b, !=) + beginBinaryExpression(!=) + beginParenthesizedExpressionOrRecordLiteral(() + handleLiteralInt(2) + handleLiteralInt(3) + endRecordLiteral((, 2, null) + endBinaryExpression(!=) + endSwitchCaseWhenClause()) + endCaseExpression(case, when, :) + beginSwitchCase(0, 1, case) + handleIdentifier(print, expression) + handleNoTypeArguments(() + beginArguments(() + handleIdentifier(b, expression) + handleNoTypeArguments()) + handleNoArguments()) + handleSend(b, )) + endArguments(1, (, )) + handleSend(print, ;) + handleExpressionStatement(;) + endSwitchCase(0, 1, null, null, 1, case, case) + beginCaseExpression(case) + handleNoTypeArguments(() + handleIdentifier(field, namedArgumentReference) + beginRecordType(() + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(,) + handleType(int, null) + handleNoName(,) + endRecordTypeEntry() + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments()) + handleType(int, null) + handleNoName()) + endRecordTypeEntry() + endRecordType((, ?, 2, false) + handleDeclaredVariablePattern(null, b, false) + handlePatternField(:) + handleObjectPatternFields(1, (, )) + handleObjectPattern(Class, null, null) + beginSwitchCaseWhenClause(when) + handleIdentifier(b, expression) + handleNoTypeArguments(!=) + handleNoArguments(!=) + handleSend(b, !=) + beginBinaryExpression(!=) + beginParenthesizedExpressionOrRecordLiteral(() + handleLiteralInt(2) + handleLiteralInt(3) + endRecordLiteral((, 2, null) + endBinaryExpression(!=) + endSwitchCaseWhenClause()) + endCaseExpression(case, when, :) + beginSwitchCase(0, 1, case) + handleIdentifier(print, expression) + handleNoTypeArguments(() + beginArguments(() + handleIdentifier(b, expression) + handleNoTypeArguments()) + handleNoArguments()) + handleSend(b, )) + endArguments(1, (, )) + handleSend(print, ;) + handleExpressionStatement(;) + endSwitchCase(0, 1, null, null, 1, case, }) + endSwitchBlock(2, {, }) + endSwitchStatement(switch, }) + endBlockFunctionBody(1, {, }) + endTopLevelMethod(testNullable, null, }) endTopLevelDeclaration() -endCompilationUnit(2, ) +endCompilationUnit(3, )
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51169.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/issue_51169.dart.intertwined.expect index 66e6407..6d508db 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51169.dart.intertwined.expect +++ b/pkg/front_end/parser_testcases/patterns/issue_51169.dart.intertwined.expect
@@ -606,6 +606,340 @@ notEofOrValue(}, }) listener: endBlockFunctionBody(1, {, }) listener: endTopLevelMethod(test, null, }) + listener: endTopLevelDeclaration(testNullable) + parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext') + parseMetadataStar(}) + listener: beginMetadataStar(testNullable) + listener: endMetadataStar(0) + parseTopLevelMemberImpl(}) + listener: beginTopLevelMember(testNullable) + isReservedKeyword(() + parseTopLevelMethod(}, null, null, }, Instance of 'NoType', null, testNullable, false) + listener: beginTopLevelMethod(}, null, null) + listener: handleNoType(}) + ensureIdentifierPotentiallyRecovered(}, topLevelFunctionDeclaration, false) + listener: handleIdentifier(testNullable, topLevelFunctionDeclaration) + parseMethodTypeVar(testNullable) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(testNullable, testNullable, false, MemberKind.TopLevelMethod) + parseFormalParameters(testNullable, MemberKind.TopLevelMethod) + parseFormalParametersRest((, MemberKind.TopLevelMethod) + listener: beginFormalParameters((, MemberKind.TopLevelMethod) + parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod) + parseMetadataStar(() + listener: beginMetadataStar(a) + listener: endMetadataStar(0) + listener: beginFormalParameter(a, MemberKind.TopLevelMethod, null, null, null) + listener: handleNoType(() + ensureIdentifier((, formalParameterDeclaration) + listener: handleIdentifier(a, formalParameterDeclaration) + listener: handleFormalParameterWithoutValue()) + listener: endFormalParameter(null, null, null, a, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod) + listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod) + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + parseFunctionBody(), false, false) + listener: beginBlockFunctionBody({) + notEofOrValue(}, switch) + parseStatement({) + parseStatementX({) + parseSwitchStatement({) + listener: beginSwitchStatement(switch) + ensureParenthesizedCondition(switch, allowCase: false) + parseExpressionInParenthesisRest((, allowCase: false) + parseExpression(() + looksLikeOuterPatternEquals(() + skipOuterPattern(() + skipObjectPatternRest(a) + 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(a, expression) + listener: handleNoTypeArguments()) + parseArgumentsOpt(a) + listener: handleNoArguments()) + listener: handleSend(a, )) + ensureCloseParen(a, () + listener: handleParenthesizedCondition((, null, null) + parseSwitchBlock()) + ensureBlock(), null, switch statement) + listener: beginSwitchBlock({) + notEofOrValue(}, case) + peekPastLabels(case) + listener: beginCaseExpression(case) + parsePattern(case, PatternContext.matching, precedence: 1) + parsePrimaryPattern(case, PatternContext.matching) + parseParenthesizedPatternOrRecordPattern(case, PatternContext.matching) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(foo, namedRecordFieldReference) + parsePattern(:, PatternContext.matching, precedence: 1) + parsePrimaryPattern(:, PatternContext.matching) + parseVariablePattern(:, PatternContext.matching, typeInfo: Instance of 'ComplexTypeInfo') + parseRecordType((, :, true) + listener: beginRecordType(() + parseRecordTypeField((, identifierIsOptional: true) + listener: beginRecordTypeEntry() + parseMetadataStar(() + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(,) + listener: handleType(int, null) + listener: handleNoName(,) + listener: endRecordTypeEntry() + parseRecordTypeField(,, identifierIsOptional: true) + listener: beginRecordTypeEntry() + parseMetadataStar(,) + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments()) + listener: handleType(int, null) + listener: handleNoName()) + listener: endRecordTypeEntry() + listener: endRecordType((, ?, 2, false) + listener: handleDeclaredVariablePattern(null, b, false) + listener: handlePatternField(:) + ensureCloseParen(b, () + listener: handleRecordPattern((, 1) + listener: beginSwitchCaseWhenClause(when) + parseExpression(when) + looksLikeOuterPatternEquals(when) + skipOuterPattern(when) + skipObjectPatternRest(b) + parsePrecedenceExpression(when, 1, true, ConstantPatternContext.none) + parseUnaryExpression(when, true, ConstantPatternContext.none) + parsePrimary(when, expression, ConstantPatternContext.none) + parseSendOrFunctionLiteral(when, expression, ConstantPatternContext.none) + parseSend(when, expression, ConstantPatternContext.none) + isNextIdentifier(when) + ensureIdentifier(when, expression) + listener: handleIdentifier(b, expression) + listener: handleNoTypeArguments(!=) + parseArgumentsOpt(b) + listener: handleNoArguments(!=) + listener: handleSend(b, !=) + listener: beginBinaryExpression(!=) + parsePrecedenceExpression(!=, 8, 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) + parseLiteralInt(() + listener: handleLiteralInt(2) + 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: endBinaryExpression(!=) + listener: endSwitchCaseWhenClause()) + ensureColon()) + listener: endCaseExpression(case, when, :) + peekPastLabels(print) + parseStatementsInSwitchCase(:, print, case, 0, 1, null, null) + listener: beginSwitchCase(0, 1, case) + 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(() + skipObjectPatternRest(b) + 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(b, expression) + listener: handleNoTypeArguments()) + parseArgumentsOpt(b) + listener: handleNoArguments()) + listener: handleSend(b, )) + listener: endArguments(1, (, )) + listener: handleSend(print, ;) + ensureSemicolon()) + listener: handleExpressionStatement(;) + peekPastLabels(case) + listener: endSwitchCase(0, 1, null, null, 1, case, case) + notEofOrValue(}, case) + peekPastLabels(case) + listener: beginCaseExpression(case) + parsePattern(case, PatternContext.matching, precedence: 1) + parsePrimaryPattern(case, PatternContext.matching) + listener: handleNoTypeArguments(() + parseObjectPatternRest(Class, PatternContext.matching) + ensureIdentifier((, namedArgumentReference) + listener: handleIdentifier(field, namedArgumentReference) + parsePattern(:, PatternContext.matching, precedence: 1) + parsePrimaryPattern(:, PatternContext.matching) + parseVariablePattern(:, PatternContext.matching, typeInfo: Instance of 'ComplexTypeInfo') + parseRecordType((, :, true) + listener: beginRecordType(() + parseRecordTypeField((, identifierIsOptional: true) + listener: beginRecordTypeEntry() + parseMetadataStar(() + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(,) + listener: handleType(int, null) + listener: handleNoName(,) + listener: endRecordTypeEntry() + parseRecordTypeField(,, identifierIsOptional: true) + listener: beginRecordTypeEntry() + parseMetadataStar(,) + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments()) + listener: handleType(int, null) + listener: handleNoName()) + listener: endRecordTypeEntry() + listener: endRecordType((, ?, 2, false) + listener: handleDeclaredVariablePattern(null, b, false) + listener: handlePatternField(:) + listener: handleObjectPatternFields(1, (, )) + listener: handleObjectPattern(Class, null, null) + listener: beginSwitchCaseWhenClause(when) + parseExpression(when) + looksLikeOuterPatternEquals(when) + skipOuterPattern(when) + skipObjectPatternRest(b) + parsePrecedenceExpression(when, 1, true, ConstantPatternContext.none) + parseUnaryExpression(when, true, ConstantPatternContext.none) + parsePrimary(when, expression, ConstantPatternContext.none) + parseSendOrFunctionLiteral(when, expression, ConstantPatternContext.none) + parseSend(when, expression, ConstantPatternContext.none) + isNextIdentifier(when) + ensureIdentifier(when, expression) + listener: handleIdentifier(b, expression) + listener: handleNoTypeArguments(!=) + parseArgumentsOpt(b) + listener: handleNoArguments(!=) + listener: handleSend(b, !=) + listener: beginBinaryExpression(!=) + parsePrecedenceExpression(!=, 8, 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) + parseLiteralInt(() + listener: handleLiteralInt(2) + 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: endBinaryExpression(!=) + listener: endSwitchCaseWhenClause()) + ensureColon()) + listener: endCaseExpression(case, when, :) + peekPastLabels(print) + parseStatementsInSwitchCase(:, print, case, 0, 1, null, null) + listener: beginSwitchCase(0, 1, case) + 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(() + skipObjectPatternRest(b) + 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(b, expression) + listener: handleNoTypeArguments()) + parseArgumentsOpt(b) + listener: handleNoArguments()) + listener: handleSend(b, )) + listener: endArguments(1, (, )) + listener: handleSend(print, ;) + ensureSemicolon()) + listener: handleExpressionStatement(;) + peekPastLabels(}) + listener: endSwitchCase(0, 1, null, null, 1, case, }) + notEofOrValue(}, }) + listener: endSwitchBlock(2, {, }) + listener: endSwitchStatement(switch, }) + notEofOrValue(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endTopLevelMethod(testNullable, null, }) listener: endTopLevelDeclaration() reportAllErrorTokens(class) - listener: endCompilationUnit(2, ) + listener: endCompilationUnit(3, )
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51169.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/issue_51169.dart.parser.expect index bc3e020..29dd81d 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51169.dart.parser.expect +++ b/pkg/front_end/parser_testcases/patterns/issue_51169.dart.parser.expect
@@ -16,6 +16,15 @@ } } +testNullable(a) { +switch (a) { +case (foo: (int, int)? b) when b != (2, 3): +print(b); +case Class(field: (int, int)? b) when b != (2, 3): +print(b); +} +} + class[KeywordToken] Class[StringToken] {[BeginToken] dynamic[KeywordToken] field[StringToken];[SimpleToken] @@ -34,4 +43,13 @@ print[StringToken]([BeginToken]b[StringToken])[SimpleToken];[SimpleToken] }[SimpleToken] }[SimpleToken] + +testNullable[StringToken]([BeginToken]a[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]a[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] ([BeginToken]foo[StringToken]:[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]?[SimpleToken] b[StringToken])[SimpleToken] when[KeywordToken] b[StringToken] !=[SimpleToken] ([BeginToken]2[StringToken],[SimpleToken] 3[StringToken])[SimpleToken]:[SimpleToken] +print[StringToken]([BeginToken]b[StringToken])[SimpleToken];[SimpleToken] +case[KeywordToken] Class[StringToken]([BeginToken]field[StringToken]:[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]?[SimpleToken] b[StringToken])[SimpleToken] when[KeywordToken] b[StringToken] !=[SimpleToken] ([BeginToken]2[StringToken],[SimpleToken] 3[StringToken])[SimpleToken]:[SimpleToken] +print[StringToken]([BeginToken]b[StringToken])[SimpleToken];[SimpleToken] +}[SimpleToken] +}[SimpleToken] [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51169.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/issue_51169.dart.scanner.expect index bc3e020..29dd81d 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51169.dart.scanner.expect +++ b/pkg/front_end/parser_testcases/patterns/issue_51169.dart.scanner.expect
@@ -16,6 +16,15 @@ } } +testNullable(a) { +switch (a) { +case (foo: (int, int)? b) when b != (2, 3): +print(b); +case Class(field: (int, int)? b) when b != (2, 3): +print(b); +} +} + class[KeywordToken] Class[StringToken] {[BeginToken] dynamic[KeywordToken] field[StringToken];[SimpleToken] @@ -34,4 +43,13 @@ print[StringToken]([BeginToken]b[StringToken])[SimpleToken];[SimpleToken] }[SimpleToken] }[SimpleToken] + +testNullable[StringToken]([BeginToken]a[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]a[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] ([BeginToken]foo[StringToken]:[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]?[SimpleToken] b[StringToken])[SimpleToken] when[KeywordToken] b[StringToken] !=[SimpleToken] ([BeginToken]2[StringToken],[SimpleToken] 3[StringToken])[SimpleToken]:[SimpleToken] +print[StringToken]([BeginToken]b[StringToken])[SimpleToken];[SimpleToken] +case[KeywordToken] Class[StringToken]([BeginToken]field[StringToken]:[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]?[SimpleToken] b[StringToken])[SimpleToken] when[KeywordToken] b[StringToken] !=[SimpleToken] ([BeginToken]2[StringToken],[SimpleToken] 3[StringToken])[SimpleToken]:[SimpleToken] +print[StringToken]([BeginToken]b[StringToken])[SimpleToken];[SimpleToken] +}[SimpleToken] +}[SimpleToken] [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51176.dart b/pkg/front_end/parser_testcases/patterns/issue_51176.dart index f34ab34..4d85b08 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51176.dart +++ b/pkg/front_end/parser_testcases/patterns/issue_51176.dart
@@ -14,4 +14,20 @@ var (n: (int, {int x}) a10, (int z, {int y}) b10) = (n: (x: 42, -1), (y: 1, 0)); + + var ((a1,)?,) = (null,); + var (n: (x: a2)?) = (n: null); + var (n: (x: a3, b3)?, (y: c3, d3)?) = (n: null, null); + + final ((a4,)?,) = (null,); + final (n: (x: a5)?) = (n: null); + final (n: (x: a6, b6)?, (y: c6, d6)?) = (n: null, null); + + var ((int a7,)?,) = (null,); + var (n: (x: int a8)?) = (n: null); + var (n: (x: int a9, int b9)?, (y: int c9, int d9)?) + = (n: null, null); + + var (n: (int, {int x})? a10, (int z, {int y})? b10) + = (n: null, null); }
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51176.dart.expect b/pkg/front_end/parser_testcases/patterns/issue_51176.dart.expect index 4d8bd96..337be13 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51176.dart.expect +++ b/pkg/front_end/parser_testcases/patterns/issue_51176.dart.expect
@@ -313,7 +313,257 @@ endRecordLiteral((, 2, null) endRecordLiteral((, 2, null) handlePatternVariableDeclarationStatement(var, =, ;) - endBlockFunctionBody(10, {, }) + beginMetadataStar(var) + endMetadataStar(0) + handleNoType(a1) + handleDeclaredVariablePattern(null, a1, false) + handlePatternField(null) + handleRecordPattern((, 1) + handleNullCheckPattern(?) + handlePatternField(null) + handleRecordPattern((, 1) + beginParenthesizedExpressionOrRecordLiteral(() + handleLiteralNull(null) + endRecordLiteral((, 1, null) + handlePatternVariableDeclarationStatement(var, =, ;) + beginMetadataStar(var) + endMetadataStar(0) + handleIdentifier(n, namedRecordFieldReference) + handleIdentifier(x, namedRecordFieldReference) + handleNoType(a2) + handleDeclaredVariablePattern(null, a2, false) + handlePatternField(:) + handleRecordPattern((, 1) + handleNullCheckPattern(?) + handlePatternField(:) + handleRecordPattern((, 1) + beginParenthesizedExpressionOrRecordLiteral(() + handleIdentifier(n, namedRecordFieldReference) + handleLiteralNull(null) + handleNamedRecordField(:) + endRecordLiteral((, 1, null) + handlePatternVariableDeclarationStatement(var, =, ;) + beginMetadataStar(var) + endMetadataStar(0) + handleIdentifier(n, namedRecordFieldReference) + handleIdentifier(x, namedRecordFieldReference) + handleNoType(a3) + handleDeclaredVariablePattern(null, a3, false) + handlePatternField(:) + handleNoType(b3) + handleDeclaredVariablePattern(null, b3, false) + handlePatternField(null) + handleRecordPattern((, 2) + handleNullCheckPattern(?) + handlePatternField(:) + handleIdentifier(y, namedRecordFieldReference) + handleNoType(c3) + handleDeclaredVariablePattern(null, c3, false) + handlePatternField(:) + handleNoType(d3) + handleDeclaredVariablePattern(null, d3, false) + handlePatternField(null) + handleRecordPattern((, 2) + handleNullCheckPattern(?) + handlePatternField(null) + handleRecordPattern((, 2) + beginParenthesizedExpressionOrRecordLiteral(() + handleIdentifier(n, namedRecordFieldReference) + handleLiteralNull(null) + handleNamedRecordField(:) + handleLiteralNull(null) + endRecordLiteral((, 2, null) + handlePatternVariableDeclarationStatement(var, =, ;) + beginMetadataStar(final) + endMetadataStar(0) + handleNoType(a4) + handleDeclaredVariablePattern(null, a4, false) + handlePatternField(null) + handleRecordPattern((, 1) + handleNullCheckPattern(?) + handlePatternField(null) + handleRecordPattern((, 1) + beginParenthesizedExpressionOrRecordLiteral(() + handleLiteralNull(null) + endRecordLiteral((, 1, null) + handlePatternVariableDeclarationStatement(final, =, ;) + beginMetadataStar(final) + endMetadataStar(0) + handleIdentifier(n, namedRecordFieldReference) + handleIdentifier(x, namedRecordFieldReference) + handleNoType(a5) + handleDeclaredVariablePattern(null, a5, false) + handlePatternField(:) + handleRecordPattern((, 1) + handleNullCheckPattern(?) + handlePatternField(:) + handleRecordPattern((, 1) + beginParenthesizedExpressionOrRecordLiteral(() + handleIdentifier(n, namedRecordFieldReference) + handleLiteralNull(null) + handleNamedRecordField(:) + endRecordLiteral((, 1, null) + handlePatternVariableDeclarationStatement(final, =, ;) + beginMetadataStar(final) + endMetadataStar(0) + handleIdentifier(n, namedRecordFieldReference) + handleIdentifier(x, namedRecordFieldReference) + handleNoType(a6) + handleDeclaredVariablePattern(null, a6, false) + handlePatternField(:) + handleNoType(b6) + handleDeclaredVariablePattern(null, b6, false) + handlePatternField(null) + handleRecordPattern((, 2) + handleNullCheckPattern(?) + handlePatternField(:) + handleIdentifier(y, namedRecordFieldReference) + handleNoType(c6) + handleDeclaredVariablePattern(null, c6, false) + handlePatternField(:) + handleNoType(d6) + handleDeclaredVariablePattern(null, d6, false) + handlePatternField(null) + handleRecordPattern((, 2) + handleNullCheckPattern(?) + handlePatternField(null) + handleRecordPattern((, 2) + beginParenthesizedExpressionOrRecordLiteral(() + handleIdentifier(n, namedRecordFieldReference) + handleLiteralNull(null) + handleNamedRecordField(:) + handleLiteralNull(null) + endRecordLiteral((, 2, null) + handlePatternVariableDeclarationStatement(final, =, ;) + beginMetadataStar(var) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(a7) + handleType(int, null) + handleDeclaredVariablePattern(null, a7, false) + handlePatternField(null) + handleRecordPattern((, 1) + handleNullCheckPattern(?) + handlePatternField(null) + handleRecordPattern((, 1) + beginParenthesizedExpressionOrRecordLiteral(() + handleLiteralNull(null) + endRecordLiteral((, 1, null) + handlePatternVariableDeclarationStatement(var, =, ;) + beginMetadataStar(var) + endMetadataStar(0) + handleIdentifier(n, namedRecordFieldReference) + handleIdentifier(x, namedRecordFieldReference) + handleIdentifier(int, typeReference) + handleNoTypeArguments(a8) + handleType(int, null) + handleDeclaredVariablePattern(null, a8, false) + handlePatternField(:) + handleRecordPattern((, 1) + handleNullCheckPattern(?) + handlePatternField(:) + handleRecordPattern((, 1) + beginParenthesizedExpressionOrRecordLiteral(() + handleIdentifier(n, namedRecordFieldReference) + handleLiteralNull(null) + handleNamedRecordField(:) + endRecordLiteral((, 1, null) + handlePatternVariableDeclarationStatement(var, =, ;) + beginMetadataStar(var) + endMetadataStar(0) + handleIdentifier(n, namedRecordFieldReference) + handleIdentifier(x, namedRecordFieldReference) + handleIdentifier(int, typeReference) + handleNoTypeArguments(a9) + handleType(int, null) + handleDeclaredVariablePattern(null, a9, false) + handlePatternField(:) + handleIdentifier(int, typeReference) + handleNoTypeArguments(b9) + handleType(int, null) + handleDeclaredVariablePattern(null, b9, false) + handlePatternField(null) + handleRecordPattern((, 2) + handleNullCheckPattern(?) + handlePatternField(:) + handleIdentifier(y, namedRecordFieldReference) + handleIdentifier(int, typeReference) + handleNoTypeArguments(c9) + handleType(int, null) + handleDeclaredVariablePattern(null, c9, false) + handlePatternField(:) + handleIdentifier(int, typeReference) + handleNoTypeArguments(d9) + handleType(int, null) + handleDeclaredVariablePattern(null, d9, false) + handlePatternField(null) + handleRecordPattern((, 2) + handleNullCheckPattern(?) + handlePatternField(null) + handleRecordPattern((, 2) + beginParenthesizedExpressionOrRecordLiteral(() + handleIdentifier(n, namedRecordFieldReference) + handleLiteralNull(null) + handleNamedRecordField(:) + handleLiteralNull(null) + endRecordLiteral((, 2, null) + handlePatternVariableDeclarationStatement(var, =, ;) + beginMetadataStar(var) + endMetadataStar(0) + handleIdentifier(n, namedRecordFieldReference) + beginRecordType(() + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(,) + handleType(int, null) + handleNoName(,) + endRecordTypeEntry() + beginRecordTypeNamedFields({) + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(x) + handleType(int, null) + handleIdentifier(x, recordFieldDeclaration) + endRecordTypeEntry() + endRecordTypeNamedFields(1, {) + endRecordType((, ?, 2, true) + handleDeclaredVariablePattern(null, a10, false) + handlePatternField(:) + beginRecordType(() + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(z) + handleType(int, null) + handleIdentifier(z, recordFieldDeclaration) + endRecordTypeEntry() + beginRecordTypeNamedFields({) + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(y) + handleType(int, null) + handleIdentifier(y, recordFieldDeclaration) + endRecordTypeEntry() + endRecordTypeNamedFields(1, {) + endRecordType((, ?, 2, true) + handleDeclaredVariablePattern(null, b10, false) + handlePatternField(null) + handleRecordPattern((, 2) + beginParenthesizedExpressionOrRecordLiteral(() + handleIdentifier(n, namedRecordFieldReference) + handleLiteralNull(null) + handleNamedRecordField(:) + handleLiteralNull(null) + endRecordLiteral((, 2, null) + handlePatternVariableDeclarationStatement(var, =, ;) + endBlockFunctionBody(20, {, }) endTopLevelMethod(main, null, }) endTopLevelDeclaration() endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51176.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/issue_51176.dart.intertwined.expect index 457e412..bd2eeb7 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51176.dart.intertwined.expect +++ b/pkg/front_end/parser_testcases/patterns/issue_51176.dart.intertwined.expect
@@ -982,8 +982,704 @@ listener: endRecordLiteral((, 2, null) ensureSemicolon()) listener: handlePatternVariableDeclarationStatement(var, =, ;) + notEofOrValue(}, var) + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, null) + skipOuterPattern(var) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + parsePatternVariableDeclarationStatement(var, ;, var) + parsePattern(var, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(var, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration) + parsePattern((, PatternContext.declaration, precedence: 1) + parsePrimaryPattern((, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern((, PatternContext.declaration) + parsePattern((, PatternContext.declaration, precedence: 1) + parsePrimaryPattern((, PatternContext.declaration) + parseVariablePattern((, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(a1) + listener: handleDeclaredVariablePattern(null, a1, false) + listener: handlePatternField(null) + ensureCloseParen(,, () + listener: handleRecordPattern((, 1) + listener: handleNullCheckPattern(?) + listener: handlePatternField(null) + ensureCloseParen(,, () + listener: handleRecordPattern((, 1) + 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) + parseLiteralNull(() + listener: handleLiteralNull(null) + ensureCloseParen(,, () + listener: endRecordLiteral((, 1, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(var, =, ;) + notEofOrValue(}, var) + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, null) + skipOuterPattern(var) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + parsePatternVariableDeclarationStatement(var, ;, var) + parsePattern(var, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(var, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(n, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(:, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(x, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(a2) + listener: handleDeclaredVariablePattern(null, a2, false) + listener: handlePatternField(:) + ensureCloseParen(a2, () + listener: handleRecordPattern((, 1) + listener: handleNullCheckPattern(?) + listener: handlePatternField(:) + ensureCloseParen(?, () + listener: handleRecordPattern((, 1) + 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(n, namedRecordFieldReference) + parseExpression(:) + looksLikeOuterPatternEquals(:) + skipOuterPattern(:) + parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none) + parseUnaryExpression(:, true, ConstantPatternContext.none) + parsePrimary(:, expression, ConstantPatternContext.none) + parseLiteralNull(:) + listener: handleLiteralNull(null) + listener: handleNamedRecordField(:) + ensureCloseParen(null, () + listener: endRecordLiteral((, 1, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(var, =, ;) + notEofOrValue(}, var) + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, null) + skipOuterPattern(var) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + parsePatternVariableDeclarationStatement(var, ;, var) + parsePattern(var, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(var, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(n, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(:, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(x, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(a3) + listener: handleDeclaredVariablePattern(null, a3, false) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(b3) + listener: handleDeclaredVariablePattern(null, b3, false) + listener: handlePatternField(null) + ensureCloseParen(b3, () + listener: handleRecordPattern((, 2) + listener: handleNullCheckPattern(?) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(,, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(y, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(c3) + listener: handleDeclaredVariablePattern(null, c3, false) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(d3) + listener: handleDeclaredVariablePattern(null, d3, false) + listener: handlePatternField(null) + ensureCloseParen(d3, () + listener: handleRecordPattern((, 2) + listener: handleNullCheckPattern(?) + listener: handlePatternField(null) + ensureCloseParen(?, () + listener: handleRecordPattern((, 2) + 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(n, namedRecordFieldReference) + parseExpression(:) + looksLikeOuterPatternEquals(:) + skipOuterPattern(:) + parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none) + parseUnaryExpression(:, true, ConstantPatternContext.none) + parsePrimary(:, expression, ConstantPatternContext.none) + parseLiteralNull(:) + listener: handleLiteralNull(null) + listener: handleNamedRecordField(:) + parseExpression(,) + looksLikeOuterPatternEquals(,) + skipOuterPattern(,) + parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none) + parseUnaryExpression(,, true, ConstantPatternContext.none) + parsePrimary(,, expression, ConstantPatternContext.none) + parseLiteralNull(,) + listener: handleLiteralNull(null) + ensureCloseParen(null, () + listener: endRecordLiteral((, 2, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(var, =, ;) + 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) + parsePrimaryPattern(final, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(final, PatternContext.declaration) + parsePattern((, PatternContext.declaration, precedence: 1) + parsePrimaryPattern((, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern((, PatternContext.declaration) + parsePattern((, PatternContext.declaration, precedence: 1) + parsePrimaryPattern((, PatternContext.declaration) + parseVariablePattern((, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(a4) + listener: handleDeclaredVariablePattern(null, a4, false) + listener: handlePatternField(null) + ensureCloseParen(,, () + listener: handleRecordPattern((, 1) + listener: handleNullCheckPattern(?) + listener: handlePatternField(null) + ensureCloseParen(,, () + listener: handleRecordPattern((, 1) + 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) + parseLiteralNull(() + listener: handleLiteralNull(null) + ensureCloseParen(,, () + listener: endRecordLiteral((, 1, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(final, =, ;) + 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) + parsePrimaryPattern(final, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(final, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(n, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(:, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(x, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(a5) + listener: handleDeclaredVariablePattern(null, a5, false) + listener: handlePatternField(:) + ensureCloseParen(a5, () + listener: handleRecordPattern((, 1) + listener: handleNullCheckPattern(?) + listener: handlePatternField(:) + ensureCloseParen(?, () + listener: handleRecordPattern((, 1) + 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(n, namedRecordFieldReference) + parseExpression(:) + looksLikeOuterPatternEquals(:) + skipOuterPattern(:) + parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none) + parseUnaryExpression(:, true, ConstantPatternContext.none) + parsePrimary(:, expression, ConstantPatternContext.none) + parseLiteralNull(:) + listener: handleLiteralNull(null) + listener: handleNamedRecordField(:) + ensureCloseParen(null, () + listener: endRecordLiteral((, 1, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(final, =, ;) + 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) + parsePrimaryPattern(final, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(final, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(n, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(:, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(x, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(a6) + listener: handleDeclaredVariablePattern(null, a6, false) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(b6) + listener: handleDeclaredVariablePattern(null, b6, false) + listener: handlePatternField(null) + ensureCloseParen(b6, () + listener: handleRecordPattern((, 2) + listener: handleNullCheckPattern(?) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(,, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(y, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(c6) + listener: handleDeclaredVariablePattern(null, c6, false) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'NoType') + listener: handleNoType(d6) + listener: handleDeclaredVariablePattern(null, d6, false) + listener: handlePatternField(null) + ensureCloseParen(d6, () + listener: handleRecordPattern((, 2) + listener: handleNullCheckPattern(?) + listener: handlePatternField(null) + ensureCloseParen(?, () + listener: handleRecordPattern((, 2) + 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(n, namedRecordFieldReference) + parseExpression(:) + looksLikeOuterPatternEquals(:) + skipOuterPattern(:) + parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none) + parseUnaryExpression(:, true, ConstantPatternContext.none) + parsePrimary(:, expression, ConstantPatternContext.none) + parseLiteralNull(:) + listener: handleLiteralNull(null) + listener: handleNamedRecordField(:) + parseExpression(,) + looksLikeOuterPatternEquals(,) + skipOuterPattern(,) + parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none) + parseUnaryExpression(,, true, ConstantPatternContext.none) + parsePrimary(,, expression, ConstantPatternContext.none) + parseLiteralNull(,) + listener: handleLiteralNull(null) + ensureCloseParen(null, () + listener: endRecordLiteral((, 2, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(final, =, ;) + notEofOrValue(}, var) + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, null) + skipOuterPattern(var) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + parsePatternVariableDeclarationStatement(var, ;, var) + parsePattern(var, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(var, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration) + parsePattern((, PatternContext.declaration, precedence: 1) + parsePrimaryPattern((, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern((, PatternContext.declaration) + parsePattern((, PatternContext.declaration, precedence: 1) + parsePrimaryPattern((, PatternContext.declaration) + parseVariablePattern((, PatternContext.declaration, typeInfo: Instance of 'SimpleType') + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(a7) + listener: handleType(int, null) + listener: handleDeclaredVariablePattern(null, a7, false) + listener: handlePatternField(null) + ensureCloseParen(,, () + listener: handleRecordPattern((, 1) + listener: handleNullCheckPattern(?) + listener: handlePatternField(null) + ensureCloseParen(,, () + listener: handleRecordPattern((, 1) + 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) + parseLiteralNull(() + listener: handleLiteralNull(null) + ensureCloseParen(,, () + listener: endRecordLiteral((, 1, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(var, =, ;) + notEofOrValue(}, var) + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, null) + skipOuterPattern(var) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + parsePatternVariableDeclarationStatement(var, ;, var) + parsePattern(var, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(var, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(n, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(:, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(x, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'SimpleType') + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(a8) + listener: handleType(int, null) + listener: handleDeclaredVariablePattern(null, a8, false) + listener: handlePatternField(:) + ensureCloseParen(a8, () + listener: handleRecordPattern((, 1) + listener: handleNullCheckPattern(?) + listener: handlePatternField(:) + ensureCloseParen(?, () + listener: handleRecordPattern((, 1) + 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(n, namedRecordFieldReference) + parseExpression(:) + looksLikeOuterPatternEquals(:) + skipOuterPattern(:) + parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none) + parseUnaryExpression(:, true, ConstantPatternContext.none) + parsePrimary(:, expression, ConstantPatternContext.none) + parseLiteralNull(:) + listener: handleLiteralNull(null) + listener: handleNamedRecordField(:) + ensureCloseParen(null, () + listener: endRecordLiteral((, 1, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(var, =, ;) + notEofOrValue(}, var) + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, null) + skipOuterPattern(var) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + parsePatternVariableDeclarationStatement(var, ;, var) + parsePattern(var, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(var, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(n, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(:, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(x, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'SimpleType') + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(a9) + listener: handleType(int, null) + listener: handleDeclaredVariablePattern(null, a9, false) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'SimpleType') + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(b9) + listener: handleType(int, null) + listener: handleDeclaredVariablePattern(null, b9, false) + listener: handlePatternField(null) + ensureCloseParen(b9, () + listener: handleRecordPattern((, 2) + listener: handleNullCheckPattern(?) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(,, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(y, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'SimpleType') + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(c9) + listener: handleType(int, null) + listener: handleDeclaredVariablePattern(null, c9, false) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'SimpleType') + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(d9) + listener: handleType(int, null) + listener: handleDeclaredVariablePattern(null, d9, false) + listener: handlePatternField(null) + ensureCloseParen(d9, () + listener: handleRecordPattern((, 2) + listener: handleNullCheckPattern(?) + listener: handlePatternField(null) + ensureCloseParen(?, () + listener: handleRecordPattern((, 2) + 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(n, namedRecordFieldReference) + parseExpression(:) + looksLikeOuterPatternEquals(:) + skipOuterPattern(:) + parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none) + parseUnaryExpression(:, true, ConstantPatternContext.none) + parsePrimary(:, expression, ConstantPatternContext.none) + parseLiteralNull(:) + listener: handleLiteralNull(null) + listener: handleNamedRecordField(:) + parseExpression(,) + looksLikeOuterPatternEquals(,) + skipOuterPattern(,) + parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none) + parseUnaryExpression(,, true, ConstantPatternContext.none) + parsePrimary(,, expression, ConstantPatternContext.none) + parseLiteralNull(,) + listener: handleLiteralNull(null) + ensureCloseParen(null, () + listener: endRecordLiteral((, 2, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(var, =, ;) + notEofOrValue(}, var) + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, null) + skipOuterPattern(var) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + parsePatternVariableDeclarationStatement(var, ;, var) + parsePattern(var, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(var, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration) + ensureIdentifier((, namedRecordFieldReference) + listener: handleIdentifier(n, namedRecordFieldReference) + parsePattern(:, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(:, PatternContext.declaration) + parseVariablePattern(:, PatternContext.declaration, typeInfo: Instance of 'ComplexTypeInfo') + parseRecordType((, :, true) + listener: beginRecordType(() + parseRecordTypeField((, identifierIsOptional: true) + listener: beginRecordTypeEntry() + parseMetadataStar(() + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(,) + listener: handleType(int, null) + listener: handleNoName(,) + listener: endRecordTypeEntry() + parseRecordTypeNamedFields(,) + listener: beginRecordTypeNamedFields({) + parseRecordTypeField({, identifierIsOptional: false) + listener: beginRecordTypeEntry() + parseMetadataStar({) + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(x) + listener: handleType(int, null) + ensureIdentifier(int, recordFieldDeclaration) + listener: handleIdentifier(x, recordFieldDeclaration) + listener: endRecordTypeEntry() + listener: endRecordTypeNamedFields(1, {) + ensureCloseParen(}, () + listener: endRecordType((, ?, 2, true) + listener: handleDeclaredVariablePattern(null, a10, false) + listener: handlePatternField(:) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'ComplexTypeInfo') + parseRecordType((, ,, true) + listener: beginRecordType(() + parseRecordTypeField((, identifierIsOptional: true) + listener: beginRecordTypeEntry() + parseMetadataStar(() + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(z) + listener: handleType(int, null) + ensureIdentifier(int, recordFieldDeclaration) + listener: handleIdentifier(z, recordFieldDeclaration) + listener: endRecordTypeEntry() + parseRecordTypeNamedFields(,) + listener: beginRecordTypeNamedFields({) + parseRecordTypeField({, identifierIsOptional: false) + listener: beginRecordTypeEntry() + parseMetadataStar({) + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(y) + listener: handleType(int, null) + ensureIdentifier(int, recordFieldDeclaration) + listener: handleIdentifier(y, recordFieldDeclaration) + listener: endRecordTypeEntry() + listener: endRecordTypeNamedFields(1, {) + ensureCloseParen(}, () + listener: endRecordType((, ?, 2, true) + listener: handleDeclaredVariablePattern(null, b10, false) + listener: handlePatternField(null) + ensureCloseParen(b10, () + listener: handleRecordPattern((, 2) + 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(n, namedRecordFieldReference) + parseExpression(:) + looksLikeOuterPatternEquals(:) + skipOuterPattern(:) + parsePrecedenceExpression(:, 1, true, ConstantPatternContext.none) + parseUnaryExpression(:, true, ConstantPatternContext.none) + parsePrimary(:, expression, ConstantPatternContext.none) + parseLiteralNull(:) + listener: handleLiteralNull(null) + listener: handleNamedRecordField(:) + parseExpression(,) + looksLikeOuterPatternEquals(,) + skipOuterPattern(,) + parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none) + parseUnaryExpression(,, true, ConstantPatternContext.none) + parsePrimary(,, expression, ConstantPatternContext.none) + parseLiteralNull(,) + listener: handleLiteralNull(null) + ensureCloseParen(null, () + listener: endRecordLiteral((, 2, null) + ensureSemicolon()) + listener: handlePatternVariableDeclarationStatement(var, =, ;) notEofOrValue(}, }) - listener: endBlockFunctionBody(10, {, }) + listener: endBlockFunctionBody(20, {, }) listener: endTopLevelMethod(main, null, }) listener: endTopLevelDeclaration() reportAllErrorTokens(main)
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51176.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/issue_51176.dart.parser.expect index ce2b87a..183fa4e 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51176.dart.parser.expect +++ b/pkg/front_end/parser_testcases/patterns/issue_51176.dart.parser.expect
@@ -14,6 +14,22 @@ var (n: (int, {int x}) a10, (int z, {int y}) b10) = (n: (x: 42, -1), (y: 1, 0)); + +var ((a1,)?,) = (null,); +var (n: (x: a2)?) = (n: null); +var (n: (x: a3, b3)?, (y: c3, d3)?) = (n: null, null); + +final ((a4,)?,) = (null,); +final (n: (x: a5)?) = (n: null); +final (n: (x: a6, b6)?, (y: c6, d6)?) = (n: null, null); + +var ((int a7,)?,) = (null,); +var (n: (x: int a8)?) = (n: null); +var (n: (x: int a9, int b9)?, (y: int c9, int d9)?) += (n: null, null); + +var (n: (int, {int x})? a10, (int z, {int y})? b10) += (n: null, null); } @@ -33,5 +49,21 @@ var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] {[BeginToken]int[StringToken] x[StringToken]}[SimpleToken])[SimpleToken] a10[StringToken],[SimpleToken] ([BeginToken]int[StringToken] z[StringToken],[SimpleToken] {[BeginToken]int[StringToken] y[StringToken]}[SimpleToken])[SimpleToken] b10[StringToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] 42[StringToken],[SimpleToken] -[SimpleToken]1[StringToken])[SimpleToken],[SimpleToken] ([BeginToken]y[StringToken]:[SimpleToken] 1[StringToken],[SimpleToken] 0[StringToken])[SimpleToken])[SimpleToken];[SimpleToken] + +var[KeywordToken] ([BeginToken]([BeginToken]a1[StringToken],[SimpleToken])[SimpleToken]?[SimpleToken],[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]null[KeywordToken],[SimpleToken])[SimpleToken];[SimpleToken] +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] a2[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] a3[StringToken],[SimpleToken] b3[StringToken])[SimpleToken]?[SimpleToken],[SimpleToken] ([BeginToken]y[StringToken]:[SimpleToken] c3[StringToken],[SimpleToken] d3[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken],[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] + +final[KeywordToken] ([BeginToken]([BeginToken]a4[StringToken],[SimpleToken])[SimpleToken]?[SimpleToken],[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]null[KeywordToken],[SimpleToken])[SimpleToken];[SimpleToken] +final[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] a5[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] +final[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] a6[StringToken],[SimpleToken] b6[StringToken])[SimpleToken]?[SimpleToken],[SimpleToken] ([BeginToken]y[StringToken]:[SimpleToken] c6[StringToken],[SimpleToken] d6[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken],[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] + +var[KeywordToken] ([BeginToken]([BeginToken]int[StringToken] a7[StringToken],[SimpleToken])[SimpleToken]?[SimpleToken],[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]null[KeywordToken],[SimpleToken])[SimpleToken];[SimpleToken] +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] int[StringToken] a8[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] int[StringToken] a9[StringToken],[SimpleToken] int[StringToken] b9[StringToken])[SimpleToken]?[SimpleToken],[SimpleToken] ([BeginToken]y[StringToken]:[SimpleToken] int[StringToken] c9[StringToken],[SimpleToken] int[StringToken] d9[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] +=[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken],[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] + +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] {[BeginToken]int[StringToken] x[StringToken]}[SimpleToken])[SimpleToken]?[SimpleToken] a10[StringToken],[SimpleToken] ([BeginToken]int[StringToken] z[StringToken],[SimpleToken] {[BeginToken]int[StringToken] y[StringToken]}[SimpleToken])[SimpleToken]?[SimpleToken] b10[StringToken])[SimpleToken] +=[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken],[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] }[SimpleToken] [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/issue_51176.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/issue_51176.dart.scanner.expect index ce2b87a..183fa4e 100644 --- a/pkg/front_end/parser_testcases/patterns/issue_51176.dart.scanner.expect +++ b/pkg/front_end/parser_testcases/patterns/issue_51176.dart.scanner.expect
@@ -14,6 +14,22 @@ var (n: (int, {int x}) a10, (int z, {int y}) b10) = (n: (x: 42, -1), (y: 1, 0)); + +var ((a1,)?,) = (null,); +var (n: (x: a2)?) = (n: null); +var (n: (x: a3, b3)?, (y: c3, d3)?) = (n: null, null); + +final ((a4,)?,) = (null,); +final (n: (x: a5)?) = (n: null); +final (n: (x: a6, b6)?, (y: c6, d6)?) = (n: null, null); + +var ((int a7,)?,) = (null,); +var (n: (x: int a8)?) = (n: null); +var (n: (x: int a9, int b9)?, (y: int c9, int d9)?) += (n: null, null); + +var (n: (int, {int x})? a10, (int z, {int y})? b10) += (n: null, null); } @@ -33,5 +49,21 @@ var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] {[BeginToken]int[StringToken] x[StringToken]}[SimpleToken])[SimpleToken] a10[StringToken],[SimpleToken] ([BeginToken]int[StringToken] z[StringToken],[SimpleToken] {[BeginToken]int[StringToken] y[StringToken]}[SimpleToken])[SimpleToken] b10[StringToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] 42[StringToken],[SimpleToken] -[SimpleToken]1[StringToken])[SimpleToken],[SimpleToken] ([BeginToken]y[StringToken]:[SimpleToken] 1[StringToken],[SimpleToken] 0[StringToken])[SimpleToken])[SimpleToken];[SimpleToken] + +var[KeywordToken] ([BeginToken]([BeginToken]a1[StringToken],[SimpleToken])[SimpleToken]?[SimpleToken],[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]null[KeywordToken],[SimpleToken])[SimpleToken];[SimpleToken] +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] a2[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] a3[StringToken],[SimpleToken] b3[StringToken])[SimpleToken]?[SimpleToken],[SimpleToken] ([BeginToken]y[StringToken]:[SimpleToken] c3[StringToken],[SimpleToken] d3[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken],[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] + +final[KeywordToken] ([BeginToken]([BeginToken]a4[StringToken],[SimpleToken])[SimpleToken]?[SimpleToken],[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]null[KeywordToken],[SimpleToken])[SimpleToken];[SimpleToken] +final[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] a5[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] +final[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] a6[StringToken],[SimpleToken] b6[StringToken])[SimpleToken]?[SimpleToken],[SimpleToken] ([BeginToken]y[StringToken]:[SimpleToken] c6[StringToken],[SimpleToken] d6[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken],[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] + +var[KeywordToken] ([BeginToken]([BeginToken]int[StringToken] a7[StringToken],[SimpleToken])[SimpleToken]?[SimpleToken],[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]null[KeywordToken],[SimpleToken])[SimpleToken];[SimpleToken] +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] int[StringToken] a8[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] =[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]x[StringToken]:[SimpleToken] int[StringToken] a9[StringToken],[SimpleToken] int[StringToken] b9[StringToken])[SimpleToken]?[SimpleToken],[SimpleToken] ([BeginToken]y[StringToken]:[SimpleToken] int[StringToken] c9[StringToken],[SimpleToken] int[StringToken] d9[StringToken])[SimpleToken]?[SimpleToken])[SimpleToken] +=[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken],[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] + +var[KeywordToken] ([BeginToken]n[StringToken]:[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] {[BeginToken]int[StringToken] x[StringToken]}[SimpleToken])[SimpleToken]?[SimpleToken] a10[StringToken],[SimpleToken] ([BeginToken]int[StringToken] z[StringToken],[SimpleToken] {[BeginToken]int[StringToken] y[StringToken]}[SimpleToken])[SimpleToken]?[SimpleToken] b10[StringToken])[SimpleToken] +=[SimpleToken] ([BeginToken]n[StringToken]:[SimpleToken] null[KeywordToken],[SimpleToken] null[KeywordToken])[SimpleToken];[SimpleToken] }[SimpleToken] [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/issue_52439.dart b/pkg/front_end/parser_testcases/patterns/issue_52439.dart new file mode 100644 index 0000000..d06090a --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/issue_52439.dart
@@ -0,0 +1,5 @@ +void main() { + var (int x, (int, )? y) = switch (foo) { + _ => (42, null), + }; +}
diff --git a/pkg/front_end/parser_testcases/patterns/issue_52439.dart.expect b/pkg/front_end/parser_testcases/patterns/issue_52439.dart.expect new file mode 100644 index 0000000..e6eca06 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/issue_52439.dart.expect
@@ -0,0 +1,55 @@ +beginCompilationUnit(void) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(, null, null) + handleVoidKeyword(void) + handleIdentifier(main, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + beginMetadataStar(var) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(x) + handleType(int, null) + handleDeclaredVariablePattern(null, x, false) + handlePatternField(null) + beginRecordType(() + beginRecordTypeEntry() + beginMetadataStar(int) + endMetadataStar(0) + handleIdentifier(int, typeReference) + handleNoTypeArguments(,) + handleType(int, null) + handleNoName(,) + endRecordTypeEntry() + endRecordType((, ?, 1, false) + handleDeclaredVariablePattern(null, y, false) + handlePatternField(null) + handleRecordPattern((, 2) + beginSwitchExpression(switch) + handleIdentifier(foo, expression) + handleNoTypeArguments()) + handleNoArguments()) + handleSend(foo, )) + handleParenthesizedCondition((, null, null) + beginSwitchExpressionBlock({) + beginSwitchExpressionCase() + handleNoType(_) + handleWildcardPattern(null, _) + handleSwitchExpressionCasePattern(_) + beginParenthesizedExpressionOrRecordLiteral(() + handleLiteralInt(42) + handleLiteralNull(null) + endRecordLiteral((, 2, null) + endSwitchExpressionCase(null, =>, )) + endSwitchExpressionBlock(1, {, }) + endSwitchExpression(switch, }) + handlePatternVariableDeclarationStatement(var, =, ;) + endBlockFunctionBody(1, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/issue_52439.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/issue_52439.dart.intertwined.expect new file mode 100644 index 0000000..6d7b50a --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/issue_52439.dart.intertwined.expect
@@ -0,0 +1,143 @@ +parseUnit(void) + skipErrorTokens(void) + listener: beginCompilationUnit(void) + syntheticPreviousToken(void) + parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext') + parseMetadataStar() + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + parseTopLevelMemberImpl() + listener: beginTopLevelMember(void) + parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, main, false) + listener: beginTopLevelMethod(, null, null) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, 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(}, var) + parseStatement({) + parseStatementX({) + parseExpressionStatementOrDeclarationAfterModifiers(var, {, null, var, null, null) + skipOuterPattern(var) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + parsePatternVariableDeclarationStatement(var, {, var) + parsePattern(var, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(var, PatternContext.declaration) + parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration) + parsePattern((, PatternContext.declaration, precedence: 1) + parsePrimaryPattern((, PatternContext.declaration) + parseVariablePattern((, PatternContext.declaration, typeInfo: Instance of 'SimpleType') + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(x) + listener: handleType(int, null) + listener: handleDeclaredVariablePattern(null, x, false) + listener: handlePatternField(null) + parsePattern(,, PatternContext.declaration, precedence: 1) + parsePrimaryPattern(,, PatternContext.declaration) + parseVariablePattern(,, PatternContext.declaration, typeInfo: Instance of 'ComplexTypeInfo') + parseRecordType((, ,, true) + listener: beginRecordType(() + parseRecordTypeField((, identifierIsOptional: true) + listener: beginRecordTypeEntry() + parseMetadataStar(() + listener: beginMetadataStar(int) + listener: endMetadataStar(0) + listener: handleIdentifier(int, typeReference) + listener: handleNoTypeArguments(,) + listener: handleType(int, null) + listener: handleNoName(,) + listener: endRecordTypeEntry() + listener: endRecordType((, ?, 1, false) + listener: handleDeclaredVariablePattern(null, y, false) + listener: handlePatternField(null) + ensureCloseParen(y, () + listener: handleRecordPattern((, 2) + parseExpression(=) + looksLikeOuterPatternEquals(=) + skipOuterPattern(=) + parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none) + parseUnaryExpression(=, true, ConstantPatternContext.none) + parsePrimary(=, expression, ConstantPatternContext.none) + inPlainSync() + parseSwitchExpression(=) + listener: beginSwitchExpression(switch) + ensureParenthesizedCondition(switch, allowCase: false) + parseExpressionInParenthesisRest((, allowCase: false) + parseExpression(() + looksLikeOuterPatternEquals(() + skipOuterPattern(() + skipObjectPatternRest(foo) + 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(foo, expression) + listener: handleNoTypeArguments()) + parseArgumentsOpt(foo) + listener: handleNoArguments()) + listener: handleSend(foo, )) + ensureCloseParen(foo, () + listener: handleParenthesizedCondition((, null, null) + ensureBlock(), null, switch expression) + listener: beginSwitchExpressionBlock({) + listener: beginSwitchExpressionCase() + parsePattern({, PatternContext.matching, precedence: 1) + parsePrimaryPattern({, PatternContext.matching) + parseVariablePattern({, PatternContext.matching, typeInfo: Instance of 'NoType') + listener: handleNoType(_) + listener: handleWildcardPattern(null, _) + listener: handleSwitchExpressionCasePattern(_) + ensureFunctionArrow(_) + 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) + parseLiteralInt(() + listener: handleLiteralInt(42) + parseExpression(,) + looksLikeOuterPatternEquals(,) + skipOuterPattern(,) + parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none) + parseUnaryExpression(,, true, ConstantPatternContext.none) + parsePrimary(,, expression, ConstantPatternContext.none) + parseLiteralNull(,) + listener: handleLiteralNull(null) + ensureCloseParen(null, () + listener: endRecordLiteral((, 2, null) + listener: endSwitchExpressionCase(null, =>, )) + listener: endSwitchExpressionBlock(1, {, }) + listener: endSwitchExpression(switch, }) + ensureSemicolon(}) + listener: handlePatternVariableDeclarationStatement(var, =, ;) + notEofOrValue(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/issue_52439.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/issue_52439.dart.parser.expect new file mode 100644 index 0000000..add3432 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/issue_52439.dart.parser.expect
@@ -0,0 +1,13 @@ +void main() { +var (int x, (int, )? y) = switch (foo) { +_ => (42, null), +}; +} + + +void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken] +var[KeywordToken] ([BeginToken]int[StringToken] x[StringToken],[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] )[SimpleToken]?[SimpleToken] y[StringToken])[SimpleToken] =[SimpleToken] switch[KeywordToken] ([BeginToken]foo[StringToken])[SimpleToken] {[BeginToken] +_[StringToken] =>[SimpleToken] ([BeginToken]42[StringToken],[SimpleToken] null[KeywordToken])[SimpleToken],[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/issue_52439.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/issue_52439.dart.scanner.expect new file mode 100644 index 0000000..add3432 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/issue_52439.dart.scanner.expect
@@ -0,0 +1,13 @@ +void main() { +var (int x, (int, )? y) = switch (foo) { +_ => (42, null), +}; +} + + +void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken] +var[KeywordToken] ([BeginToken]int[StringToken] x[StringToken],[SimpleToken] ([BeginToken]int[StringToken],[SimpleToken] )[SimpleToken]?[SimpleToken] y[StringToken])[SimpleToken] =[SimpleToken] switch[KeywordToken] ([BeginToken]foo[StringToken])[SimpleToken] {[BeginToken] +_[StringToken] =>[SimpleToken] ([BeginToken]42[StringToken],[SimpleToken] null[KeywordToken])[SimpleToken],[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken]
diff --git a/tests/language/patterns/issue_52439.dart b/tests/language/patterns/issue_52439.dart new file mode 100644 index 0000000..53858de --- /dev/null +++ b/tests/language/patterns/issue_52439.dart
@@ -0,0 +1,17 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=records,patterns + +import "package:expect/expect.dart"; + +void main() { + dynamic foo = 84; + var (int x, (int, )? y) = switch (foo) { + _ => (42, null), + }; + Expect.equals(42, x); + Expect.equals(null, y); +} +