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

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

Issue 2324843005: [parser] Refactor of Parse*Statement*, part 6 (Closed)
Patch Set: The real patch 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
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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 // typedef Expression; 131 // typedef Expression;
132 // typedef FunctionLiteral; 132 // typedef FunctionLiteral;
133 // typedef ObjectLiteralProperty; 133 // typedef ObjectLiteralProperty;
134 // typedef ClassLiteralProperty; 134 // typedef ClassLiteralProperty;
135 // typedef ExpressionList; 135 // typedef ExpressionList;
136 // typedef PropertyList; 136 // typedef PropertyList;
137 // typedef FormalParameters; 137 // typedef FormalParameters;
138 // typedef Statement; 138 // typedef Statement;
139 // typedef StatementList; 139 // typedef StatementList;
140 // typedef Block; 140 // typedef Block;
141 // typedef BreakableStatement;
142 // typedef IterationStatement;
141 // // For constructing objects returned by the traversing functions. 143 // // For constructing objects returned by the traversing functions.
142 // typedef Factory; 144 // typedef Factory;
143 // // For other implementation-specific tasks. 145 // // For other implementation-specific tasks.
144 // typedef Target; 146 // typedef Target;
145 // typedef TargetScope; 147 // typedef TargetScope;
146 // }; 148 // };
147 149
148 template <typename Impl> 150 template <typename Impl>
149 struct ParserTypes; 151 struct ParserTypes;
150 152
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, 1207 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels,
1206 bool* ok); 1208 bool* ok);
1207 StatementT ParseReturnStatement(bool* ok); 1209 StatementT ParseReturnStatement(bool* ok);
1208 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, 1210 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels,
1209 bool* ok); 1211 bool* ok);
1210 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, 1212 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
1211 bool* ok); 1213 bool* ok);
1212 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, 1214 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels,
1213 bool* ok); 1215 bool* ok);
1214 StatementT ParseThrowStatement(bool* ok); 1216 StatementT ParseThrowStatement(bool* ok);
1217 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
1218 bool* ok);
1215 1219
1216 bool IsNextLetKeyword(); 1220 bool IsNextLetKeyword();
1217 bool IsTrivialExpression(); 1221 bool IsTrivialExpression();
1218 1222
1219 // Checks if the expression is a valid reference expression (e.g., on the 1223 // Checks if the expression is a valid reference expression (e.g., on the
1220 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1224 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1221 // we allow calls for web compatibility and rewrite them to a runtime throw. 1225 // we allow calls for web compatibility and rewrite them to a runtime throw.
1222 ExpressionT CheckAndRewriteReferenceExpression( 1226 ExpressionT CheckAndRewriteReferenceExpression(
1223 ExpressionT expression, int beg_pos, int end_pos, 1227 ExpressionT expression, int beg_pos, int end_pos,
1224 MessageTemplate::Template message, bool* ok); 1228 MessageTemplate::Template message, bool* ok);
(...skipping 2983 matching lines...) Expand 10 before | Expand all | Expand 10 after
4208 factory()->NewBlock(labels, 1, false, kNoSourcePosition); 4212 factory()->NewBlock(labels, 1, false, kNoSourcePosition);
4209 typename Types::Target target(this, result); 4213 typename Types::Target target(this, result);
4210 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK); 4214 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
4211 result->statements()->Add(statement, zone()); 4215 result->statements()->Add(statement, zone());
4212 return result; 4216 return result;
4213 } 4217 }
4214 } 4218 }
4215 case Token::WITH: 4219 case Token::WITH:
4216 return ParseWithStatement(labels, ok); 4220 return ParseWithStatement(labels, ok);
4217 case Token::SWITCH: 4221 case Token::SWITCH:
4218 return impl()->ParseSwitchStatement(labels, ok); 4222 return ParseSwitchStatement(labels, ok);
4219 case Token::FUNCTION: 4223 case Token::FUNCTION:
4220 // FunctionDeclaration only allowed as a StatementListItem, not in 4224 // FunctionDeclaration only allowed as a StatementListItem, not in
4221 // an arbitrary Statement position. Exceptions such as 4225 // an arbitrary Statement position. Exceptions such as
4222 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses 4226 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
4223 // are handled by calling ParseScopedStatement rather than 4227 // are handled by calling ParseScopedStatement rather than
4224 // ParseStatement directly. 4228 // ParseStatement directly.
4225 impl()->ReportMessageAt(scanner()->peek_location(), 4229 impl()->ReportMessageAt(scanner()->peek_location(),
4226 is_strict(language_mode()) 4230 is_strict(language_mode())
4227 ? MessageTemplate::kStrictFunction 4231 ? MessageTemplate::kStrictFunction
4228 : MessageTemplate::kSloppyFunction); 4232 : MessageTemplate::kSloppyFunction);
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
4443 4447
4444 int pos = peek_position(); 4448 int pos = peek_position();
4445 Expect(Token::CONTINUE, CHECK_OK); 4449 Expect(Token::CONTINUE, CHECK_OK);
4446 IdentifierT label = impl()->EmptyIdentifier(); 4450 IdentifierT label = impl()->EmptyIdentifier();
4447 Token::Value tok = peek(); 4451 Token::Value tok = peek();
4448 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON && 4452 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
4449 tok != Token::RBRACE && tok != Token::EOS) { 4453 tok != Token::RBRACE && tok != Token::EOS) {
4450 // ECMA allows "eval" or "arguments" as labels even in strict mode. 4454 // ECMA allows "eval" or "arguments" as labels even in strict mode.
4451 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 4455 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4452 } 4456 }
4453 typename Types::IterationStatementT target = 4457 typename Types::IterationStatement target =
4454 impl()->LookupContinueTarget(label, CHECK_OK); 4458 impl()->LookupContinueTarget(label, CHECK_OK);
4455 if (impl()->IsNullStatement(target)) { 4459 if (impl()->IsNullStatement(target)) {
4456 // Illegal continue statement. 4460 // Illegal continue statement.
4457 MessageTemplate::Template message = MessageTemplate::kIllegalContinue; 4461 MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
4458 if (!impl()->IsEmptyIdentifier(label)) { 4462 if (!impl()->IsEmptyIdentifier(label)) {
4459 message = MessageTemplate::kUnknownLabel; 4463 message = MessageTemplate::kUnknownLabel;
4460 } 4464 }
4461 ReportMessage(message, label); 4465 ReportMessage(message, label);
4462 *ok = false; 4466 *ok = false;
4463 return impl()->NullStatement(); 4467 return impl()->NullStatement();
(...skipping 17 matching lines...) Expand all
4481 // ECMA allows "eval" or "arguments" as labels even in strict mode. 4485 // ECMA allows "eval" or "arguments" as labels even in strict mode.
4482 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 4486 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4483 } 4487 }
4484 // Parse labeled break statements that target themselves into 4488 // Parse labeled break statements that target themselves into
4485 // empty statements, e.g. 'l1: l2: l3: break l2;' 4489 // empty statements, e.g. 'l1: l2: l3: break l2;'
4486 if (!impl()->IsEmptyIdentifier(label) && 4490 if (!impl()->IsEmptyIdentifier(label) &&
4487 impl()->ContainsLabel(labels, label)) { 4491 impl()->ContainsLabel(labels, label)) {
4488 ExpectSemicolon(CHECK_OK); 4492 ExpectSemicolon(CHECK_OK);
4489 return factory()->NewEmptyStatement(pos); 4493 return factory()->NewEmptyStatement(pos);
4490 } 4494 }
4491 typename Types::BreakableStatementT target = 4495 typename Types::BreakableStatement target =
4492 impl()->LookupBreakTarget(label, CHECK_OK); 4496 impl()->LookupBreakTarget(label, CHECK_OK);
4493 if (impl()->IsNullStatement(target)) { 4497 if (impl()->IsNullStatement(target)) {
4494 // Illegal break statement. 4498 // Illegal break statement.
4495 MessageTemplate::Template message = MessageTemplate::kIllegalBreak; 4499 MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
4496 if (!impl()->IsEmptyIdentifier(label)) { 4500 if (!impl()->IsEmptyIdentifier(label)) {
4497 message = MessageTemplate::kUnknownLabel; 4501 message = MessageTemplate::kUnknownLabel;
4498 } 4502 }
4499 ReportMessage(message, label); 4503 ReportMessage(message, label);
4500 *ok = false; 4504 *ok = false;
4501 return impl()->NullStatement(); 4505 return impl()->NullStatement();
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
4640 ReportMessage(MessageTemplate::kNewlineAfterThrow); 4644 ReportMessage(MessageTemplate::kNewlineAfterThrow);
4641 *ok = false; 4645 *ok = false;
4642 return impl()->NullStatement(); 4646 return impl()->NullStatement();
4643 } 4647 }
4644 ExpressionT exception = ParseExpression(true, CHECK_OK); 4648 ExpressionT exception = ParseExpression(true, CHECK_OK);
4645 ExpectSemicolon(CHECK_OK); 4649 ExpectSemicolon(CHECK_OK);
4646 4650
4647 return impl()->NewThrowStatement(exception, pos); 4651 return impl()->NewThrowStatement(exception, pos);
4648 } 4652 }
4649 4653
4654 template <typename Impl>
4655 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
4656 ZoneList<const AstRawString*>* labels, bool* ok) {
4657 // SwitchStatement ::
4658 // 'switch' '(' Expression ')' '{' CaseClause* '}'
4659 // CaseClause ::
4660 // 'case' Expression ':' StatementList
4661 // 'default' ':' StatementList
4662
4663 int switch_pos = peek_position();
4664
4665 Expect(Token::SWITCH, CHECK_OK);
4666 Expect(Token::LPAREN, CHECK_OK);
4667 ExpressionT tag = ParseExpression(true, CHECK_OK);
4668 Expect(Token::RPAREN, CHECK_OK);
4669
4670 auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos);
4671
4672 {
4673 BlockState cases_block_state(&scope_state_);
4674 cases_block_state.set_start_position(scanner()->location().beg_pos);
4675 cases_block_state.SetNonlinear();
4676 typename Types::Target target(this, switch_statement);
4677
4678 bool default_seen = false;
4679 auto cases = impl()->NewCaseClauseList(4);
4680 Expect(Token::LBRACE, CHECK_OK);
4681 while (peek() != Token::RBRACE) {
4682 // An empty label indicates the default case.
4683 ExpressionT label = impl()->EmptyExpression();
4684 if (Check(Token::CASE)) {
4685 label = ParseExpression(true, CHECK_OK);
4686 } else {
4687 Expect(Token::DEFAULT, CHECK_OK);
4688 if (default_seen) {
4689 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
4690 *ok = false;
4691 return impl()->NullStatement();
4692 }
4693 default_seen = true;
4694 }
4695 Expect(Token::COLON, CHECK_OK);
4696 int clause_pos = position();
4697 StatementListT statements = impl()->NewStatementList(5);
4698 while (peek() != Token::CASE && peek() != Token::DEFAULT &&
4699 peek() != Token::RBRACE) {
4700 StatementT stat = ParseStatementListItem(CHECK_OK);
4701 statements->Add(stat, zone());
4702 }
4703 auto clause = factory()->NewCaseClause(label, statements, clause_pos);
4704 cases->Add(clause, zone());
4705 }
4706 Expect(Token::RBRACE, CHECK_OK);
4707
4708 cases_block_state.set_end_position(scanner()->location().end_pos);
4709 return impl()->RewriteSwitchStatement(
4710 tag, switch_statement, cases, cases_block_state.FinalizedBlockScope());
4711 }
4712 }
4713
4650 #undef CHECK_OK 4714 #undef CHECK_OK
4651 #undef CHECK_OK_CUSTOM 4715 #undef CHECK_OK_CUSTOM
4652 4716
4653 template <typename Impl> 4717 template <typename Impl>
4654 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( 4718 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
4655 Token::Value property) { 4719 Token::Value property) {
4656 if (property == Token::SMI || property == Token::NUMBER) return; 4720 if (property == Token::SMI || property == Token::NUMBER) return;
4657 4721
4658 if (IsProto()) { 4722 if (IsProto()) {
4659 if (has_seen_proto_) { 4723 if (has_seen_proto_) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4698 has_seen_constructor_ = true; 4762 has_seen_constructor_ = true;
4699 return; 4763 return;
4700 } 4764 }
4701 } 4765 }
4702 4766
4703 4767
4704 } // namespace internal 4768 } // namespace internal
4705 } // namespace v8 4769 } // namespace v8
4706 4770
4707 #endif // V8_PARSING_PARSER_BASE_H 4771 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« src/parsing/parser.cc ('K') | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698