Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Unified Diff: src/parsing/preparser.cc

Issue 2297563007: Move ParseVariableDeclarations to ParserBase. (Closed)
Patch Set: rebased Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/preparser.cc
diff --git a/src/parsing/preparser.cc b/src/parsing/preparser.cc
index aa0d27ad1d58f614c86526c39a592b719dd0d875..369ff2415efb8dbe3351b73dfb3c818147460c64 100644
--- a/src/parsing/preparser.cc
+++ b/src/parsing/preparser.cc
@@ -423,118 +423,12 @@ PreParser::Statement PreParser::ParseVariableStatement(
// VariableStatement ::
// VariableDeclarations ';'
- Statement result = ParseVariableDeclarations(
- var_context, nullptr, nullptr, nullptr, nullptr, nullptr, CHECK_OK);
+ Statement result =
+ ParseVariableDeclarations(var_context, nullptr, nullptr, CHECK_OK);
ExpectSemicolon(CHECK_OK);
return result;
}
-
-// If the variable declaration declares exactly one non-const
-// variable, then *var is set to that variable. In all other cases,
-// *var is untouched; in particular, it is the caller's responsibility
-// to initialize it properly. This mechanism is also used for the parsing
-// of 'for-in' loops.
-PreParser::Statement PreParser::ParseVariableDeclarations(
- VariableDeclarationContext var_context, int* num_decl, bool* is_lexical,
- bool* is_binding_pattern, Scanner::Location* first_initializer_loc,
- Scanner::Location* bindings_loc, bool* ok) {
- // VariableDeclarations ::
- // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
- //
- // The ES6 Draft Rev3 specifies the following grammar for const declarations
- //
- // ConstDeclaration ::
- // const ConstBinding (',' ConstBinding)* ';'
- // ConstBinding ::
- // Identifier '=' AssignmentExpression
- //
- // TODO(ES6):
- // ConstBinding ::
- // BindingPattern '=' AssignmentExpression
- bool require_initializer = false;
- bool lexical = false;
- bool is_pattern = false;
- if (peek() == Token::VAR) {
- Consume(Token::VAR);
- } else if (peek() == Token::CONST) {
- // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
- //
- // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
- //
- // * It is a Syntax Error if the code that matches this production is not
- // contained in extended code.
- //
- // However disallowing const in sloppy mode will break compatibility with
- // existing pages. Therefore we keep allowing const with the old
- // non-harmony semantics in sloppy mode.
- Consume(Token::CONST);
- DCHECK(var_context != kStatement);
- require_initializer = true;
- lexical = true;
- } else if (peek() == Token::LET) {
- Consume(Token::LET);
- DCHECK(var_context != kStatement);
- lexical = true;
- } else {
- *ok = false;
- return Statement::Default();
- }
-
- // The scope of a var/const declared variable anywhere inside a function
- // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
- // of a let declared variable is the scope of the immediately enclosing
- // block.
- int nvars = 0; // the number of variables declared
- int bindings_start = peek_position();
- do {
- // Parse binding pattern.
- if (nvars > 0) Consume(Token::COMMA);
- int decl_pos = peek_position();
- PreParserExpression pattern = PreParserExpression::Default();
- {
- ExpressionClassifier pattern_classifier(this);
- pattern = ParsePrimaryExpression(CHECK_OK);
-
- ValidateBindingPattern(CHECK_OK);
- if (lexical) ValidateLetPattern(CHECK_OK);
- }
-
- is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral();
-
- Scanner::Location variable_loc = scanner()->location();
- nvars++;
- if (Check(Token::ASSIGN)) {
- ExpressionClassifier classifier(this);
- ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
- ValidateExpression(CHECK_OK);
-
- variable_loc.end_pos = scanner()->location().end_pos;
- if (first_initializer_loc && !first_initializer_loc->IsValid()) {
- *first_initializer_loc = variable_loc;
- }
- } else if ((require_initializer || is_pattern) &&
- (var_context != kForStatement || !PeekInOrOf())) {
- ReportMessageAt(
- Scanner::Location(decl_pos, scanner()->location().end_pos),
- MessageTemplate::kDeclarationMissingInitializer,
- is_pattern ? "destructuring" : "const");
- *ok = false;
- return Statement::Default();
- }
- } while (peek() == Token::COMMA);
-
- if (bindings_loc) {
- *bindings_loc =
- Scanner::Location(bindings_start, scanner()->location().end_pos);
- }
-
- if (num_decl != nullptr) *num_decl = nvars;
- if (is_lexical != nullptr) *is_lexical = lexical;
- if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern;
- return Statement::Default();
-}
-
PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
Consume(Token::FUNCTION);
int pos = position();
@@ -798,32 +692,35 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
ForEachStatement::VisitMode mode;
if (peek() == Token::VAR || peek() == Token::CONST ||
(peek() == Token::LET && IsNextLetKeyword())) {
- int decl_count;
- bool is_lexical;
- bool is_binding_pattern;
- Scanner::Location first_initializer_loc = Scanner::Location::invalid();
- Scanner::Location bindings_loc = Scanner::Location::invalid();
- ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical,
- &is_binding_pattern, &first_initializer_loc,
- &bindings_loc, CHECK_OK);
- if (is_lexical) has_lexical = true;
+ DeclarationParsingResult parsing_result;
+
+ ParseVariableDeclarations(kForStatement, &parsing_result, nullptr,
+ CHECK_OK);
+ if (parsing_result.descriptor.mode == CONST ||
+ parsing_result.descriptor.mode == LET) {
+ has_lexical = true;
+ }
if (CheckInOrOf(&mode)) {
- if (decl_count != 1) {
- ReportMessageAt(bindings_loc,
+ if (!*ok) return Statement::Default();
+ if (parsing_result.declarations.length() != 1) {
+ ReportMessageAt(parsing_result.bindings_loc,
MessageTemplate::kForInOfLoopMultiBindings,
ForEachStatement::VisitModeString(mode));
*ok = false;
return Statement::Default();
}
- if (first_initializer_loc.IsValid() &&
+ bool is_binding_pattern =
+ parsing_result.declarations[0].pattern.IsObjectLiteral() ||
+ parsing_result.declarations[0].pattern.IsArrayLiteral();
+ if (parsing_result.first_initializer_loc.IsValid() &&
(is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
- is_lexical || is_binding_pattern || allow_harmony_for_in())) {
+ has_lexical || is_binding_pattern || allow_harmony_for_in())) {
// Only increment the use count if we would have let this through
// without the flag.
if (use_counts_ != nullptr && allow_harmony_for_in()) {
++use_counts_[v8::Isolate::kForInInitializer];
}
- ReportMessageAt(first_initializer_loc,
+ ReportMessageAt(parsing_result.first_initializer_loc,
MessageTemplate::kForInOfLoopInitializer,
ForEachStatement::VisitModeString(mode));
*ok = false;
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698