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

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

Issue 2323763002: [parser] Refactor of Parse*Statement*, part 4 (Closed)
Patch Set: Rebase 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/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 DeclarationScope* result = 667 DeclarationScope* result =
668 new (zone()) DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind); 668 new (zone()) DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind);
669 // TODO(verwaest): Move into the DeclarationScope constructor. 669 // TODO(verwaest): Move into the DeclarationScope constructor.
670 if (!IsArrowFunction(kind)) { 670 if (!IsArrowFunction(kind)) {
671 result->DeclareThis(ast_value_factory()); 671 result->DeclareThis(ast_value_factory());
672 result->DeclareDefaultFunctionVariables(ast_value_factory()); 672 result->DeclareDefaultFunctionVariables(ast_value_factory());
673 } 673 }
674 return result; 674 return result;
675 } 675 }
676 676
677 V8_INLINE DeclarationScope* GetDeclarationScope() const {
678 return scope()->GetDeclarationScope();
679 }
680 V8_INLINE DeclarationScope* GetClosureScope() const {
681 return scope()->GetClosureScope();
682 }
683
677 Scanner* scanner() const { return scanner_; } 684 Scanner* scanner() const { return scanner_; }
678 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } 685 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
679 int position() const { return scanner_->location().beg_pos; } 686 int position() const { return scanner_->location().beg_pos; }
680 int peek_position() const { return scanner_->peek_location().beg_pos; } 687 int peek_position() const { return scanner_->peek_location().beg_pos; }
681 bool stack_overflow() const { return stack_overflow_; } 688 bool stack_overflow() const { return stack_overflow_; }
682 void set_stack_overflow() { stack_overflow_ = true; } 689 void set_stack_overflow() { stack_overflow_ = true; }
683 Mode mode() const { return mode_; } 690 Mode mode() const { return mode_; }
684 691
685 INLINE(Token::Value peek()) { 692 INLINE(Token::Value peek()) {
686 if (stack_overflow_) return Token::ILLEGAL; 693 if (stack_overflow_) return Token::ILLEGAL;
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 LanguageMode old = scope()->language_mode(); 881 LanguageMode old = scope()->language_mode();
875 impl()->SetLanguageMode(scope(), old > mode ? old : mode); 882 impl()->SetLanguageMode(scope(), old > mode ? old : mode);
876 } 883 }
877 bool is_generator() const { return function_state_->is_generator(); } 884 bool is_generator() const { return function_state_->is_generator(); }
878 bool is_async_function() const { 885 bool is_async_function() const {
879 return function_state_->is_async_function(); 886 return function_state_->is_async_function();
880 } 887 }
881 bool is_resumable() const { return function_state_->is_resumable(); } 888 bool is_resumable() const { return function_state_->is_resumable(); }
882 889
883 // Report syntax errors. 890 // Report syntax errors.
884 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, 891 void ReportMessage(MessageTemplate::Template message) {
892 Scanner::Location source_location = scanner()->location();
893 impl()->ReportMessageAt(source_location, message,
894 static_cast<const char*>(nullptr), kSyntaxError);
895 }
896
897 template <typename T>
898 void ReportMessage(MessageTemplate::Template message, T arg,
885 ParseErrorType error_type = kSyntaxError) { 899 ParseErrorType error_type = kSyntaxError) {
886 Scanner::Location source_location = scanner()->location(); 900 Scanner::Location source_location = scanner()->location();
887 impl()->ReportMessageAt(source_location, message, arg, error_type); 901 impl()->ReportMessageAt(source_location, message, arg, error_type);
888 }
889
890 void ReportMessage(MessageTemplate::Template message, const AstRawString* arg,
891 ParseErrorType error_type = kSyntaxError) {
892 Scanner::Location source_location = scanner()->location();
893 impl()->ReportMessageAt(source_location, message, arg, error_type);
894 } 902 }
895 903
896 void ReportMessageAt(Scanner::Location location, 904 void ReportMessageAt(Scanner::Location location,
897 MessageTemplate::Template message, 905 MessageTemplate::Template message,
898 ParseErrorType error_type) { 906 ParseErrorType error_type) {
899 impl()->ReportMessageAt(location, message, 907 impl()->ReportMessageAt(location, message,
900 static_cast<const char*>(nullptr), error_type); 908 static_cast<const char*>(nullptr), error_type);
901 } 909 }
902 910
903 void GetUnexpectedTokenMessage( 911 void GetUnexpectedTokenMessage(
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 1193
1186 StatementT ParseVariableStatement(VariableDeclarationContext var_context, 1194 StatementT ParseVariableStatement(VariableDeclarationContext var_context,
1187 ZoneList<const AstRawString*>* names, 1195 ZoneList<const AstRawString*>* names,
1188 bool* ok); 1196 bool* ok);
1189 1197
1190 // Magical syntax support. 1198 // Magical syntax support.
1191 ExpressionT ParseV8Intrinsic(bool* ok); 1199 ExpressionT ParseV8Intrinsic(bool* ok);
1192 1200
1193 StatementT ParseDebuggerStatement(bool* ok); 1201 StatementT ParseDebuggerStatement(bool* ok);
1194 1202
1203 StatementT ParseExpressionOrLabelledStatement(
1204 ZoneList<const AstRawString*>* labels,
1205 AllowLabelledFunctionStatement allow_function, bool* ok);
1206 StatementT ParseIfStatement(ZoneList<const AstRawString*>* labels, bool* ok);
1207 StatementT ParseContinueStatement(bool* ok);
1208 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels,
1209 bool* ok);
1210 StatementT ParseReturnStatement(bool* ok);
1211 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels,
1212 bool* ok);
1213
1195 bool IsNextLetKeyword(); 1214 bool IsNextLetKeyword();
1196 bool IsTrivialExpression(); 1215 bool IsTrivialExpression();
1197 1216
1198 // Checks if the expression is a valid reference expression (e.g., on the 1217 // Checks if the expression is a valid reference expression (e.g., on the
1199 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1218 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1200 // we allow calls for web compatibility and rewrite them to a runtime throw. 1219 // we allow calls for web compatibility and rewrite them to a runtime throw.
1201 ExpressionT CheckAndRewriteReferenceExpression( 1220 ExpressionT CheckAndRewriteReferenceExpression(
1202 ExpressionT expression, int beg_pos, int end_pos, 1221 ExpressionT expression, int beg_pos, int end_pos,
1203 MessageTemplate::Template message, bool* ok); 1222 MessageTemplate::Template message, bool* ok);
1204 ExpressionT CheckAndRewriteReferenceExpression( 1223 ExpressionT CheckAndRewriteReferenceExpression(
(...skipping 2853 matching lines...) Expand 10 before | Expand all | Expand 10 after
4058 while (peek() != end_token) { 4077 while (peek() != end_token) {
4059 if (directive_prologue && peek() != Token::STRING) { 4078 if (directive_prologue && peek() != Token::STRING) {
4060 directive_prologue = false; 4079 directive_prologue = false;
4061 } 4080 }
4062 4081
4063 bool starts_with_identifier = peek() == Token::IDENTIFIER; 4082 bool starts_with_identifier = peek() == Token::IDENTIFIER;
4064 Scanner::Location token_loc = scanner()->peek_location(); 4083 Scanner::Location token_loc = scanner()->peek_location();
4065 StatementT stat = impl()->ParseStatementListItem( 4084 StatementT stat = impl()->ParseStatementListItem(
4066 CHECK_OK_CUSTOM(Return, kLazyParsingComplete)); 4085 CHECK_OK_CUSTOM(Return, kLazyParsingComplete));
4067 4086
4068 if (impl()->IsNullOrEmptyStatement(stat)) { 4087 if (impl()->IsNullStatement(stat) || impl()->IsEmptyStatement(stat)) {
4069 directive_prologue = false; // End of directive prologue. 4088 directive_prologue = false; // End of directive prologue.
4070 continue; 4089 continue;
4071 } 4090 }
4072 4091
4073 if (directive_prologue) { 4092 if (directive_prologue) {
4074 // The length of the token is used to distinguish between strings literals 4093 // The length of the token is used to distinguish between strings literals
4075 // that evaluate equal to directives but contain either escape sequences 4094 // that evaluate equal to directives but contain either escape sequences
4076 // (e.g., "use \x73trict") or line continuations (e.g., "use \(newline) 4095 // (e.g., "use \x73trict") or line continuations (e.g., "use \(newline)
4077 // strict"). 4096 // strict").
4078 if (impl()->IsUseStrictDirective(stat) && 4097 if (impl()->IsUseStrictDirective(stat) &&
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
4207 // labels can be simply ignored in all other cases; except for 4226 // labels can be simply ignored in all other cases; except for
4208 // trivial labeled break statements 'label: break label' which is 4227 // trivial labeled break statements 'label: break label' which is
4209 // parsed into an empty statement. 4228 // parsed into an empty statement.
4210 switch (peek()) { 4229 switch (peek()) {
4211 case Token::LBRACE: 4230 case Token::LBRACE:
4212 return impl()->ParseBlock(labels, ok); 4231 return impl()->ParseBlock(labels, ok);
4213 case Token::SEMICOLON: 4232 case Token::SEMICOLON:
4214 Next(); 4233 Next();
4215 return factory()->NewEmptyStatement(kNoSourcePosition); 4234 return factory()->NewEmptyStatement(kNoSourcePosition);
4216 case Token::IF: 4235 case Token::IF:
4217 return impl()->ParseIfStatement(labels, ok); 4236 return ParseIfStatement(labels, ok);
4218 case Token::DO: 4237 case Token::DO:
4219 return impl()->ParseDoWhileStatement(labels, ok); 4238 return impl()->ParseDoWhileStatement(labels, ok);
4220 case Token::WHILE: 4239 case Token::WHILE:
4221 return impl()->ParseWhileStatement(labels, ok); 4240 return impl()->ParseWhileStatement(labels, ok);
4222 case Token::FOR: 4241 case Token::FOR:
4223 return impl()->ParseForStatement(labels, ok); 4242 return impl()->ParseForStatement(labels, ok);
4224 case Token::CONTINUE: 4243 case Token::CONTINUE:
4225 case Token::BREAK: 4244 case Token::BREAK:
4226 case Token::RETURN: 4245 case Token::RETURN:
4227 case Token::THROW: 4246 case Token::THROW:
4228 case Token::TRY: { 4247 case Token::TRY: {
4229 // These statements must have their labels preserved in an enclosing 4248 // These statements must have their labels preserved in an enclosing
4230 // block, as the corresponding AST nodes do not currently store their 4249 // block, as the corresponding AST nodes do not currently store their
4231 // labels. 4250 // labels.
4232 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. 4251 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes.
4233 if (labels == nullptr) { 4252 if (labels == nullptr) {
4234 return ParseStatementAsUnlabelled(labels, ok); 4253 return ParseStatementAsUnlabelled(labels, ok);
4235 } else { 4254 } else {
4236 BlockT result = 4255 BlockT result =
4237 factory()->NewBlock(labels, 1, false, kNoSourcePosition); 4256 factory()->NewBlock(labels, 1, false, kNoSourcePosition);
4238 typename Types::Target target(this, result); 4257 typename Types::Target target(this, result);
4239 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK); 4258 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
4240 result->statements()->Add(statement, zone()); 4259 result->statements()->Add(statement, zone());
4241 return result; 4260 return result;
4242 } 4261 }
4243 } 4262 }
4244 case Token::WITH: 4263 case Token::WITH:
4245 return impl()->ParseWithStatement(labels, ok); 4264 return ParseWithStatement(labels, ok);
4246 case Token::SWITCH: 4265 case Token::SWITCH:
4247 return impl()->ParseSwitchStatement(labels, ok); 4266 return impl()->ParseSwitchStatement(labels, ok);
4248 case Token::FUNCTION: 4267 case Token::FUNCTION:
4249 // FunctionDeclaration only allowed as a StatementListItem, not in 4268 // FunctionDeclaration only allowed as a StatementListItem, not in
4250 // an arbitrary Statement position. Exceptions such as 4269 // an arbitrary Statement position. Exceptions such as
4251 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses 4270 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
4252 // are handled by calling ParseScopedStatement rather than 4271 // are handled by calling ParseScopedStatement rather than
4253 // ParseStatement directly. 4272 // ParseStatement directly.
4254 impl()->ReportMessageAt(scanner()->peek_location(), 4273 impl()->ReportMessageAt(scanner()->peek_location(),
4255 is_strict(language_mode()) 4274 is_strict(language_mode())
4256 ? MessageTemplate::kStrictFunction 4275 ? MessageTemplate::kStrictFunction
4257 : MessageTemplate::kSloppyFunction); 4276 : MessageTemplate::kSloppyFunction);
4258 *ok = false; 4277 *ok = false;
4259 return impl()->NullStatement(); 4278 return impl()->NullStatement();
4260 case Token::DEBUGGER: 4279 case Token::DEBUGGER:
4261 return ParseDebuggerStatement(ok); 4280 return ParseDebuggerStatement(ok);
4262 case Token::VAR: 4281 case Token::VAR:
4263 return ParseVariableStatement(kStatement, nullptr, ok); 4282 return ParseVariableStatement(kStatement, nullptr, ok);
4264 default: 4283 default:
4265 return impl()->ParseExpressionOrLabelledStatement(labels, allow_function, 4284 return ParseExpressionOrLabelledStatement(labels, allow_function, ok);
4266 ok);
4267 } 4285 }
4268 } 4286 }
4269 4287
4270 // This method parses a subset of statements (break, continue, return, throw, 4288 // This method parses a subset of statements (break, continue, return, throw,
4271 // try) which are to be grouped because they all require their labeles to be 4289 // try) which are to be grouped because they all require their labeles to be
4272 // preserved in an enclosing block. 4290 // preserved in an enclosing block.
4273 template <typename Impl> 4291 template <typename Impl>
4274 typename ParserBase<Impl>::StatementT 4292 typename ParserBase<Impl>::StatementT
4275 ParserBase<Impl>::ParseStatementAsUnlabelled( 4293 ParserBase<Impl>::ParseStatementAsUnlabelled(
4276 ZoneList<const AstRawString*>* labels, bool* ok) { 4294 ZoneList<const AstRawString*>* labels, bool* ok) {
4277 switch (peek()) { 4295 switch (peek()) {
4278 case Token::CONTINUE: 4296 case Token::CONTINUE:
4279 return impl()->ParseContinueStatement(ok); 4297 return ParseContinueStatement(ok);
4280 case Token::BREAK: 4298 case Token::BREAK:
4281 return impl()->ParseBreakStatement(labels, ok); 4299 return ParseBreakStatement(labels, ok);
4282 case Token::RETURN: 4300 case Token::RETURN:
4283 return impl()->ParseReturnStatement(ok); 4301 return ParseReturnStatement(ok);
4284 case Token::THROW: 4302 case Token::THROW:
4285 return impl()->ParseThrowStatement(ok); 4303 return impl()->ParseThrowStatement(ok);
4286 case Token::TRY: 4304 case Token::TRY:
4287 return impl()->ParseTryStatement(ok); 4305 return impl()->ParseTryStatement(ok);
4288 default: 4306 default:
4289 UNREACHABLE(); 4307 UNREACHABLE();
4290 return impl()->NullStatement(); 4308 return impl()->NullStatement();
4291 } 4309 }
4292 } 4310 }
4293 4311
4294 template <typename Impl> 4312 template <typename Impl>
4295 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock( 4313 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
4296 ZoneList<const AstRawString*>* labels, bool* ok) { 4314 ZoneList<const AstRawString*>* labels, bool* ok) {
4297 // Block :: 4315 // Block ::
4298 // '{' StatementList '}' 4316 // '{' StatementList '}'
4299 4317
4300 // Construct block expecting 16 statements. 4318 // Construct block expecting 16 statements.
4301 BlockT body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); 4319 BlockT body = factory()->NewBlock(labels, 16, false, kNoSourcePosition);
4302 4320
4303 // Parse the statements and collect escaping labels. 4321 // Parse the statements and collect escaping labels.
4304 Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullBlock)); 4322 Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullBlock));
4305 { 4323 {
4306 BlockState block_state(&scope_state_); 4324 BlockState block_state(&scope_state_);
4307 block_state.set_start_position(scanner()->location().beg_pos); 4325 block_state.set_start_position(scanner()->location().beg_pos);
4308 typename Types::Target target(this, body); 4326 typename Types::Target target(this, body);
4309 4327
4310 while (peek() != Token::RBRACE) { 4328 while (peek() != Token::RBRACE) {
4311 StatementT stat = ParseStatementListItem(CHECK_OK_CUSTOM(NullBlock)); 4329 StatementT stat = ParseStatementListItem(CHECK_OK_CUSTOM(NullBlock));
4312 if (!impl()->IsNullOrEmptyStatement(stat)) { 4330 if (!impl()->IsNullStatement(stat) && !impl()->IsEmptyStatement(stat)) {
4313 body->statements()->Add(stat, zone()); 4331 body->statements()->Add(stat, zone());
4314 } 4332 }
4315 } 4333 }
4316 4334
4317 Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullBlock)); 4335 Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullBlock));
4318 block_state.set_end_position(scanner()->location().end_pos); 4336 block_state.set_end_position(scanner()->location().end_pos);
4319 body->set_scope(block_state.FinalizedBlockScope()); 4337 body->set_scope(block_state.FinalizedBlockScope());
4320 } 4338 }
4321 return body; 4339 return body;
4322 } 4340 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4378 // break point is present. 4396 // break point is present.
4379 // DebuggerStatement :: 4397 // DebuggerStatement ::
4380 // 'debugger' ';' 4398 // 'debugger' ';'
4381 4399
4382 int pos = peek_position(); 4400 int pos = peek_position();
4383 Expect(Token::DEBUGGER, CHECK_OK); 4401 Expect(Token::DEBUGGER, CHECK_OK);
4384 ExpectSemicolon(CHECK_OK); 4402 ExpectSemicolon(CHECK_OK);
4385 return factory()->NewDebuggerStatement(pos); 4403 return factory()->NewDebuggerStatement(pos);
4386 } 4404 }
4387 4405
4406 template <typename Impl>
4407 typename ParserBase<Impl>::StatementT
4408 ParserBase<Impl>::ParseExpressionOrLabelledStatement(
4409 ZoneList<const AstRawString*>* labels,
4410 AllowLabelledFunctionStatement allow_function, bool* ok) {
4411 // ExpressionStatement | LabelledStatement ::
4412 // Expression ';'
4413 // Identifier ':' Statement
4414 //
4415 // ExpressionStatement[Yield] :
4416 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
4417
4418 int pos = peek_position();
4419
4420 switch (peek()) {
4421 case Token::FUNCTION:
4422 case Token::LBRACE:
4423 UNREACHABLE(); // Always handled by the callers.
4424 case Token::CLASS:
4425 ReportUnexpectedToken(Next());
4426 *ok = false;
4427 return impl()->NullStatement();
4428 default:
4429 break;
4430 }
4431
4432 bool starts_with_identifier = peek_any_identifier();
4433 ExpressionT expr = ParseExpression(true, CHECK_OK);
4434 if (peek() == Token::COLON && starts_with_identifier &&
4435 impl()->IsIdentifier(expr)) {
4436 // The whole expression was a single identifier, and not, e.g.,
4437 // something starting with an identifier or a parenthesized identifier.
4438 labels = impl()->DeclareLabel(labels, impl()->AsIdentifierExpression(expr),
4439 CHECK_OK);
4440 Consume(Token::COLON);
4441 // ES#sec-labelled-function-declarations Labelled Function Declarations
4442 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
4443 if (allow_function == kAllowLabelledFunctionStatement) {
4444 return impl()->ParseFunctionDeclaration(ok);
4445 } else {
4446 return ParseScopedStatement(labels, true, ok);
4447 }
4448 }
4449 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
4450 }
4451
4452 // If we have an extension, we allow a native function declaration.
4453 // A native function declaration starts with "native function" with
4454 // no line-terminator between the two words.
4455 if (extension_ != nullptr && peek() == Token::FUNCTION &&
4456 !scanner()->HasAnyLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
4457 !scanner()->literal_contains_escapes()) {
4458 return impl()->ParseNativeDeclaration(ok);
4459 }
4460
4461 // Parsed expression statement, followed by semicolon.
4462 ExpectSemicolon(CHECK_OK);
4463 return factory()->NewExpressionStatement(expr, pos);
4464 }
4465
4466 template <typename Impl>
4467 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
4468 ZoneList<const AstRawString*>* labels, bool* ok) {
4469 // IfStatement ::
4470 // 'if' '(' Expression ')' Statement ('else' Statement)?
4471
4472 int pos = peek_position();
4473 Expect(Token::IF, CHECK_OK);
4474 Expect(Token::LPAREN, CHECK_OK);
4475 ExpressionT condition = ParseExpression(true, CHECK_OK);
4476 Expect(Token::RPAREN, CHECK_OK);
4477 StatementT then_statement = ParseScopedStatement(labels, false, CHECK_OK);
4478 StatementT else_statement = impl()->NullStatement();
4479 if (Check(Token::ELSE)) {
4480 else_statement = ParseScopedStatement(labels, false, CHECK_OK);
4481 } else {
4482 else_statement = factory()->NewEmptyStatement(kNoSourcePosition);
4483 }
4484 return factory()->NewIfStatement(condition, then_statement, else_statement,
4485 pos);
4486 }
4487
4488 template <typename Impl>
4489 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement(
4490 bool* ok) {
4491 // ContinueStatement ::
4492 // 'continue' Identifier? ';'
4493
4494 int pos = peek_position();
4495 Expect(Token::CONTINUE, CHECK_OK);
4496 IdentifierT label = impl()->EmptyIdentifier();
4497 Token::Value tok = peek();
4498 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
4499 tok != Token::RBRACE && tok != Token::EOS) {
4500 // ECMA allows "eval" or "arguments" as labels even in strict mode.
4501 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4502 }
4503 typename Types::IterationStatementT target =
4504 impl()->LookupContinueTarget(label, CHECK_OK);
4505 if (impl()->IsNullStatement(target)) {
4506 // Illegal continue statement.
4507 MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
4508 if (!impl()->IsEmptyIdentifier(label)) {
4509 message = MessageTemplate::kUnknownLabel;
4510 }
4511 ReportMessage(message, label);
4512 *ok = false;
4513 return impl()->NullStatement();
4514 }
4515 ExpectSemicolon(CHECK_OK);
4516 return factory()->NewContinueStatement(target, pos);
4517 }
4518
4519 template <typename Impl>
4520 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
4521 ZoneList<const AstRawString*>* labels, bool* ok) {
4522 // BreakStatement ::
4523 // 'break' Identifier? ';'
4524
4525 int pos = peek_position();
4526 Expect(Token::BREAK, CHECK_OK);
4527 IdentifierT label = impl()->EmptyIdentifier();
4528 Token::Value tok = peek();
4529 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
4530 tok != Token::RBRACE && tok != Token::EOS) {
4531 // ECMA allows "eval" or "arguments" as labels even in strict mode.
4532 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4533 }
4534 // Parse labeled break statements that target themselves into
4535 // empty statements, e.g. 'l1: l2: l3: break l2;'
4536 if (!impl()->IsEmptyIdentifier(label) &&
4537 impl()->ContainsLabel(labels, label)) {
4538 ExpectSemicolon(CHECK_OK);
4539 return factory()->NewEmptyStatement(pos);
4540 }
4541 typename Types::BreakableStatementT target =
4542 impl()->LookupBreakTarget(label, CHECK_OK);
4543 if (impl()->IsNullStatement(target)) {
4544 // Illegal break statement.
4545 MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
4546 if (!impl()->IsEmptyIdentifier(label)) {
4547 message = MessageTemplate::kUnknownLabel;
4548 }
4549 ReportMessage(message, label);
4550 *ok = false;
4551 return impl()->NullStatement();
4552 }
4553 ExpectSemicolon(CHECK_OK);
4554 return factory()->NewBreakStatement(target, pos);
4555 }
4556
4557 template <typename Impl>
4558 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement(
4559 bool* ok) {
4560 // ReturnStatement ::
4561 // 'return' [no line terminator] Expression? ';'
4562
4563 // Consume the return token. It is necessary to do that before
4564 // reporting any errors on it, because of the way errors are
4565 // reported (underlining).
4566 Expect(Token::RETURN, CHECK_OK);
4567 Scanner::Location loc = scanner()->location();
4568
4569 Token::Value tok = peek();
4570 ExpressionT return_value = impl()->EmptyExpression();
4571 if (scanner()->HasAnyLineTerminatorBeforeNext() || tok == Token::SEMICOLON ||
4572 tok == Token::RBRACE || tok == Token::EOS) {
4573 if (IsSubclassConstructor(function_state_->kind())) {
4574 return_value = impl()->ThisExpression(loc.beg_pos);
4575 } else {
4576 return_value = impl()->GetLiteralUndefined(position());
4577 }
4578 } else {
4579 if (IsSubclassConstructor(function_state_->kind())) {
4580 // Because of the return code rewriting that happens in case of a subclass
4581 // constructor we don't want to accept tail calls, therefore we don't set
4582 // ReturnExprScope to kInsideValidReturnStatement here.
4583 return_value = ParseExpression(true, CHECK_OK);
4584 } else {
4585 ReturnExprScope maybe_allow_tail_calls(
4586 function_state_, ReturnExprContext::kInsideValidReturnStatement);
4587 return_value = ParseExpression(true, CHECK_OK);
4588
4589 if (allow_tailcalls() && !is_sloppy(language_mode()) && !is_resumable()) {
4590 // ES6 14.6.1 Static Semantics: IsInTailPosition
4591 function_state_->AddImplicitTailCallExpression(return_value);
4592 }
4593 }
4594 }
4595 ExpectSemicolon(CHECK_OK);
4596 return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
4597
4598 DeclarationScope* decl_scope = GetDeclarationScope();
4599 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
4600 impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
4601 *ok = false;
4602 return impl()->NullStatement();
4603 }
4604 return factory()->NewReturnStatement(return_value, loc.beg_pos);
4605 }
4606
4607 template <typename Impl>
4608 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
4609 ZoneList<const AstRawString*>* labels, bool* ok) {
4610 // WithStatement ::
4611 // 'with' '(' Expression ')' Statement
4612
4613 Expect(Token::WITH, CHECK_OK);
4614 int pos = position();
4615
4616 if (is_strict(language_mode())) {
4617 ReportMessage(MessageTemplate::kStrictWith);
4618 *ok = false;
4619 return impl()->NullStatement();
4620 }
4621
4622 Expect(Token::LPAREN, CHECK_OK);
4623 ExpressionT expr = ParseExpression(true, CHECK_OK);
4624 Expect(Token::RPAREN, CHECK_OK);
4625
4626 Scope* with_scope = NewScope(WITH_SCOPE);
4627 StatementT body = impl()->NullStatement();
4628 {
4629 BlockState block_state(&scope_state_, with_scope);
4630 with_scope->set_start_position(scanner()->peek_location().beg_pos);
4631 body = ParseScopedStatement(labels, true, CHECK_OK);
4632 with_scope->set_end_position(scanner()->location().end_pos);
4633 }
4634 return factory()->NewWithStatement(with_scope, expr, body, pos);
4635 }
4636
4388 #undef CHECK_OK 4637 #undef CHECK_OK
4389 #undef CHECK_OK_CUSTOM 4638 #undef CHECK_OK_CUSTOM
4390 4639
4391 template <typename Impl> 4640 template <typename Impl>
4392 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( 4641 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
4393 Token::Value property) { 4642 Token::Value property) {
4394 if (property == Token::SMI || property == Token::NUMBER) return; 4643 if (property == Token::SMI || property == Token::NUMBER) return;
4395 4644
4396 if (IsProto()) { 4645 if (IsProto()) {
4397 if (has_seen_proto_) { 4646 if (has_seen_proto_) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4436 has_seen_constructor_ = true; 4685 has_seen_constructor_ = true;
4437 return; 4686 return;
4438 } 4687 }
4439 } 4688 }
4440 4689
4441 4690
4442 } // namespace internal 4691 } // namespace internal
4443 } // namespace v8 4692 } // namespace v8
4444 4693
4445 #endif // V8_PARSING_PARSER_BASE_H 4694 #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