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

Side by Side Diff: src/parsing/parser-base.h

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 unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PARSING_PARSER_BASE_H 5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H 6 #define V8_PARSING_PARSER_BASE_H
7 7
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/hashmap.h" 10 #include "src/base/hashmap.h"
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 typedef typename Types::Expression ExpressionT; 207 typedef typename Types::Expression ExpressionT;
208 typedef typename Types::Identifier IdentifierT; 208 typedef typename Types::Identifier IdentifierT;
209 typedef typename Types::FormalParameter FormalParameterT; 209 typedef typename Types::FormalParameter FormalParameterT;
210 typedef typename Types::FormalParameters FormalParametersT; 210 typedef typename Types::FormalParameters FormalParametersT;
211 typedef typename Types::FunctionLiteral FunctionLiteralT; 211 typedef typename Types::FunctionLiteral FunctionLiteralT;
212 typedef typename Types::Literal LiteralT; 212 typedef typename Types::Literal LiteralT;
213 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; 213 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
214 typedef typename Types::StatementList StatementListT; 214 typedef typename Types::StatementList StatementListT;
215 typedef typename v8::internal::ExpressionClassifier<Types> 215 typedef typename v8::internal::ExpressionClassifier<Types>
216 ExpressionClassifier; 216 ExpressionClassifier;
217 typedef typename Types::Block BlockT;
217 218
218 // All implementation-specific methods must be called through this. 219 // All implementation-specific methods must be called through this.
219 Impl* impl() { return static_cast<Impl*>(this); } 220 Impl* impl() { return static_cast<Impl*>(this); }
220 const Impl* impl() const { return static_cast<const Impl*>(this); } 221 const Impl* impl() const { return static_cast<const Impl*>(this); }
221 222
222 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, 223 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
223 v8::Extension* extension, AstValueFactory* ast_value_factory, 224 v8::Extension* extension, AstValueFactory* ast_value_factory,
224 ParserRecorder* log) 225 ParserRecorder* log)
225 : scope_state_(nullptr), 226 : scope_state_(nullptr),
226 function_state_(nullptr), 227 function_state_(nullptr),
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); 1171 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
1171 ExpressionT ParseSuperExpression(bool is_new, bool* ok); 1172 ExpressionT ParseSuperExpression(bool is_new, bool* ok);
1172 ExpressionT ParseNewTargetExpression(bool* ok); 1173 ExpressionT ParseNewTargetExpression(bool* ok);
1173 1174
1174 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); 1175 void ParseFormalParameter(FormalParametersT* parameters, bool* ok);
1175 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); 1176 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok);
1176 void CheckArityRestrictions(int param_count, FunctionKind function_type, 1177 void CheckArityRestrictions(int param_count, FunctionKind function_type,
1177 bool has_rest, int formals_start_pos, 1178 bool has_rest, int formals_start_pos,
1178 int formals_end_pos, bool* ok); 1179 int formals_end_pos, bool* ok);
1179 1180
1181 BlockT ParseVariableDeclarations(VariableDeclarationContext var_context,
1182 DeclarationParsingResult* parsing_result,
1183 ZoneList<const AstRawString*>* names,
1184 bool* ok);
1185
1180 bool IsNextLetKeyword(); 1186 bool IsNextLetKeyword();
1181 bool IsTrivialExpression(); 1187 bool IsTrivialExpression();
1182 1188
1183 // Checks if the expression is a valid reference expression (e.g., on the 1189 // Checks if the expression is a valid reference expression (e.g., on the
1184 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1190 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1185 // we allow calls for web compatibility and rewrite them to a runtime throw. 1191 // we allow calls for web compatibility and rewrite them to a runtime throw.
1186 ExpressionT CheckAndRewriteReferenceExpression( 1192 ExpressionT CheckAndRewriteReferenceExpression(
1187 ExpressionT expression, int beg_pos, int end_pos, 1193 ExpressionT expression, int beg_pos, int end_pos,
1188 MessageTemplate::Template message, bool* ok); 1194 MessageTemplate::Template message, bool* ok);
1189 ExpressionT CheckAndRewriteReferenceExpression( 1195 ExpressionT CheckAndRewriteReferenceExpression(
(...skipping 2213 matching lines...) Expand 10 before | Expand all | Expand 10 after
3403 } 3409 }
3404 } 3410 }
3405 3411
3406 for (int i = 0; i < parameters->Arity(); ++i) { 3412 for (int i = 0; i < parameters->Arity(); ++i) {
3407 auto parameter = parameters->at(i); 3413 auto parameter = parameters->at(i);
3408 impl()->DeclareFormalParameter(parameters->scope, parameter); 3414 impl()->DeclareFormalParameter(parameters->scope, parameter);
3409 } 3415 }
3410 } 3416 }
3411 3417
3412 template <typename Impl> 3418 template <typename Impl>
3419 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations(
3420 VariableDeclarationContext var_context,
3421 DeclarationParsingResult* parsing_result,
3422 ZoneList<const AstRawString*>* names, bool* ok) {
3423 // VariableDeclarations ::
3424 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
3425 //
3426 // ES6:
3427 // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
3428 // declaration syntax.
3429
3430 DeclarationParsingResult temp_result;
3431 if (parsing_result == nullptr) {
3432 parsing_result = &temp_result;
3433 }
3434 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
3435 parsing_result->descriptor.declaration_pos = peek_position();
3436 parsing_result->descriptor.initialization_pos = peek_position();
3437
3438 BlockT init_block = impl()->NullBlock();
3439 if (var_context != kForStatement) {
3440 init_block = impl()->NewBlock(nullptr, 1, true,
3441 parsing_result->descriptor.declaration_pos);
3442 }
3443
3444 switch (peek()) {
3445 case Token::VAR:
3446 parsing_result->descriptor.mode = VAR;
3447 Consume(Token::VAR);
3448 break;
3449 case Token::CONST:
3450 Consume(Token::CONST);
3451 DCHECK(var_context != kStatement);
3452 parsing_result->descriptor.mode = CONST;
3453 break;
3454 case Token::LET:
3455 Consume(Token::LET);
3456 DCHECK(var_context != kStatement);
3457 parsing_result->descriptor.mode = LET;
3458 break;
3459 default:
3460 UNREACHABLE(); // by current callers
3461 break;
3462 }
3463
3464 parsing_result->descriptor.scope = scope();
3465 parsing_result->descriptor.hoist_scope = nullptr;
3466
3467 // The scope of a var/const declared variable anywhere inside a function
3468 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
3469 // of a let declared variable is the scope of the immediately enclosing
3470 // block.
3471 int bindings_start = peek_position();
3472 do {
3473 // Parse binding pattern.
3474 FuncNameInferrer::State fni_state(fni_);
3475
3476 ExpressionT pattern = impl()->EmptyExpression();
3477 int decl_pos = peek_position();
3478 {
3479 ExpressionClassifier pattern_classifier(this);
3480 pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(NullBlock));
3481
3482 ValidateBindingPattern(CHECK_OK_CUSTOM(NullBlock));
3483 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
3484 ValidateLetPattern(CHECK_OK_CUSTOM(NullBlock));
3485 }
3486 }
3487
3488 Scanner::Location variable_loc = scanner()->location();
3489 bool single_name = impl()->IsIdentifier(pattern);
3490
3491 if (single_name && fni_ != nullptr) {
3492 impl()->PushVariableName(fni_, impl()->AsIdentifier(pattern));
3493 }
3494
3495 ExpressionT value = impl()->EmptyExpression();
3496 int initializer_position = kNoSourcePosition;
3497 if (Check(Token::ASSIGN)) {
3498 ExpressionClassifier classifier(this);
3499 value = ParseAssignmentExpression(var_context != kForStatement,
3500 CHECK_OK_CUSTOM(NullBlock));
3501 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullBlock));
3502 variable_loc.end_pos = scanner()->location().end_pos;
3503
3504 if (!parsing_result->first_initializer_loc.IsValid()) {
3505 parsing_result->first_initializer_loc = variable_loc;
3506 }
3507
3508 // Don't infer if it is "a = function(){...}();"-like expression.
3509 if (single_name && fni_ != nullptr) {
3510 if (!value->IsCall() && !value->IsCallNew()) {
3511 fni_->Infer();
3512 } else {
3513 fni_->RemoveLastFunction();
3514 }
3515 }
3516
3517 impl()->SetFunctionNameFromIdentifierRef(value, pattern);
3518
3519 // End position of the initializer is after the assignment expression.
3520 initializer_position = scanner()->location().end_pos;
3521 } else {
3522 if (var_context != kForStatement || !PeekInOrOf()) {
3523 // ES6 'const' and binding patterns require initializers.
3524 if (parsing_result->descriptor.mode == CONST ||
3525 !impl()->IsIdentifier(pattern)) {
3526 impl()->ReportMessageAt(
3527 Scanner::Location(decl_pos, scanner()->location().end_pos),
3528 MessageTemplate::kDeclarationMissingInitializer,
3529 !impl()->IsIdentifier(pattern) ? "destructuring" : "const");
3530 *ok = false;
3531 return impl()->NullBlock();
3532 }
3533 // 'let x' initializes 'x' to undefined.
3534 if (parsing_result->descriptor.mode == LET) {
3535 value = impl()->GetLiteralUndefined(position());
3536 }
3537 }
3538
3539 // End position of the initializer is after the variable.
3540 initializer_position = position();
3541 }
3542
3543 typename DeclarationParsingResult::Declaration decl(
3544 pattern, initializer_position, value);
3545 if (var_context == kForStatement) {
3546 // Save the declaration for further handling in ParseForStatement.
3547 parsing_result->declarations.Add(decl);
3548 } else {
3549 // Immediately declare the variable otherwise. This avoids O(N^2)
3550 // behavior (where N is the number of variables in a single
3551 // declaration) in the PatternRewriter having to do with removing
3552 // and adding VariableProxies to the Scope (see bug 4699).
3553 impl()->DeclareAndInitializeVariables(init_block,
3554 &parsing_result->descriptor, &decl,
3555 names, CHECK_OK_CUSTOM(NullBlock));
3556 }
3557 } while (Check(Token::COMMA));
3558
3559 parsing_result->bindings_loc =
3560 Scanner::Location(bindings_start, scanner()->location().end_pos);
3561
3562 DCHECK(*ok);
3563 return init_block;
3564 }
3565
3566 template <typename Impl>
3413 void ParserBase<Impl>::CheckArityRestrictions(int param_count, 3567 void ParserBase<Impl>::CheckArityRestrictions(int param_count,
3414 FunctionKind function_kind, 3568 FunctionKind function_kind,
3415 bool has_rest, 3569 bool has_rest,
3416 int formals_start_pos, 3570 int formals_start_pos,
3417 int formals_end_pos, bool* ok) { 3571 int formals_end_pos, bool* ok) {
3418 if (IsGetterFunction(function_kind)) { 3572 if (IsGetterFunction(function_kind)) {
3419 if (param_count != 0) { 3573 if (param_count != 0) {
3420 impl()->ReportMessageAt( 3574 impl()->ReportMessageAt(
3421 Scanner::Location(formals_start_pos, formals_end_pos), 3575 Scanner::Location(formals_start_pos, formals_end_pos),
3422 MessageTemplate::kBadGetterArity); 3576 MessageTemplate::kBadGetterArity);
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
3823 has_seen_constructor_ = true; 3977 has_seen_constructor_ = true;
3824 return; 3978 return;
3825 } 3979 }
3826 } 3980 }
3827 3981
3828 3982
3829 } // namespace internal 3983 } // namespace internal
3830 } // namespace v8 3984 } // namespace v8
3831 3985
3832 #endif // V8_PARSING_PARSER_BASE_H 3986 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698