Parse for-loop statements with Fasta.

R=ahe@google.com, paulberry@google.com
BUG=

Review-Url: https://codereview.chromium.org/2746333005 .
This commit is contained in:
Konstantin Shcheglov
2017-03-15 11:40:32 -07:00
parent 39dbb75c76
commit ae85bcf954
7 changed files with 54 additions and 89 deletions
@@ -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() {
@@ -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
@@ -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<Expression> 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,
@@ -1018,8 +1018,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> 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<Expression> updates = popListForEffect(updateExpressionCount);
@@ -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");
}
@@ -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;
}
+1 -1
View File
@@ -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