From 213cfdc85ec8eadfd0ff321bbbaccca985ba4d3e Mon Sep 17 00:00:00 2001 From: Dan Rubel Date: Tue, 29 Jan 2019 17:53:58 +0000 Subject: [PATCH] Update AstBuilder to generate new for statement structure ... if control flow or spread collection entries are enabled. Change-Id: I8718c1f7a649b7a2a7c9e376a6bf67c1df0542cf Reviewed-on: https://dart-review.googlesource.com/c/91320 Reviewed-by: Brian Wilkerson --- pkg/analyzer/lib/dart/ast/ast_factory.dart | 3 +- pkg/analyzer/lib/src/fasta/ast_builder.dart | 178 +++++----- .../test/generated/parser_fasta_listener.dart | 8 +- .../test/generated/parser_fasta_test.dart | 327 +++++++++++++++++- pkg/analyzer/test/generated/parser_test.dart | 34 ++ .../lib/src/fasta/kernel/body_builder.dart | 4 +- .../src/fasta/parser/forwarding_listener.dart | 8 +- .../lib/src/fasta/parser/listener.dart | 4 +- .../type_promotion_look_ahead_listener.dart | 4 +- .../fasta/parser/literal_entry_info_test.dart | 8 +- 10 files changed, 458 insertions(+), 120 deletions(-) diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart index d7049da2775..fee50cba3c3 100644 --- a/pkg/analyzer/lib/dart/ast/ast_factory.dart +++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart @@ -596,7 +596,8 @@ abstract class AstFactory { * Returns a newly created for statement. */ ForStatement2 forStatement2( - {Token forKeyword, + {Token awaitKeyword, + Token forKeyword, Token leftParenthesis, ForLoopParts forLoopParts, Token rightParenthesis, diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart index e5a4e593de3..5cab0db5106 100644 --- a/pkg/analyzer/lib/src/fasta/ast_builder.dart +++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart @@ -872,22 +872,6 @@ class AstBuilder extends StackListener { assert(optional(';', leftSeparator)); assert(updateExpressionCount >= 0); - push(forKeyword); - push(leftParen); - push(leftSeparator); - push(updateExpressionCount); - } - - @override - void endForControlFlow(Token rightParenthesis) { - debugEvent("endForControlFlow"); - var entry = pop(); - - int updateExpressionCount = pop(); - Token leftSeparator = pop(); - Token leftParenthesis = pop(); - Token forToken = pop(); - List updates = popTypedList(updateExpressionCount); Statement conditionStatement = pop(); Object initializerPart = pop(); @@ -901,8 +885,7 @@ class AstBuilder extends StackListener { rightSeparator = (conditionStatement as EmptyStatement).semicolon; } - ForLoopParts forLoopParts; - Expression initializer; + ForParts forLoopParts; if (initializerPart is VariableDeclarationStatement) { forLoopParts = ast.forPartsWithDeclarations( variables: initializerPart.variables, @@ -912,9 +895,8 @@ class AstBuilder extends StackListener { updaters: updates, ); } else { - initializer = initializerPart as Expression; forLoopParts = ast.forPartsWithExpression( - initialization: initializer, + initialization: initializerPart as Expression, leftSeparator: leftSeparator, condition: condition, rightSeparator: rightSeparator, @@ -922,8 +904,20 @@ class AstBuilder extends StackListener { ); } - pushForControlFlowInfo( - null, forToken, leftParenthesis, forLoopParts, entry); + push(forKeyword); + push(leftParen); + push(forLoopParts); + } + + @override + void endForControlFlow(Token token) { + debugEvent("endForControlFlow"); + var entry = pop(); + ForParts forLoopParts = pop(); + Token leftParen = pop(); + Token forToken = pop(); + + pushForControlFlowInfo(null, forToken, leftParen, forLoopParts, entry); } void pushForControlFlowInfo(Token awaitToken, Token forToken, @@ -942,44 +936,38 @@ class AstBuilder extends StackListener { void endForStatement(Token endToken) { debugEvent("ForStatement"); Statement body = pop(); - - int updateExpressionCount = pop(); - Token leftSeparator = pop(); + ForParts forLoopParts = pop(); Token leftParen = pop(); - Token forKeyword = pop(); + Token forToken = pop(); - List updates = popTypedList(updateExpressionCount); - Statement conditionStatement = pop(); - Object initializerPart = pop(); - - VariableDeclarationList variableList; - Expression initializer; - if (initializerPart is VariableDeclarationStatement) { - variableList = initializerPart.variables; + if (enableControlFlowCollections || enableSpreadCollections) { + push(ast.forStatement2( + forKeyword: forToken, + leftParenthesis: leftParen, + forLoopParts: forLoopParts, + rightParenthesis: leftParen.endGroup, + body: body, + )); } else { - initializer = initializerPart as Expression; + VariableDeclarationList variableList; + Expression initializer; + if (forLoopParts is ForPartsWithDeclarations) { + variableList = forLoopParts.variables; + } else { + initializer = (forLoopParts as ForPartsWithExpression).initialization; + } + push(ast.forStatement( + forToken, + leftParen, + variableList, + initializer, + forLoopParts.leftSeparator, + forLoopParts.condition, + forLoopParts.rightSeparator, + forLoopParts.updaters, + leftParen?.endGroup, + body)); } - - Expression condition; - Token rightSeparator; - if (conditionStatement is ExpressionStatement) { - condition = conditionStatement.expression; - rightSeparator = conditionStatement.semicolon; - } else { - rightSeparator = (conditionStatement as EmptyStatement).semicolon; - } - - push(ast.forStatement( - forKeyword, - leftParen, - variableList, - initializer, - leftSeparator, - condition, - rightSeparator, - updates, - leftParen?.endGroup, - body)); } void handleLiteralList( @@ -1358,26 +1346,10 @@ class AstBuilder extends StackListener { assert(optional('(', leftParenthesis)); assert(optional('in', inKeyword) || optional(':', inKeyword)); - push(awaitToken ?? NullValue.AwaitToken); - push(forToken); - push(leftParenthesis); - push(inKeyword); - } - - @override - void endForInControlFlow(Token rightParenthesis) { - debugEvent("endForInControlFlow"); - var entry = pop(); - - Token inKeyword = pop(); - Token leftParenthesis = pop(); - Token forToken = pop(); - Token awaitToken = pop(NullValue.AwaitToken); - Expression iterator = pop(); Object variableOrDeclaration = pop(); - ForLoopParts forLoopParts; + ForEachParts forLoopParts; if (variableOrDeclaration is VariableDeclarationStatement) { VariableDeclarationList variableList = variableOrDeclaration.variables; forLoopParts = ast.forEachPartsWithDeclaration( @@ -1408,6 +1380,22 @@ class AstBuilder extends StackListener { ); } + push(awaitToken ?? NullValue.AwaitToken); + push(forToken); + push(leftParenthesis); + push(forLoopParts); + } + + @override + void endForInControlFlow(Token token) { + debugEvent("endForInControlFlow"); + + var entry = pop(); + ForEachParts forLoopParts = pop(); + Token leftParenthesis = pop(); + Token forToken = pop(); + Token awaitToken = pop(NullValue.AwaitToken); + pushForControlFlowInfo( awaitToken, forToken, leftParenthesis, forLoopParts, entry); } @@ -1417,48 +1405,38 @@ class AstBuilder extends StackListener { debugEvent("ForInExpression"); Statement body = pop(); - - Token inKeyword = pop(); + ForEachParts forLoopParts = pop(); Token leftParenthesis = pop(); Token forToken = pop(); Token awaitToken = pop(NullValue.AwaitToken); - Expression iterator = pop(); - Object variableOrDeclaration = pop(); - if (variableOrDeclaration is VariableDeclarationStatement) { - VariableDeclarationList variableList = variableOrDeclaration.variables; + if (enableControlFlowCollections || enableSpreadCollections) { + push(ast.forStatement2( + awaitKeyword: awaitToken, + forKeyword: forToken, + leftParenthesis: leftParenthesis, + forLoopParts: forLoopParts, + rightParenthesis: leftParenthesis.endGroup, + body: body, + )); + } else if (forLoopParts is ForEachPartsWithDeclaration) { push(ast.forEachStatementWithDeclaration( awaitToken, forToken, leftParenthesis, - ast.declaredIdentifier( - variableList.documentationComment, - variableList.metadata, - variableList.keyword, - variableList.type, - variableList.variables.first.name), - inKeyword, - iterator, + forLoopParts.loopVariable, + forLoopParts.inKeyword, + forLoopParts.iterable, leftParenthesis?.endGroup, body)); } else { - if (variableOrDeclaration is! SimpleIdentifier) { - // Parser has already reported the error. - if (!leftParenthesis.next.isIdentifier) { - parser.rewriter.insertToken( - leftParenthesis, - new SyntheticStringToken( - TokenType.IDENTIFIER, '', leftParenthesis.next.charOffset)); - } - variableOrDeclaration = ast.simpleIdentifier(leftParenthesis.next); - } push(ast.forEachStatementWithReference( awaitToken, forToken, leftParenthesis, - variableOrDeclaration, - inKeyword, - iterator, + (forLoopParts as ForEachPartsWithIdentifier).identifier, + forLoopParts.inKeyword, + forLoopParts.iterable, leftParenthesis?.endGroup, body)); } diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart index 89b0d3869f9..7217806cb9a 100644 --- a/pkg/analyzer/test/generated/parser_fasta_listener.dart +++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart @@ -710,15 +710,15 @@ class ForwardingTestListener extends ForwardingListener { } @override - void endForControlFlow(Token rightParenthesis) { + void endForControlFlow(Token token) { end('ForControlFlow'); - super.endForControlFlow(rightParenthesis); + super.endForControlFlow(token); } @override - void endForInControlFlow(Token rightParenthesis) { + void endForInControlFlow(Token token) { end('ForControlFlow'); - super.endForInControlFlow(rightParenthesis); + super.endForInControlFlow(token); } @override diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart index 88245894837..c5b4ea743b8 100644 --- a/pkg/analyzer/test/generated/parser_fasta_test.dart +++ b/pkg/analyzer/test/generated/parser_fasta_test.dart @@ -1477,8 +1477,20 @@ class FastaParserTestCase @override Statement parseStatement(String source, - {bool enableLazyAssignmentOperators, int expectedEndOffset}) { + {bool enableLazyAssignmentOperators, + int expectedEndOffset, + bool parseSetLiterals = false, + bool parseSpreadCollections = false, + bool parseControlFlowCollections = false, + bool inAsync = false}) { createParser(source, expectedEndOffset: expectedEndOffset); + _parserProxy.fastaParser.enableSetLiterals = parseSetLiterals; + _parserProxy.astBuilder.enableSpreadCollections = parseSpreadCollections; + _parserProxy.astBuilder.enableControlFlowCollections = + parseControlFlowCollections; + if (inAsync) { + _parserProxy.fastaParser.asyncState = AsyncModifier.Async; + } Statement statement = _parserProxy.parseStatement2(); assertErrors(codes: NO_ERROR_COMPARISON); return statement; @@ -1762,6 +1774,21 @@ class RecoveryParserTest_Fasta extends FastaParserTestCase ]); } + void test_incompleteForEach2() { + ForStatement2 statement = parseStatement('for (String item i) {}', + parseControlFlowCollections: true); + listener.assertErrors([ + expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 4), + expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1) + ]); + expect(statement.toSource(), 'for (String item; i;) {}'); + ForPartsWithDeclarations forLoopParts = statement.forLoopParts; + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.leftSeparator.type, TokenType.SEMICOLON); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.rightSeparator.type, TokenType.SEMICOLON); + } + void test_invalidTypeParameters_super() { parseCompilationUnit('class C {}', errors: [ // TODO(danrubel): Improve recovery. @@ -1865,6 +1892,304 @@ class StatementParserTest_Fasta extends FastaParserTestCase } } + void test_parseForStatement_each_await2() { + ForStatement2 forStatement = parseStatement( + 'await for (element in list) {}', + inAsync: true, + parseControlFlowCollections: true, + ); + assertNoErrors(); + expect(forStatement.awaitKeyword, isNotNull); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForEachPartsWithIdentifier forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.identifier, isNotNull); + expect(forLoopParts.inKeyword, isNotNull); + expect(forLoopParts.iterable, isNotNull); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_each_genericFunctionType2() { + ForStatement2 forStatement = parseStatement( + 'for (void Function(T) element in list) {}', + parseControlFlowCollections: true, + ); + assertNoErrors(); + expect(forStatement.awaitKeyword, isNull); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForEachPartsWithDeclaration forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.loopVariable, isNotNull); + expect(forLoopParts.inKeyword, isNotNull); + expect(forLoopParts.iterable, isNotNull); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_each_identifier2() { + ForStatement2 forStatement = parseStatement( + 'for (element in list) {}', + parseControlFlowCollections: true, + ); + assertNoErrors(); + expect(forStatement.awaitKeyword, isNull); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForEachPartsWithIdentifier forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.identifier, isNotNull); + expect(forLoopParts.inKeyword, isNotNull); + expect(forLoopParts.iterable, isNotNull); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_each_noType_metadata2() { + ForStatement2 forStatement = parseStatement( + 'for (@A var element in list) {}', + parseControlFlowCollections: true, + ); + assertNoErrors(); + expect(forStatement.awaitKeyword, isNull); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForEachPartsWithDeclaration forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.loopVariable, isNotNull); + expect(forLoopParts.loopVariable.metadata, hasLength(1)); + expect(forLoopParts.inKeyword, isNotNull); + expect(forLoopParts.iterable, isNotNull); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_each_type2() { + ForStatement2 forStatement = parseStatement( + 'for (A element in list) {}', + parseControlFlowCollections: true, + ); + assertNoErrors(); + expect(forStatement.awaitKeyword, isNull); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForEachPartsWithDeclaration forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.loopVariable, isNotNull); + expect(forLoopParts.inKeyword, isNotNull); + expect(forLoopParts.iterable, isNotNull); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_each_var2() { + ForStatement2 forStatement = parseStatement( + 'for (var element in list) {}', + parseControlFlowCollections: true, + ); + assertNoErrors(); + expect(forStatement.awaitKeyword, isNull); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForEachPartsWithDeclaration forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.loopVariable, isNotNull); + expect(forLoopParts.inKeyword, isNotNull); + expect(forLoopParts.iterable, isNotNull); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_c2() { + ForStatement2 forStatement = parseStatement( + 'for (; i < count;) {}', + parseControlFlowCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithExpression forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.initialization, isNull); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNotNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(0)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_cu2() { + ForStatement2 forStatement = parseStatement( + 'for (; i < count; i++) {}', + parseControlFlowCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithExpression forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.initialization, isNull); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNotNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(1)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_ecu2() { + ForStatement2 forStatement = parseStatement( + 'for (i--; i < count; i++) {}', + parseSpreadCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithExpression forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.initialization, isNotNull); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNotNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(1)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_i2() { + ForStatement2 forStatement = parseStatement( + 'for (var i = 0;;) {}', + parseSpreadCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts; + VariableDeclarationList variables = forLoopParts.variables; + expect(variables, isNotNull); + expect(variables.metadata, hasLength(0)); + expect(variables.variables, hasLength(1)); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(0)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_i_withMetadata2() { + ForStatement2 forStatement = parseStatement( + 'for (@A var i = 0;;) {}', + parseSpreadCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts; + VariableDeclarationList variables = forLoopParts.variables; + expect(variables, isNotNull); + expect(variables.metadata, hasLength(1)); + expect(variables.variables, hasLength(1)); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(0)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_ic2() { + ForStatement2 forStatement = parseStatement( + 'for (var i = 0; i < count;) {}', + parseSpreadCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts; + VariableDeclarationList variables = forLoopParts.variables; + expect(variables, isNotNull); + expect(variables.variables, hasLength(1)); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNotNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(0)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_icu2() { + ForStatement2 forStatement = parseStatement( + 'for (var i = 0; i < count; i++) {}', + parseSpreadCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts; + VariableDeclarationList variables = forLoopParts.variables; + expect(variables, isNotNull); + expect(variables.variables, hasLength(1)); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNotNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(1)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_iicuu2() { + ForStatement2 forStatement = parseStatement( + 'for (int i = 0, j = count; i < j; i++, j--) {}', + parseSpreadCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts; + VariableDeclarationList variables = forLoopParts.variables; + expect(variables, isNotNull); + expect(variables.variables, hasLength(2)); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNotNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(2)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_iu2() { + ForStatement2 forStatement = parseStatement( + 'for (var i = 0;; i++) {}', + parseSpreadCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts; + VariableDeclarationList variables = forLoopParts.variables; + expect(variables, isNotNull); + expect(variables.variables, hasLength(1)); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(1)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + + void test_parseForStatement_loop_u2() { + ForStatement2 forStatement = parseStatement( + 'for (;; i++) {}', + parseSpreadCollections: true, + ); + assertNoErrors(); + expect(forStatement.forKeyword, isNotNull); + expect(forStatement.leftParenthesis, isNotNull); + ForPartsWithExpression forLoopParts = forStatement.forLoopParts; + expect(forLoopParts.initialization, isNull); + expect(forLoopParts.leftSeparator, isNotNull); + expect(forLoopParts.condition, isNull); + expect(forLoopParts.rightSeparator, isNotNull); + expect(forLoopParts.updaters, hasLength(1)); + expect(forStatement.rightParenthesis, isNotNull); + expect(forStatement.body, isNotNull); + } + void test_partial_typeArg1_34850() { var unit = parseCompilationUnit('(T) element in list) {}') as ForEachStatement; @@ -14602,6 +14608,8 @@ main() { } void test_parseForStatement_each_identifier() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (element in list) {}') as ForEachStatement; assertNoErrors(); @@ -14617,6 +14625,8 @@ main() { } void test_parseForStatement_each_noType_metadata() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (@A var element in list) {}') as ForEachStatement; assertNoErrors(); @@ -14633,6 +14643,8 @@ main() { } void test_parseForStatement_each_type() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (A element in list) {}') as ForEachStatement; assertNoErrors(); @@ -14648,6 +14660,8 @@ main() { } void test_parseForStatement_each_var() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (var element in list) {}') as ForEachStatement; assertNoErrors(); @@ -14663,6 +14677,8 @@ main() { } void test_parseForStatement_loop_c() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (; i < count;) {}') as ForStatement; assertNoErrors(); expect(forStatement.forKeyword, isNotNull); @@ -14678,6 +14694,8 @@ main() { } void test_parseForStatement_loop_cu() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (; i < count; i++) {}') as ForStatement; assertNoErrors(); @@ -14694,6 +14712,8 @@ main() { } void test_parseForStatement_loop_ecu() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (i--; i < count; i++) {}') as ForStatement; assertNoErrors(); @@ -14710,6 +14730,8 @@ main() { } void test_parseForStatement_loop_i() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (var i = 0;;) {}') as ForStatement; assertNoErrors(); expect(forStatement.forKeyword, isNotNull); @@ -14728,6 +14750,8 @@ main() { } void test_parseForStatement_loop_i_withMetadata() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (@A var i = 0;;) {}') as ForStatement; assertNoErrors(); @@ -14747,6 +14771,8 @@ main() { } void test_parseForStatement_loop_ic() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (var i = 0; i < count;) {}') as ForStatement; assertNoErrors(); @@ -14765,6 +14791,8 @@ main() { } void test_parseForStatement_loop_icu() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (var i = 0; i < count; i++) {}') as ForStatement; assertNoErrors(); @@ -14783,6 +14811,8 @@ main() { } void test_parseForStatement_loop_iicuu() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (int i = 0, j = count; i < j; i++, j--) {}') as ForStatement; @@ -14802,6 +14832,8 @@ main() { } void test_parseForStatement_loop_iu() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (var i = 0;; i++) {}') as ForStatement; assertNoErrors(); @@ -14820,6 +14852,8 @@ main() { } void test_parseForStatement_loop_u() { + // TODO(danrubel): remove this once control flow and spread collection + // entry parsing is enabled by default var forStatement = parseStatement('for (;; i++) {}') as ForStatement; assertNoErrors(); expect(forStatement.forKeyword, isNotNull); diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index 7709f111490..b55e634aac6 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -2250,7 +2250,7 @@ abstract class BodyBuilder extends ScopeListener } @override - void endForControlFlow(Token rightParenthesis) { + void endForControlFlow(Token token) { debugEvent("endForControlFlow"); // TODO(danrubel) implement control flow support var entry = pop(); @@ -3874,7 +3874,7 @@ abstract class BodyBuilder extends ScopeListener } @override - void endForInControlFlow(Token rightParenthesis) { + void endForInControlFlow(Token token) { debugEvent("endForInControlFlow"); // TODO(danrubel) implement control flow support var entry = pop(); diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart index 241a22ee32b..585a7b21d1c 100644 --- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart +++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart @@ -569,13 +569,13 @@ class ForwardingListener implements Listener { } @override - void endForControlFlow(Token rightParenthesis) { - listener?.endForControlFlow(rightParenthesis); + void endForControlFlow(Token token) { + listener?.endForControlFlow(token); } @override - void endForInControlFlow(Token rightParenthesis) { - listener?.endForInControlFlow(rightParenthesis); + void endForInControlFlow(Token token) { + listener?.endForInControlFlow(token); } @override diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart index b460e8b1825..86036d3fb40 100644 --- a/pkg/front_end/lib/src/fasta/parser/listener.dart +++ b/pkg/front_end/lib/src/fasta/parser/listener.dart @@ -1088,12 +1088,12 @@ class Listener implements UnescapeErrorListener { void beginForControlFlow(Token awaitToken, Token forToken) {} /// Called after parsing a "for" control flow list, set, or map entry. - void endForControlFlow(Token rightParenthesis) { + void endForControlFlow(Token token) { logEvent('endForControlFlow'); } /// Called after parsing a "for-in" control flow list, set, or map entry. - void endForInControlFlow(Token rightParenthesis) { + void endForInControlFlow(Token token) { logEvent('endForInControlFlow'); } diff --git a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart index 398cabc7501..c78a6a157fe 100644 --- a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart +++ b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart @@ -377,13 +377,13 @@ class TypePromotionLookAheadListener extends Listener { } @override - void endForControlFlow(Token rightParenthesis) { + void endForControlFlow(Token token) { // TODO(danrubel) add support for for control flow collection entries // but for now this is ignored and an error reported in the body builder. } @override - void endForInControlFlow(Token rightParenthesis) { + void endForInControlFlow(Token token) { // TODO(danrubel) add support for for control flow collection entries // but for now this is ignored and an error reported in the body builder. } diff --git a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart index 9ae64aeb28e..9e4620f5808 100644 --- a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart +++ b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart @@ -660,13 +660,13 @@ class TestInfoListener implements Listener { } @override - void endForControlFlow(Token rightParenthesis) { - calls.add('endForControlFlow $rightParenthesis'); + void endForControlFlow(Token token) { + calls.add('endForControlFlow $token'); } @override - void endForInControlFlow(Token rightParenthesis) { - calls.add('endForInControlFlow $rightParenthesis'); + void endForInControlFlow(Token token) { + calls.add('endForInControlFlow $token'); } @override