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

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

Issue 2297563007: Move ParseVariableDeclarations to ParserBase. (Closed)
Patch Set: comment & whitespace fixes - see try jobs from a previous patch set 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 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 impl()->ReportMessageAt(source_location, message, arg, error_type); 928 impl()->ReportMessageAt(source_location, message, arg, error_type);
928 } 929 }
929 930
930 void ReportMessageAt(Scanner::Location location, 931 void ReportMessageAt(Scanner::Location location,
931 MessageTemplate::Template message, 932 MessageTemplate::Template message,
932 ParseErrorType error_type) { 933 ParseErrorType error_type) {
933 impl()->ReportMessageAt(location, message, 934 impl()->ReportMessageAt(location, message,
934 static_cast<const char*>(nullptr), error_type); 935 static_cast<const char*>(nullptr), error_type);
935 } 936 }
936 937
938 void ReportMessageAt(Scanner::Location location,
939 MessageTemplate::Template message, const char* arg,
940 ParseErrorType error_type = kSyntaxError) {
941 impl()->ReportMessageAt(location, message, arg, error_type);
942 }
nickie 2016/09/01 10:53:08 I suppose that by rearranging the parameters and p
marja 2016/09/01 11:16:10 Removed this one, calling impl()->ReportMessage di
943
937 void GetUnexpectedTokenMessage( 944 void GetUnexpectedTokenMessage(
938 Token::Value token, MessageTemplate::Template* message, 945 Token::Value token, MessageTemplate::Template* message,
939 Scanner::Location* location, const char** arg, 946 Scanner::Location* location, const char** arg,
940 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); 947 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
941 948
942 void ReportUnexpectedToken(Token::Value token); 949 void ReportUnexpectedToken(Token::Value token);
943 void ReportUnexpectedTokenAt( 950 void ReportUnexpectedTokenAt(
944 Scanner::Location location, Token::Value token, 951 Scanner::Location location, Token::Value token,
945 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); 952 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
946 953
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); 1166 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
1160 ExpressionT ParseSuperExpression(bool is_new, bool* ok); 1167 ExpressionT ParseSuperExpression(bool is_new, bool* ok);
1161 ExpressionT ParseNewTargetExpression(bool* ok); 1168 ExpressionT ParseNewTargetExpression(bool* ok);
1162 1169
1163 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); 1170 void ParseFormalParameter(FormalParametersT* parameters, bool* ok);
1164 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); 1171 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok);
1165 void CheckArityRestrictions(int param_count, FunctionKind function_type, 1172 void CheckArityRestrictions(int param_count, FunctionKind function_type,
1166 bool has_rest, int formals_start_pos, 1173 bool has_rest, int formals_start_pos,
1167 int formals_end_pos, bool* ok); 1174 int formals_end_pos, bool* ok);
1168 1175
1176 BlockT ParseVariableDeclarations(VariableDeclarationContext var_context,
1177 DeclarationParsingResult* parsing_result,
1178 ZoneList<const AstRawString*>* names,
1179 bool* ok);
1180
1169 bool IsNextLetKeyword(); 1181 bool IsNextLetKeyword();
1170 bool IsTrivialExpression(); 1182 bool IsTrivialExpression();
1171 1183
1172 // Checks if the expression is a valid reference expression (e.g., on the 1184 // Checks if the expression is a valid reference expression (e.g., on the
1173 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1185 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1174 // we allow calls for web compatibility and rewrite them to a runtime throw. 1186 // we allow calls for web compatibility and rewrite them to a runtime throw.
1175 ExpressionT CheckAndRewriteReferenceExpression( 1187 ExpressionT CheckAndRewriteReferenceExpression(
1176 ExpressionT expression, int beg_pos, int end_pos, 1188 ExpressionT expression, int beg_pos, int end_pos,
1177 MessageTemplate::Template message, bool* ok); 1189 MessageTemplate::Template message, bool* ok);
1178 ExpressionT CheckAndRewriteReferenceExpression( 1190 ExpressionT CheckAndRewriteReferenceExpression(
(...skipping 2213 matching lines...) Expand 10 before | Expand all | Expand 10 after
3392 } 3404 }
3393 } 3405 }
3394 3406
3395 for (int i = 0; i < parameters->Arity(); ++i) { 3407 for (int i = 0; i < parameters->Arity(); ++i) {
3396 auto parameter = parameters->at(i); 3408 auto parameter = parameters->at(i);
3397 impl()->DeclareFormalParameter(parameters->scope, parameter); 3409 impl()->DeclareFormalParameter(parameters->scope, parameter);
3398 } 3410 }
3399 } 3411 }
3400 3412
3401 template <typename Impl> 3413 template <typename Impl>
3414 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations(
3415 VariableDeclarationContext var_context,
3416 DeclarationParsingResult* parsing_result,
3417 ZoneList<const AstRawString*>* names, bool* ok) {
3418 // VariableDeclarations ::
3419 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
3420 //
3421 // ES6:
3422 // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
3423 // declaration syntax.
3424
3425 DeclarationParsingResult temp_result;
3426 if (parsing_result == nullptr) {
3427 parsing_result = &temp_result;
3428 }
3429 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
3430 parsing_result->descriptor.declaration_pos = peek_position();
3431 parsing_result->descriptor.initialization_pos = peek_position();
3432 parsing_result->descriptor.mode = VAR;
nickie 2016/09/01 10:53:08 Is there a reason why this line is not after 3441,
marja 2016/09/01 11:16:10 Done.
3433
3434 BlockT init_block = impl()->NullBlock();
3435 if (var_context != kForStatement) {
3436 init_block = impl()->NewBlock(nullptr, 1, true,
3437 parsing_result->descriptor.declaration_pos);
3438 }
3439
3440 if (peek() == Token::VAR) {
nickie 2016/09/01 10:53:08 Again a matter of taste, but I'd rather use a "swi
marja 2016/09/01 11:16:10 Done. (Replaced w/ switch)
3441 Consume(Token::VAR);
3442 } else if (peek() == Token::CONST) {
3443 Consume(Token::CONST);
3444 DCHECK(var_context != kStatement);
3445 parsing_result->descriptor.mode = CONST;
3446 } else if (peek() == Token::LET) {
3447 Consume(Token::LET);
3448 DCHECK(var_context != kStatement);
3449 parsing_result->descriptor.mode = LET;
3450 } else {
3451 UNREACHABLE(); // by current callers
3452 }
3453
3454 parsing_result->descriptor.scope = scope();
3455 parsing_result->descriptor.hoist_scope = nullptr;
3456
3457 // The scope of a var/const declared variable anywhere inside a function
3458 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
3459 // of a let declared variable is the scope of the immediately enclosing
3460 // block.
3461 bool first_declaration = true;
3462 int bindings_start = peek_position();
3463 do {
3464 // Parse binding pattern.
3465 FuncNameInferrer::State fni_state(fni_);
3466
3467 if (!first_declaration) Consume(Token::COMMA);
3468 first_declaration = false;
nickie 2016/09/01 10:53:08 I think you can get rid of these two lines and the
marja 2016/09/01 11:16:10 Done.
3469
3470 ExpressionT pattern = impl()->EmptyExpression();
3471 int decl_pos = peek_position();
3472 {
3473 ExpressionClassifier pattern_classifier(this);
3474 pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(NullBlock));
3475
3476 ValidateBindingPattern(CHECK_OK_CUSTOM(NullBlock));
3477 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
3478 ValidateLetPattern(CHECK_OK_CUSTOM(NullBlock));
3479 }
3480 }
3481
3482 Scanner::Location variable_loc = scanner()->location();
3483 bool single_name = impl()->IsIdentifier(pattern);
3484
3485 if (single_name && fni_ != nullptr) {
3486 impl()->PushVariableName(fni_, impl()->AsIdentifier(pattern));
nickie 2016/09/01 10:53:08 I think that impl()->PushVariableName does not nee
marja 2016/09/01 11:16:10 Leaving this as is, to keep PushLiteralName (alrea
3487 }
3488
3489 ExpressionT value = impl()->EmptyExpression();
3490 int initializer_position = kNoSourcePosition;
3491 if (Check(Token::ASSIGN)) {
3492 ExpressionClassifier classifier(this);
3493 value = ParseAssignmentExpression(var_context != kForStatement,
3494 CHECK_OK_CUSTOM(NullBlock));
3495 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullBlock));
3496 variable_loc.end_pos = scanner()->location().end_pos;
3497
3498 if (!parsing_result->first_initializer_loc.IsValid()) {
3499 parsing_result->first_initializer_loc = variable_loc;
3500 }
3501
3502 // Don't infer if it is "a = function(){...}();"-like expression.
3503 if (single_name && fni_ != nullptr) {
3504 if (!value->IsCall() && !value->IsCallNew()) {
3505 fni_->Infer();
3506 } else {
3507 fni_->RemoveLastFunction();
3508 }
3509 }
3510
3511 impl()->SetFunctionNameFromIdentifierRef(value, pattern);
3512
3513 // End position of the initializer is after the assignment expression.
3514 initializer_position = scanner()->location().end_pos;
3515 } else {
3516 if (var_context != kForStatement || !PeekInOrOf()) {
3517 // ES6 'const' and binding patterns require initializers.
3518 if (parsing_result->descriptor.mode == CONST ||
3519 !impl()->IsIdentifier(pattern)) {
3520 ReportMessageAt(
3521 Scanner::Location(decl_pos, scanner()->location().end_pos),
3522 MessageTemplate::kDeclarationMissingInitializer,
3523 !impl()->IsIdentifier(pattern) ? "destructuring" : "const");
3524 *ok = false;
3525 return impl()->NullBlock();
3526 }
3527 // 'let x' initializes 'x' to undefined.
3528 if (parsing_result->descriptor.mode == LET) {
3529 value = impl()->GetLiteralUndefined(position());
3530 }
3531 }
3532
3533 // End position of the initializer is after the variable.
3534 initializer_position = position();
3535 }
3536
3537 typename DeclarationParsingResult::Declaration decl(
3538 pattern, initializer_position, value);
3539 if (var_context == kForStatement) {
3540 // Save the declaration for further handling in ParseForStatement.
3541 parsing_result->declarations.Add(decl);
3542 } else {
3543 // Immediately declare the variable otherwise. This avoids O(N^2)
3544 // behavior (where N is the number of variables in a single
3545 // declaration) in the PatternRewriter having to do with removing
3546 // and adding VariableProxies to the Scope (see bug 4699).
3547 impl()->DeclareAndInitializeVariables(init_block,
3548 &parsing_result->descriptor, &decl,
3549 names, CHECK_OK_CUSTOM(NullBlock));
3550 }
3551 } while (peek() == Token::COMMA);
3552
3553 parsing_result->bindings_loc =
3554 Scanner::Location(bindings_start, scanner()->location().end_pos);
3555
3556 DCHECK(*ok);
nickie 2016/09/01 10:53:08 This line strikes me as a bit odd. Is there any r
marja 2016/09/01 11:16:10 I think this was just paranoid coding, as we use C
3557 return init_block;
3558 }
3559
3560 template <typename Impl>
3402 void ParserBase<Impl>::CheckArityRestrictions(int param_count, 3561 void ParserBase<Impl>::CheckArityRestrictions(int param_count,
3403 FunctionKind function_kind, 3562 FunctionKind function_kind,
3404 bool has_rest, 3563 bool has_rest,
3405 int formals_start_pos, 3564 int formals_start_pos,
3406 int formals_end_pos, bool* ok) { 3565 int formals_end_pos, bool* ok) {
3407 if (IsGetterFunction(function_kind)) { 3566 if (IsGetterFunction(function_kind)) {
3408 if (param_count != 0) { 3567 if (param_count != 0) {
3409 impl()->ReportMessageAt( 3568 impl()->ReportMessageAt(
3410 Scanner::Location(formals_start_pos, formals_end_pos), 3569 Scanner::Location(formals_start_pos, formals_end_pos),
3411 MessageTemplate::kBadGetterArity); 3570 MessageTemplate::kBadGetterArity);
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
3792 has_seen_constructor_ = true; 3951 has_seen_constructor_ = true;
3793 return; 3952 return;
3794 } 3953 }
3795 } 3954 }
3796 3955
3797 3956
3798 } // namespace internal 3957 } // namespace internal
3799 } // namespace v8 3958 } // namespace v8
3800 3959
3801 #endif // V8_PARSING_PARSER_BASE_H 3960 #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