зеркало из https://github.com/mozilla/gecko-dev.git
Bug 883333, part 4 - Refactor while and do-while statement parsing. r=Waldo.
--HG-- extra : rebase_source : 26dd5b2425fdc9216c47d679877490f8d1432bd4
This commit is contained in:
Родитель
f41a87c178
Коммит
52468cf956
|
@ -209,6 +209,15 @@ class FullParseHandler
|
|||
return pn;
|
||||
}
|
||||
|
||||
ParseNode *newDoWhileStatement(ParseNode *body, ParseNode *cond, const TokenPos &pos) {
|
||||
return new_<BinaryNode>(PNK_DOWHILE, JSOP_NOP, pos, body, cond);
|
||||
}
|
||||
|
||||
ParseNode *newWhileStatement(uint32_t begin, ParseNode *cond, ParseNode *body) {
|
||||
TokenPos pos = TokenPos::make(begin, body->pn_pos.end);
|
||||
return new_<BinaryNode>(PNK_WHILE, JSOP_NOP, pos, cond, body);
|
||||
}
|
||||
|
||||
ParseNode *newCaseOrDefault(uint32_t begin, ParseNode *expr, ParseNode *body) {
|
||||
TokenPos pos = TokenPos::make(begin, body->pn_pos.end);
|
||||
return new_<BinaryNode>(expr ? PNK_CASE : PNK_DEFAULT, JSOP_NOP, pos, expr, body);
|
||||
|
|
|
@ -3652,6 +3652,56 @@ Parser<ParseHandler>::ifStatement()
|
|||
return handler.newIfStatement(begin, cond, thenBranch, elseBranch);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::doWhileStatement()
|
||||
{
|
||||
uint32_t begin = pos().begin;
|
||||
StmtInfoPC stmtInfo(context);
|
||||
PushStatementPC(pc, &stmtInfo, STMT_DO_LOOP);
|
||||
Node body = statement();
|
||||
if (!body)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO);
|
||||
Node cond = condition();
|
||||
if (!cond)
|
||||
return null();
|
||||
PopStatementPC(context, pc);
|
||||
|
||||
if (versionNumber() == JSVERSION_ECMA_3) {
|
||||
// Pedantically require a semicolon or line break, following ES3.
|
||||
// Bug 880329 proposes removing this case.
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
return null();
|
||||
} else {
|
||||
// The semicolon after do-while is even more optional than most
|
||||
// semicolons in JS. Web compat required this by 2004:
|
||||
// http://bugzilla.mozilla.org/show_bug.cgi?id=238945
|
||||
// ES3 and ES5 disagreed, but ES6 conforms to Web reality:
|
||||
// https://bugs.ecmascript.org/show_bug.cgi?id=157
|
||||
(void) tokenStream.matchToken(TOK_SEMI);
|
||||
}
|
||||
|
||||
return handler.newDoWhileStatement(body, cond, TokenPos::make(begin, pos().end));
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::whileStatement()
|
||||
{
|
||||
uint32_t begin = pos().begin;
|
||||
StmtInfoPC stmtInfo(context);
|
||||
PushStatementPC(pc, &stmtInfo, STMT_WHILE_LOOP);
|
||||
Node cond = condition();
|
||||
if (!cond)
|
||||
return null();
|
||||
Node body = statement();
|
||||
if (!body)
|
||||
return null();
|
||||
PopStatementPC(context, pc);
|
||||
return handler.newWhileStatement(begin, cond, body);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::matchInOrOf(bool *isForOfp)
|
||||
|
@ -4686,62 +4736,18 @@ Parser<ParseHandler>::statement(bool canHaveDirectives)
|
|||
case TOK_IF:
|
||||
return ifStatement();
|
||||
|
||||
case TOK_SWITCH:
|
||||
return switchStatement();
|
||||
case TOK_DO:
|
||||
return doWhileStatement();
|
||||
|
||||
case TOK_WHILE:
|
||||
{
|
||||
uint32_t begin = pos().begin;
|
||||
StmtInfoPC stmtInfo(context);
|
||||
PushStatementPC(pc, &stmtInfo, STMT_WHILE_LOOP);
|
||||
Node cond = condition();
|
||||
if (!cond)
|
||||
return null();
|
||||
Node body = statement();
|
||||
if (!body)
|
||||
return null();
|
||||
PopStatementPC(context, pc);
|
||||
pn = handler.newBinary(PNK_WHILE, cond, body);
|
||||
if (!pn)
|
||||
return null();
|
||||
handler.setBeginPosition(pn, begin);
|
||||
return pn;
|
||||
}
|
||||
|
||||
case TOK_DO:
|
||||
{
|
||||
uint32_t begin = pos().begin;
|
||||
StmtInfoPC stmtInfo(context);
|
||||
PushStatementPC(pc, &stmtInfo, STMT_DO_LOOP);
|
||||
Node body = statement();
|
||||
if (!body)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO);
|
||||
Node cond = condition();
|
||||
if (!cond)
|
||||
return null();
|
||||
PopStatementPC(context, pc);
|
||||
|
||||
pn = handler.newBinary(PNK_DOWHILE, body, cond);
|
||||
if (!pn)
|
||||
return null();
|
||||
handler.setBeginPosition(pn, begin);
|
||||
|
||||
if (versionNumber() != JSVERSION_ECMA_3) {
|
||||
/*
|
||||
* All legacy and extended versions must do automatic semicolon
|
||||
* insertion after do-while. See the testcase and discussion in
|
||||
* http://bugzilla.mozilla.org/show_bug.cgi?id=238945.
|
||||
*/
|
||||
(void) tokenStream.matchToken(TOK_SEMI);
|
||||
return pn;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return whileStatement();
|
||||
|
||||
case TOK_FOR:
|
||||
return forStatement();
|
||||
|
||||
case TOK_SWITCH:
|
||||
return switchStatement();
|
||||
|
||||
case TOK_BREAK:
|
||||
{
|
||||
uint32_t begin = pos().begin;
|
||||
|
|
|
@ -418,6 +418,8 @@ struct Parser : private AutoGCRooter, public StrictModeGetter
|
|||
Node statements();
|
||||
|
||||
Node ifStatement();
|
||||
Node doWhileStatement();
|
||||
Node whileStatement();
|
||||
Node forStatement();
|
||||
Node switchStatement();
|
||||
Node withStatement();
|
||||
|
|
|
@ -107,6 +107,8 @@ class SyntaxParseHandler
|
|||
}
|
||||
|
||||
Node newIfStatement(uint32_t begin, Node cond, Node then, Node else_) { return NodeGeneric; }
|
||||
Node newDoWhileStatement(Node body, Node cond, const TokenPos &pos) { return NodeGeneric; }
|
||||
Node newWhileStatement(uint32_t begin, Node cond, Node body) { return NodeGeneric; }
|
||||
Node newCaseOrDefault(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
|
||||
Node newContinue(PropertyName *label, uint32_t begin, uint32_t end) { return NodeGeneric; }
|
||||
Node newBreak(PropertyName *label, uint32_t begin, uint32_t end) { return NodeGeneric; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче