OLD | NEW |
---|---|
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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 // // not related to pure parsing. | 179 // // not related to pure parsing. |
180 // typedef GeneratorVariable; | 180 // typedef GeneratorVariable; |
181 // // Return types for traversing functions. | 181 // // Return types for traversing functions. |
182 // typedef Identifier; | 182 // typedef Identifier; |
183 // typedef Expression; | 183 // typedef Expression; |
184 // typedef FunctionLiteral; | 184 // typedef FunctionLiteral; |
185 // typedef ObjectLiteralProperty; | 185 // typedef ObjectLiteralProperty; |
186 // typedef ExpressionList; | 186 // typedef ExpressionList; |
187 // typedef PropertyList; | 187 // typedef PropertyList; |
188 // typedef FormalParameters; | 188 // typedef FormalParameters; |
189 // typedef Statement; | |
189 // typedef StatementList; | 190 // typedef StatementList; |
190 // typedef Block; | 191 // typedef Block; |
191 // // For constructing objects returned by the traversing functions. | 192 // // For constructing objects returned by the traversing functions. |
192 // typedef Factory; | 193 // typedef Factory; |
194 // // For other implementation-specific tasks. | |
195 // typedef Target; | |
196 // typedef TargetScope; | |
193 // }; | 197 // }; |
194 | 198 |
195 template <typename Impl> | 199 template <typename Impl> |
196 struct ParserTypes; | 200 struct ParserTypes; |
197 | 201 |
198 template <typename Impl> | 202 template <typename Impl> |
199 class ParserBase { | 203 class ParserBase { |
200 public: | 204 public: |
201 // Shorten type names defined by ParserTypes<Impl>. | 205 // Shorten type names defined by ParserTypes<Impl>. |
202 typedef ParserTypes<Impl> Types; | 206 typedef ParserTypes<Impl> Types; |
203 typedef typename Types::Identifier IdentifierT; | 207 typedef typename Types::Identifier IdentifierT; |
204 typedef typename Types::Expression ExpressionT; | 208 typedef typename Types::Expression ExpressionT; |
205 typedef typename Types::FunctionLiteral FunctionLiteralT; | 209 typedef typename Types::FunctionLiteral FunctionLiteralT; |
206 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; | 210 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; |
207 typedef typename Types::ExpressionList ExpressionListT; | 211 typedef typename Types::ExpressionList ExpressionListT; |
208 typedef typename Types::PropertyList PropertyListT; | 212 typedef typename Types::PropertyList PropertyListT; |
209 typedef typename Types::FormalParameters FormalParametersT; | 213 typedef typename Types::FormalParameters FormalParametersT; |
214 typedef typename Types::Statement StatementT; | |
210 typedef typename Types::StatementList StatementListT; | 215 typedef typename Types::StatementList StatementListT; |
211 typedef typename Types::Block BlockT; | 216 typedef typename Types::Block BlockT; |
212 typedef typename v8::internal::ExpressionClassifier<Types> | 217 typedef typename v8::internal::ExpressionClassifier<Types> |
213 ExpressionClassifier; | 218 ExpressionClassifier; |
214 | 219 |
215 // All implementation-specific methods must be called through this. | 220 // All implementation-specific methods must be called through this. |
216 Impl* impl() { return static_cast<Impl*>(this); } | 221 Impl* impl() { return static_cast<Impl*>(this); } |
217 const Impl* impl() const { return static_cast<const Impl*>(this); } | 222 const Impl* impl() const { return static_cast<const Impl*>(this); } |
218 | 223 |
219 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 224 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
909 return 0; // 0 precedence will terminate binary expression parsing | 914 return 0; // 0 precedence will terminate binary expression parsing |
910 return Token::Precedence(token); | 915 return Token::Precedence(token); |
911 } | 916 } |
912 | 917 |
913 typename Types::Factory* factory() { return &ast_node_factory_; } | 918 typename Types::Factory* factory() { return &ast_node_factory_; } |
914 | 919 |
915 DeclarationScope* GetReceiverScope() const { | 920 DeclarationScope* GetReceiverScope() const { |
916 return scope()->GetReceiverScope(); | 921 return scope()->GetReceiverScope(); |
917 } | 922 } |
918 LanguageMode language_mode() { return scope()->language_mode(); } | 923 LanguageMode language_mode() { return scope()->language_mode(); } |
924 void RaiseLanguageMode(LanguageMode mode) { | |
925 LanguageMode old = scope()->language_mode(); | |
926 impl()->SetLanguageMode(scope(), old > mode ? old : mode); | |
927 } | |
919 bool is_generator() const { return function_state_->is_generator(); } | 928 bool is_generator() const { return function_state_->is_generator(); } |
920 bool is_async_function() const { | 929 bool is_async_function() const { |
921 return function_state_->is_async_function(); | 930 return function_state_->is_async_function(); |
922 } | 931 } |
923 bool is_resumable() const { return function_state_->is_resumable(); } | 932 bool is_resumable() const { return function_state_->is_resumable(); } |
924 | 933 |
925 // Report syntax errors. | 934 // Report syntax errors. |
926 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, | 935 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, |
927 ParseErrorType error_type = kSyntaxError) { | 936 ParseErrorType error_type = kSyntaxError) { |
928 Scanner::Location source_location = scanner()->location(); | 937 Scanner::Location source_location = scanner()->location(); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1065 } | 1074 } |
1066 | 1075 |
1067 void ArrowFormalParametersUnexpectedToken() { | 1076 void ArrowFormalParametersUnexpectedToken() { |
1068 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 1077 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
1069 const char* arg; | 1078 const char* arg; |
1070 Scanner::Location location = scanner()->peek_location(); | 1079 Scanner::Location location = scanner()->peek_location(); |
1071 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 1080 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
1072 classifier()->RecordArrowFormalParametersError(location, message, arg); | 1081 classifier()->RecordArrowFormalParametersError(location, message, arg); |
1073 } | 1082 } |
1074 | 1083 |
1075 // Recursive descent functions: | 1084 // Recursive descent functions. |
1085 // All ParseXXX functions take as the last argument an *ok parameter | |
1086 // which is set to false if parsing failed; it is unchanged otherwise. | |
1087 // By making the 'exception handling' explicit, we are forced to check | |
1088 // for failure at the call sites. The family of CHECK_OK* macros can | |
1089 // be useful for this. | |
1076 | 1090 |
1077 // Parses an identifier that is valid for the current scope, in particular it | 1091 // Parses an identifier that is valid for the current scope, in particular it |
1078 // fails on strict mode future reserved keywords in a strict scope. If | 1092 // fails on strict mode future reserved keywords in a strict scope. If |
1079 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 1093 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
1080 // "arguments" as identifier even in strict mode (this is needed in cases like | 1094 // "arguments" as identifier even in strict mode (this is needed in cases like |
1081 // "var foo = eval;"). | 1095 // "var foo = eval;"). |
1082 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); | 1096 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
1083 IdentifierT ParseAndClassifyIdentifier(bool* ok); | 1097 IdentifierT ParseAndClassifyIdentifier(bool* ok); |
1084 // Parses an identifier or a strict mode future reserved word, and indicate | 1098 // Parses an identifier or a strict mode future reserved word, and indicate |
1085 // whether it is strict mode future reserved. Allows passing in function_kind | 1099 // whether it is strict mode future reserved. Allows passing in function_kind |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1172 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); | 1186 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); |
1173 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 1187 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
1174 bool has_rest, int formals_start_pos, | 1188 bool has_rest, int formals_start_pos, |
1175 int formals_end_pos, bool* ok); | 1189 int formals_end_pos, bool* ok); |
1176 | 1190 |
1177 BlockT ParseVariableDeclarations(VariableDeclarationContext var_context, | 1191 BlockT ParseVariableDeclarations(VariableDeclarationContext var_context, |
1178 DeclarationParsingResult* parsing_result, | 1192 DeclarationParsingResult* parsing_result, |
1179 ZoneList<const AstRawString*>* names, | 1193 ZoneList<const AstRawString*>* names, |
1180 bool* ok); | 1194 bool* ok); |
1181 | 1195 |
1196 // Under some circumstances, we allow preparsing to abort if the preparsed | |
1197 // function is "long and trivial", and fully parse instead. Our current | |
1198 // definition of "long and trivial" is: | |
1199 // - over kLazyParseTrialLimit statements | |
1200 // - all starting with an identifier (i.e., no if, for, while, etc.) | |
1201 static const int kLazyParseTrialLimit = 200; | |
1202 | |
1203 // TODO(nikolaos, marja): The first argument should not really be passed | |
1204 // by value. The method is expected to add the parsed statements to the | |
1205 // list. This works because in the case of the parser, StatementListT is | |
1206 // a pointer whereas the preparser does not really modify the body. | |
1207 V8_INLINE void ParseStatementList(StatementListT body, int end_token, | |
1208 bool* ok) { | |
1209 LazyParsingResult result = ParseStatementList(body, end_token, false, ok); | |
1210 USE(result); | |
1211 DCHECK_EQ(result, kLazyParsingComplete); | |
1212 } | |
1213 LazyParsingResult ParseStatementList(StatementListT body, int end_token, | |
1214 bool may_abort, bool* ok); | |
1215 StatementT ParseStatementListItem(bool* ok); | |
1216 StatementT ParseStatement(ZoneList<const AstRawString*>* labels, | |
1217 AllowLabelledFunctionStatement allow_function, | |
1218 bool* ok); | |
1219 StatementT ParseStatementAsUnlabelled(ZoneList<const AstRawString*>* labels, | |
1220 bool* ok); | |
1221 | |
1182 bool IsNextLetKeyword(); | 1222 bool IsNextLetKeyword(); |
1183 bool IsTrivialExpression(); | 1223 bool IsTrivialExpression(); |
1184 | 1224 |
1185 // Checks if the expression is a valid reference expression (e.g., on the | 1225 // Checks if the expression is a valid reference expression (e.g., on the |
1186 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1226 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1187 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1227 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1188 ExpressionT CheckAndRewriteReferenceExpression( | 1228 ExpressionT CheckAndRewriteReferenceExpression( |
1189 ExpressionT expression, int beg_pos, int end_pos, | 1229 ExpressionT expression, int beg_pos, int end_pos, |
1190 MessageTemplate::Template message, bool* ok); | 1230 MessageTemplate::Template message, bool* ok); |
1191 ExpressionT CheckAndRewriteReferenceExpression( | 1231 ExpressionT CheckAndRewriteReferenceExpression( |
(...skipping 2714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3906 void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression, | 3946 void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression, |
3907 int begin, int end) { | 3947 int begin, int end) { |
3908 if (!IsValidPattern(expression) && !expression->IsAssignment() && | 3948 if (!IsValidPattern(expression) && !expression->IsAssignment() && |
3909 !IsValidReferenceExpression(expression)) { | 3949 !IsValidReferenceExpression(expression)) { |
3910 classifier()->RecordAssignmentPatternError( | 3950 classifier()->RecordAssignmentPatternError( |
3911 Scanner::Location(begin, end), | 3951 Scanner::Location(begin, end), |
3912 MessageTemplate::kInvalidDestructuringTarget); | 3952 MessageTemplate::kInvalidDestructuringTarget); |
3913 } | 3953 } |
3914 } | 3954 } |
3915 | 3955 |
3956 // Redefinition of CHECK_OK for parsing statements. | |
3957 #undef CHECK_OK | |
3958 #define CHECK_OK CHECK_OK_CUSTOM(NullStatement) | |
3959 | |
3960 template <typename Impl> | |
3961 typename ParserBase<Impl>::LazyParsingResult | |
3962 ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token, | |
3963 bool may_abort, bool* ok) { | |
3964 // StatementList :: | |
3965 // (StatementListItem)* <end_token> | |
3966 | |
3967 // Allocate a target stack to use for this set of source | |
3968 // elements. This way, all scripts and functions get their own | |
3969 // target stack thus avoiding illegal breaks and continues across | |
3970 // functions. | |
3971 typename Types::TargetScope target_scope(this); | |
3972 int count_statements = 0; | |
3973 | |
3974 DCHECK(!impl()->IsNullStatementList(body)); | |
3975 bool directive_prologue = true; // Parsing directive prologue. | |
3976 | |
3977 while (peek() != end_token) { | |
3978 if (directive_prologue && peek() != Token::STRING) { | |
3979 directive_prologue = false; | |
3980 } | |
3981 | |
3982 bool starts_with_identifier = peek() == Token::IDENTIFIER; | |
3983 Scanner::Location token_loc = scanner()->peek_location(); | |
3984 StatementT stat = impl()->ParseStatementListItem( | |
3985 CHECK_OK_CUSTOM(Return, kLazyParsingComplete)); | |
3986 | |
3987 if (impl()->IsNullOrEmptyStatement(stat)) { | |
3988 directive_prologue = false; // End of directive prologue. | |
3989 continue; | |
3990 } | |
3991 | |
3992 if (directive_prologue) { | |
3993 // The length of the token is used to distinguish between strings literals | |
3994 // that evaluate equal to directives but contain either escape sequences | |
3995 // (e.g., "use \x73trict") or line continuations (e.g., "use \(newline) | |
3996 // strict"). | |
3997 if (impl()->IsUseStrictDirective(stat) && | |
3998 token_loc.end_pos - token_loc.beg_pos == sizeof("use strict") + 1) { | |
3999 // Directive "use strict" (ES5 14.1). | |
4000 RaiseLanguageMode(STRICT); | |
4001 if (!scope()->HasSimpleParameters()) { | |
4002 // TC39 deemed "use strict" directives to be an error when occurring | |
4003 // in the body of a function with non-simple parameter list, on | |
4004 // 29/7/2015. https://goo.gl/ueA7Ln | |
4005 impl()->ReportMessageAt( | |
4006 token_loc, MessageTemplate::kIllegalLanguageModeDirective, | |
4007 "use strict"); | |
4008 *ok = false; | |
4009 return kLazyParsingComplete; | |
4010 } | |
4011 // Because declarations in strict eval code don't leak into the scope | |
4012 // of the eval call, it is likely that functions declared in strict | |
4013 // eval code will be used within the eval code, so lazy parsing is | |
4014 // probably not a win. | |
4015 if (scope()->is_eval_scope()) mode_ = PARSE_EAGERLY; | |
4016 } else if (impl()->IsUseAsmDirective(stat) && | |
4017 token_loc.end_pos - token_loc.beg_pos == | |
4018 sizeof("use asm") + 1) { | |
4019 // Directive "use asm". | |
4020 impl()->SetAsmModule(); | |
4021 } else if (impl()->IsStringLiteral(stat)) { | |
4022 // Possibly an unknown directive. | |
4023 // TODO(nikolaos): Check if the following is really what we want! | |
4024 // """Should not change mode, but will increment UseCounter | |
4025 // if appropriate. Ditto usages below.""" ??? | |
4026 RaiseLanguageMode(SLOPPY); | |
Dan Ehrenberg
2016/09/06 16:57:03
The comparison logic in RaiseLanguageMode which yo
| |
4027 } else { | |
4028 // End of the directive prologue. | |
4029 directive_prologue = false; | |
4030 // TODO(nikolaos): Check if the following is really what we want! | |
4031 RaiseLanguageMode(SLOPPY); | |
4032 } | |
4033 } else { | |
4034 // TODO(nikolaos): Check if the following is really what we want! | |
4035 RaiseLanguageMode(SLOPPY); | |
4036 } | |
4037 | |
4038 // If we're allowed to abort, we will do so when we see a "long and | |
4039 // trivial" function. Our current definition of "long and trivial" is: | |
4040 // - over kLazyParseTrialLimit statements | |
4041 // - all starting with an identifier (i.e., no if, for, while, etc.) | |
4042 if (may_abort) { | |
4043 if (!starts_with_identifier) { | |
4044 may_abort = false; | |
4045 } else if (++count_statements > kLazyParseTrialLimit) { | |
4046 return kLazyParsingAborted; | |
4047 } | |
4048 } | |
4049 | |
4050 body->Add(stat, zone()); | |
4051 } | |
4052 return kLazyParsingComplete; | |
4053 } | |
4054 | |
4055 template <typename Impl> | |
4056 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatementListItem( | |
4057 bool* ok) { | |
4058 // ECMA 262 6th Edition | |
4059 // StatementListItem[Yield, Return] : | |
4060 // Statement[?Yield, ?Return] | |
4061 // Declaration[?Yield] | |
4062 // | |
4063 // Declaration[Yield] : | |
4064 // HoistableDeclaration[?Yield] | |
4065 // ClassDeclaration[?Yield] | |
4066 // LexicalDeclaration[In, ?Yield] | |
4067 // | |
4068 // HoistableDeclaration[Yield, Default] : | |
4069 // FunctionDeclaration[?Yield, ?Default] | |
4070 // GeneratorDeclaration[?Yield, ?Default] | |
4071 // | |
4072 // LexicalDeclaration[In, Yield] : | |
4073 // LetOrConst BindingList[?In, ?Yield] ; | |
4074 | |
4075 switch (peek()) { | |
4076 case Token::FUNCTION: | |
4077 return impl()->ParseHoistableDeclaration(nullptr, false, ok); | |
4078 case Token::CLASS: | |
4079 Consume(Token::CLASS); | |
4080 return impl()->ParseClassDeclaration(nullptr, false, ok); | |
4081 case Token::VAR: | |
4082 case Token::CONST: | |
4083 return impl()->ParseVariableStatement(kStatementListItem, nullptr, ok); | |
4084 case Token::LET: | |
4085 if (IsNextLetKeyword()) { | |
4086 return impl()->ParseVariableStatement(kStatementListItem, nullptr, ok); | |
4087 } | |
4088 break; | |
4089 case Token::ASYNC: | |
4090 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && | |
4091 !scanner()->HasAnyLineTerminatorAfterNext()) { | |
4092 Consume(Token::ASYNC); | |
4093 return impl()->ParseAsyncFunctionDeclaration(nullptr, false, ok); | |
4094 } | |
4095 /* falls through */ | |
4096 default: | |
4097 break; | |
4098 } | |
4099 return impl()->ParseStatement(nullptr, kAllowLabelledFunctionStatement, ok); | |
4100 } | |
4101 | |
4102 template <typename Impl> | |
4103 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement( | |
4104 ZoneList<const AstRawString*>* labels, | |
4105 AllowLabelledFunctionStatement allow_function, bool* ok) { | |
4106 // Statement :: | |
4107 // Block | |
4108 // VariableStatement | |
4109 // EmptyStatement | |
4110 // ExpressionStatement | |
4111 // IfStatement | |
4112 // IterationStatement | |
4113 // ContinueStatement | |
4114 // BreakStatement | |
4115 // ReturnStatement | |
4116 // WithStatement | |
4117 // LabelledStatement | |
4118 // SwitchStatement | |
4119 // ThrowStatement | |
4120 // TryStatement | |
4121 // DebuggerStatement | |
4122 | |
4123 // Note: Since labels can only be used by 'break' and 'continue' | |
4124 // statements, which themselves are only valid within blocks, | |
4125 // iterations or 'switch' statements (i.e., BreakableStatements), | |
4126 // labels can be simply ignored in all other cases; except for | |
4127 // trivial labeled break statements 'label: break label' which is | |
4128 // parsed into an empty statement. | |
4129 switch (peek()) { | |
4130 case Token::LBRACE: | |
4131 return impl()->ParseBlock(labels, ok); | |
4132 case Token::SEMICOLON: | |
4133 Next(); | |
4134 return factory()->NewEmptyStatement(kNoSourcePosition); | |
4135 case Token::IF: | |
4136 return impl()->ParseIfStatement(labels, ok); | |
4137 case Token::DO: | |
4138 return impl()->ParseDoWhileStatement(labels, ok); | |
4139 case Token::WHILE: | |
4140 return impl()->ParseWhileStatement(labels, ok); | |
4141 case Token::FOR: | |
4142 return impl()->ParseForStatement(labels, ok); | |
4143 case Token::CONTINUE: | |
4144 case Token::BREAK: | |
4145 case Token::RETURN: | |
4146 case Token::THROW: | |
4147 case Token::TRY: { | |
4148 // These statements must have their labels preserved in an enclosing | |
4149 // block, as the corresponding AST nodes do not currently store their | |
4150 // labels. | |
4151 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. | |
4152 if (labels == nullptr) { | |
4153 return ParseStatementAsUnlabelled(labels, ok); | |
4154 } else { | |
4155 BlockT result = | |
4156 factory()->NewBlock(labels, 1, false, kNoSourcePosition); | |
4157 typename Types::Target target(this, result); | |
4158 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK); | |
4159 result->statements()->Add(statement, zone()); | |
4160 return result; | |
4161 } | |
4162 } | |
4163 case Token::WITH: | |
4164 return impl()->ParseWithStatement(labels, ok); | |
4165 case Token::SWITCH: | |
4166 return impl()->ParseSwitchStatement(labels, ok); | |
4167 case Token::FUNCTION: | |
4168 // FunctionDeclaration only allowed as a StatementListItem, not in | |
4169 // an arbitrary Statement position. Exceptions such as | |
4170 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses | |
4171 // are handled by calling ParseScopedStatement rather than | |
4172 // ParseStatement directly. | |
4173 impl()->ReportMessageAt(scanner()->peek_location(), | |
4174 is_strict(language_mode()) | |
4175 ? MessageTemplate::kStrictFunction | |
4176 : MessageTemplate::kSloppyFunction); | |
4177 *ok = false; | |
4178 return impl()->NullStatement(); | |
4179 case Token::DEBUGGER: | |
4180 return impl()->ParseDebuggerStatement(ok); | |
4181 case Token::VAR: | |
4182 return impl()->ParseVariableStatement(kStatement, nullptr, ok); | |
4183 default: | |
4184 return impl()->ParseExpressionOrLabelledStatement(labels, allow_function, | |
4185 ok); | |
4186 } | |
4187 } | |
4188 | |
4189 // This method parses a subset of statements (break, continue, return, throw, | |
4190 // try) which are to be grouped because they all require their labeles to be | |
4191 // preserved in an enclosing block. | |
4192 template <typename Impl> | |
4193 typename ParserBase<Impl>::StatementT | |
4194 ParserBase<Impl>::ParseStatementAsUnlabelled( | |
4195 ZoneList<const AstRawString*>* labels, bool* ok) { | |
4196 switch (peek()) { | |
4197 case Token::CONTINUE: | |
4198 return impl()->ParseContinueStatement(ok); | |
4199 case Token::BREAK: | |
4200 return impl()->ParseBreakStatement(labels, ok); | |
4201 case Token::RETURN: | |
4202 return impl()->ParseReturnStatement(ok); | |
4203 case Token::THROW: | |
4204 return impl()->ParseThrowStatement(ok); | |
4205 case Token::TRY: | |
4206 return impl()->ParseTryStatement(ok); | |
4207 default: | |
4208 UNREACHABLE(); | |
4209 return impl()->NullStatement(); | |
4210 } | |
4211 } | |
4212 | |
3916 #undef CHECK_OK | 4213 #undef CHECK_OK |
3917 #undef CHECK_OK_CUSTOM | 4214 #undef CHECK_OK_CUSTOM |
3918 | 4215 |
3919 template <typename Impl> | 4216 template <typename Impl> |
3920 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( | 4217 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( |
3921 Token::Value property, PropertyKind type, MethodKind method_type, | 4218 Token::Value property, PropertyKind type, MethodKind method_type, |
3922 bool* ok) { | 4219 bool* ok) { |
3923 DCHECK(!IsStaticMethod(method_type)); | 4220 DCHECK(!IsStaticMethod(method_type)); |
3924 DCHECK(!IsSpecialMethod(method_type) || | 4221 DCHECK(!IsSpecialMethod(method_type) || |
3925 type == PropertyKind::kMethodProperty); | 4222 type == PropertyKind::kMethodProperty); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3971 has_seen_constructor_ = true; | 4268 has_seen_constructor_ = true; |
3972 return; | 4269 return; |
3973 } | 4270 } |
3974 } | 4271 } |
3975 | 4272 |
3976 | 4273 |
3977 } // namespace internal | 4274 } // namespace internal |
3978 } // namespace v8 | 4275 } // namespace v8 |
3979 | 4276 |
3980 #endif // V8_PARSING_PARSER_BASE_H | 4277 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |