diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart index 919c31be639..560bc76b6a6 100644 --- a/pkg/analyzer/test/generated/parser_fasta_test.dart +++ b/pkg/analyzer/test/generated/parser_fasta_test.dart @@ -1103,66 +1103,12 @@ class StatementParserTest_Fasta extends FastaParserTestCase super.test_parseForStatement_each_noType_metadata(); } - @override - @failingTest - void test_parseForStatement_loop_c() { - super.test_parseForStatement_loop_c(); - } - - @override - @failingTest - void test_parseForStatement_loop_cu() { - super.test_parseForStatement_loop_cu(); - } - - @override - @failingTest - void test_parseForStatement_loop_ecu() { - super.test_parseForStatement_loop_ecu(); - } - - @override - @failingTest - void test_parseForStatement_loop_i() { - super.test_parseForStatement_loop_i(); - } - @override @failingTest void test_parseForStatement_loop_i_withMetadata() { super.test_parseForStatement_loop_i_withMetadata(); } - @override - @failingTest - void test_parseForStatement_loop_ic() { - super.test_parseForStatement_loop_ic(); - } - - @override - @failingTest - void test_parseForStatement_loop_icu() { - super.test_parseForStatement_loop_icu(); - } - - @override - @failingTest - void test_parseForStatement_loop_iicuu() { - super.test_parseForStatement_loop_iicuu(); - } - - @override - @failingTest - void test_parseForStatement_loop_iu() { - super.test_parseForStatement_loop_iu(); - } - - @override - @failingTest - void test_parseForStatement_loop_u() { - super.test_parseForStatement_loop_u(); - } - @override @failingTest void test_parseNonLabeledStatement_functionDeclaration() { diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart index e8074a5d7f3..0aefe4d9d43 100644 --- a/pkg/compiler/lib/src/parser/node_listener.dart +++ b/pkg/compiler/lib/src/parser/node_listener.dart @@ -541,13 +541,13 @@ class NodeListener extends ElementListener { } @override - void endForStatement( - int updateExpressionCount, Token beginToken, Token endToken) { + void endForStatement(Token forKeyword, Token leftSeparator, + int updateExpressionCount, Token endToken) { Statement body = popNode(); NodeList updates = makeNodeList(updateExpressionCount, null, null, ','); Statement condition = popNode(); Node initializer = popNode(); - pushNode(new For(initializer, condition, updates, body, beginToken)); + pushNode(new For(initializer, condition, updates, body, forKeyword)); } @override diff --git a/pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart b/pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart index 922da2b97c8..11ec061cd72 100644 --- a/pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart +++ b/pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart @@ -415,8 +415,8 @@ class AstBuilder extends ScopeListener { debugEvent("WhileStatement"); Statement body = pop(); ParenthesizedExpression condition = pop(); - pop(); // continue target - pop(); // break target + exitContinueTarget(); + exitBreakTarget(); push(ast.whileStatement( toAnalyzerToken(whileKeyword), condition.leftParenthesis, @@ -475,25 +475,43 @@ class AstBuilder extends ScopeListener { toAnalyzerToken(beginToken), statements, toAnalyzerToken(endToken))); } - void endForStatement( - int updateExpressionCount, Token beginToken, Token endToken) { + void endForStatement(Token forKeyword, Token leftSeparator, + int updateExpressionCount, Token endToken) { debugEvent("ForStatement"); Statement body = pop(); List updates = popList(updateExpressionCount); - ExpressionStatement condition = pop(); - VariableDeclarationStatement variables = pop(); + Statement conditionStatement = pop(); + Object initializerPart = pop(); + exitLocalScope(); exitContinueTarget(); exitBreakTarget(); - exitLocalScope(); - BeginGroupToken leftParenthesis = beginToken.next; + BeginGroupToken leftParenthesis = forKeyword.next; + + VariableDeclarationList variableList; + Expression initializer; + if (initializerPart is VariableDeclarationStatement) { + variableList = initializerPart.variables; + } else { + initializer = initializerPart as Expression; + } + + Expression condition; + analyzer.Token rightSeparator; + if (conditionStatement is ExpressionStatement) { + condition = conditionStatement.expression; + rightSeparator = conditionStatement.semicolon; + } else { + rightSeparator = (conditionStatement as EmptyStatement).semicolon; + } + push(ast.forStatement( - toAnalyzerToken(beginToken), + toAnalyzerToken(forKeyword), toAnalyzerToken(leftParenthesis), - variables?.variables, - null, // initialization. - variables?.semicolon, - condition.expression, - condition.semicolon, + variableList, + initializer, + toAnalyzerToken(leftSeparator), + condition, + rightSeparator, updates, toAnalyzerToken(leftParenthesis.endGroup), body)); @@ -701,9 +719,9 @@ class AstBuilder extends ScopeListener { Statement body = pop(); Expression iterator = pop(); Object variableOrDeclaration = pop(); - pop(); // local scope - pop(); // continue target - pop(); // break target + exitLocalScope(); + exitContinueTarget(); + exitBreakTarget(); if (variableOrDeclaration is SimpleIdentifier) { push(ast.forEachStatementWithReference( toAnalyzerToken(awaitToken), @@ -1068,8 +1086,8 @@ class AstBuilder extends ScopeListener { debugEvent("DoWhileStatement"); ParenthesizedExpression condition = pop(); Statement body = pop(); - pop(); // continue target - pop(); // break target + exitContinueTarget(); + exitBreakTarget(); push(ast.doStatement( toAnalyzerToken(doKeyword), body, 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 f4b3f628ff2..e8b4f332ba5 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -1018,8 +1018,8 @@ class BodyBuilder extends ScopeListener implements BuilderHelper { } @override - void endForStatement( - int updateExpressionCount, Token beginToken, Token endToken) { + void endForStatement(Token forKeyword, Token leftSeparator, + int updateExpressionCount, Token endToken) { debugEvent("ForStatement"); Statement body = popStatement(); List updates = popListForEffect(updateExpressionCount); diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart index be5233a6812..2ab8d96277d 100644 --- a/pkg/front_end/lib/src/fasta/parser/listener.dart +++ b/pkg/front_end/lib/src/fasta/parser/listener.dart @@ -201,8 +201,8 @@ class Listener { void beginForStatement(Token token) {} - void endForStatement( - int updateExpressionCount, Token beginToken, Token endToken) { + void endForStatement(Token forKeyword, Token leftSeparator, + int updateExpressionCount, Token endToken) { logEvent("ForStatement"); } diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart index e2083093cd4..ca1a8e48c31 100644 --- a/pkg/front_end/lib/src/fasta/parser/parser.dart +++ b/pkg/front_end/lib/src/fasta/parser/parser.dart @@ -3214,19 +3214,19 @@ class Parser { } Token parseForStatement(Token awaitToken, Token token) { - Token forToken = token; - listener.beginForStatement(forToken); + Token forKeyword = token; + listener.beginForStatement(forKeyword); token = expect('for', token); Token leftParenthesis = token; token = expect('(', token); token = parseVariablesDeclarationOrExpressionOpt(token); if (optional('in', token)) { - return parseForInRest(awaitToken, forToken, leftParenthesis, token); + return parseForInRest(awaitToken, forKeyword, leftParenthesis, token); } else { if (awaitToken != null) { reportRecoverableError(awaitToken, ErrorKind.InvalidAwaitFor); } - return parseForRest(forToken, token); + return parseForRest(forKeyword, leftParenthesis, token); } } @@ -3248,7 +3248,8 @@ class Parser { return parseExpression(token); } - Token parseForRest(Token forToken, Token token) { + Token parseForRest(Token forToken, Token leftParenthesis, Token token) { + Token leftSeparator = token; token = expectSemicolon(token); if (optional(';', token)) { token = parseEmptyStatement(token); @@ -3270,12 +3271,12 @@ class Parser { listener.beginForStatementBody(token); token = parseStatement(token); listener.endForStatementBody(token); - listener.endForStatement(expressionCount, forToken, token); + listener.endForStatement(forToken, leftSeparator, expressionCount, token); return token; } Token parseForInRest( - Token awaitToken, Token forToken, Token leftParenthesis, Token token) { + Token awaitToken, Token forKeyword, Token leftParenthesis, Token token) { assert(optional('in', token)); Token inKeyword = token; token = token.next; @@ -3287,7 +3288,7 @@ class Parser { listener.beginForInBody(token); token = parseStatement(token); listener.endForInBody(token); - listener.endForIn(awaitToken, forToken, leftParenthesis, inKeyword, + listener.endForIn(awaitToken, forKeyword, leftParenthesis, inKeyword, rightParenthesis, token); return token; } diff --git a/pkg/front_end/test/fasta/kompile.status b/pkg/front_end/test/fasta/kompile.status index ecdd93c8974..25693d79231 100644 --- a/pkg/front_end/test/fasta/kompile.status +++ b/pkg/front_end/test/fasta/kompile.status @@ -51,7 +51,7 @@ rasta/duplicated_mixin: Crash rasta/export: Fail rasta/external_factory_redirection: Crash rasta/foo: Fail -rasta/for_loop: Crash +rasta/for_loop: Fail rasta/generic_factory: VerificationError rasta/issue_000001: Crash rasta/issue_000002: Crash