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/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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 stack_overflow_(false), | 210 stack_overflow_(false), |
211 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), | 211 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), |
212 function_literal_id_(0), | 212 function_literal_id_(0), |
213 allow_natives_(false), | 213 allow_natives_(false), |
214 allow_tailcalls_(false), | 214 allow_tailcalls_(false), |
215 allow_harmony_do_expressions_(false), | 215 allow_harmony_do_expressions_(false), |
216 allow_harmony_function_sent_(false), | 216 allow_harmony_function_sent_(false), |
217 allow_harmony_async_await_(false), | 217 allow_harmony_async_await_(false), |
218 allow_harmony_restrictive_generators_(false), | 218 allow_harmony_restrictive_generators_(false), |
219 allow_harmony_trailing_commas_(false), | 219 allow_harmony_trailing_commas_(false), |
220 allow_harmony_class_fields_(false) {} | 220 allow_harmony_class_fields_(false), |
221 allow_harmony_object_spread_(false) {} | |
221 | 222 |
222 #define ALLOW_ACCESSORS(name) \ | 223 #define ALLOW_ACCESSORS(name) \ |
223 bool allow_##name() const { return allow_##name##_; } \ | 224 bool allow_##name() const { return allow_##name##_; } \ |
224 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 225 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
225 | 226 |
226 ALLOW_ACCESSORS(natives); | 227 ALLOW_ACCESSORS(natives); |
227 ALLOW_ACCESSORS(tailcalls); | 228 ALLOW_ACCESSORS(tailcalls); |
228 ALLOW_ACCESSORS(harmony_do_expressions); | 229 ALLOW_ACCESSORS(harmony_do_expressions); |
229 ALLOW_ACCESSORS(harmony_function_sent); | 230 ALLOW_ACCESSORS(harmony_function_sent); |
230 ALLOW_ACCESSORS(harmony_async_await); | 231 ALLOW_ACCESSORS(harmony_async_await); |
231 ALLOW_ACCESSORS(harmony_restrictive_generators); | 232 ALLOW_ACCESSORS(harmony_restrictive_generators); |
232 ALLOW_ACCESSORS(harmony_trailing_commas); | 233 ALLOW_ACCESSORS(harmony_trailing_commas); |
233 ALLOW_ACCESSORS(harmony_class_fields); | 234 ALLOW_ACCESSORS(harmony_class_fields); |
235 ALLOW_ACCESSORS(harmony_object_spread); | |
234 | 236 |
235 #undef ALLOW_ACCESSORS | 237 #undef ALLOW_ACCESSORS |
236 | 238 |
237 uintptr_t stack_limit() const { return stack_limit_; } | 239 uintptr_t stack_limit() const { return stack_limit_; } |
238 | 240 |
239 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 241 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
240 | 242 |
241 void set_default_eager_compile_hint( | 243 void set_default_eager_compile_hint( |
242 FunctionLiteral::EagerCompileHint eager_compile_hint) { | 244 FunctionLiteral::EagerCompileHint eager_compile_hint) { |
243 default_eager_compile_hint_ = eager_compile_hint; | 245 default_eager_compile_hint_ = eager_compile_hint; |
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1142 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok); | 1144 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok); |
1143 | 1145 |
1144 ExpressionT ParseArrayLiteral(bool* ok); | 1146 ExpressionT ParseArrayLiteral(bool* ok); |
1145 | 1147 |
1146 enum class PropertyKind { | 1148 enum class PropertyKind { |
1147 kAccessorProperty, | 1149 kAccessorProperty, |
1148 kValueProperty, | 1150 kValueProperty, |
1149 kShorthandProperty, | 1151 kShorthandProperty, |
1150 kMethodProperty, | 1152 kMethodProperty, |
1151 kClassField, | 1153 kClassField, |
1154 kSpreadProperty, | |
1152 kNotSet | 1155 kNotSet |
1153 }; | 1156 }; |
1154 | 1157 |
1155 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); | 1158 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); |
1156 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, | 1159 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, |
1157 bool* is_generator, bool* is_get, bool* is_set, | 1160 bool* is_generator, bool* is_get, bool* is_set, |
1158 bool* is_async, bool* is_computed_name, | 1161 bool* is_async, bool* is_computed_name, |
1159 bool* ok); | 1162 bool* ok); |
1160 ExpressionT ParseObjectLiteral(bool* ok); | 1163 ExpressionT ParseObjectLiteral(bool* ok); |
1161 ClassLiteralPropertyT ParseClassPropertyDefinition( | 1164 ClassLiteralPropertyT ParseClassPropertyDefinition( |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1448 int function_literal_id_; | 1451 int function_literal_id_; |
1449 | 1452 |
1450 bool allow_natives_; | 1453 bool allow_natives_; |
1451 bool allow_tailcalls_; | 1454 bool allow_tailcalls_; |
1452 bool allow_harmony_do_expressions_; | 1455 bool allow_harmony_do_expressions_; |
1453 bool allow_harmony_function_sent_; | 1456 bool allow_harmony_function_sent_; |
1454 bool allow_harmony_async_await_; | 1457 bool allow_harmony_async_await_; |
1455 bool allow_harmony_restrictive_generators_; | 1458 bool allow_harmony_restrictive_generators_; |
1456 bool allow_harmony_trailing_commas_; | 1459 bool allow_harmony_trailing_commas_; |
1457 bool allow_harmony_class_fields_; | 1460 bool allow_harmony_class_fields_; |
1461 bool allow_harmony_object_spread_; | |
1458 | 1462 |
1459 friend class DiscardableZoneScope; | 1463 friend class DiscardableZoneScope; |
1460 }; | 1464 }; |
1461 | 1465 |
1462 template <typename Impl> | 1466 template <typename Impl> |
1463 ParserBase<Impl>::FunctionState::FunctionState( | 1467 ParserBase<Impl>::FunctionState::FunctionState( |
1464 FunctionState** function_state_stack, ScopeState** scope_stack, | 1468 FunctionState** function_state_stack, ScopeState** scope_stack, |
1465 DeclarationScope* scope) | 1469 DeclarationScope* scope) |
1466 : ScopeState(scope_stack, scope), | 1470 : ScopeState(scope_stack, scope), |
1467 next_materialized_literal_index_(0), | 1471 next_materialized_literal_index_(0), |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2101 *is_computed_name = true; | 2105 *is_computed_name = true; |
2102 Consume(Token::LBRACK); | 2106 Consume(Token::LBRACK); |
2103 ExpressionClassifier computed_name_classifier(this); | 2107 ExpressionClassifier computed_name_classifier(this); |
2104 expression = ParseAssignmentExpression(true, CHECK_OK); | 2108 expression = ParseAssignmentExpression(true, CHECK_OK); |
2105 impl()->RewriteNonPattern(CHECK_OK); | 2109 impl()->RewriteNonPattern(CHECK_OK); |
2106 impl()->AccumulateFormalParameterContainmentErrors(); | 2110 impl()->AccumulateFormalParameterContainmentErrors(); |
2107 Expect(Token::RBRACK, CHECK_OK); | 2111 Expect(Token::RBRACK, CHECK_OK); |
2108 break; | 2112 break; |
2109 } | 2113 } |
2110 | 2114 |
2115 case Token::ELLIPSIS: { | |
2116 if (allow_harmony_object_spread()) { | |
2117 // TODO(gsathya): Implement destructuring/rest | |
2118 BindingPatternUnexpectedToken(); | |
adamk
2016/12/29 00:48:45
I think you'll need to disallow this in assignment
gsathya
2016/12/29 06:40:56
Done.
adamk
2016/12/29 18:32:45
You can get both at once with
classifier()->Recor
gsathya
2017/01/05 22:18:35
Done.
| |
2119 | |
2120 *name = impl()->EmptyIdentifier(); | |
2121 Consume(Token::ELLIPSIS); | |
2122 ExpressionClassifier spread_classifier(this); | |
2123 expression = ParseAssignmentExpression(false, CHECK_OK); | |
adamk
2016/12/29 00:48:45
Don't you want to accept "in"? Please add a test,
gsathya
2016/12/29 06:40:56
Done.
| |
2124 impl()->RewriteNonPattern(CHECK_OK); | |
2125 impl()->AccumulateFormalParameterContainmentErrors(); | |
2126 *kind = PropertyKind::kSpreadProperty; | |
2127 return expression; | |
2128 } | |
2129 } | |
2130 | |
2111 default: | 2131 default: |
2112 *name = ParseIdentifierName(CHECK_OK); | 2132 *name = ParseIdentifierName(CHECK_OK); |
2113 break; | 2133 break; |
2114 } | 2134 } |
2115 | 2135 |
2116 if (*kind == PropertyKind::kNotSet) { | 2136 if (*kind == PropertyKind::kNotSet) { |
2117 SetPropertyKindFromToken(peek(), kind); | 2137 SetPropertyKindFromToken(peek(), kind); |
2118 } | 2138 } |
2119 | 2139 |
2120 if (*is_computed_name) { | 2140 if (*is_computed_name) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2261 if (!*is_computed_name) { | 2281 if (!*is_computed_name) { |
2262 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2282 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2263 } | 2283 } |
2264 | 2284 |
2265 *property_kind = | 2285 *property_kind = |
2266 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; | 2286 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; |
2267 return factory()->NewClassLiteralProperty(name_expression, value, | 2287 return factory()->NewClassLiteralProperty(name_expression, value, |
2268 *property_kind, *is_static, | 2288 *property_kind, *is_static, |
2269 *is_computed_name); | 2289 *is_computed_name); |
2270 } | 2290 } |
2291 case PropertyKind::kSpreadProperty: | |
2292 UNREACHABLE(); | |
2271 } | 2293 } |
2272 UNREACHABLE(); | 2294 UNREACHABLE(); |
2273 return impl()->EmptyClassLiteralProperty(); | 2295 return impl()->EmptyClassLiteralProperty(); |
2274 } | 2296 } |
2275 | 2297 |
2276 template <typename Impl> | 2298 template <typename Impl> |
2277 typename ParserBase<Impl>::FunctionLiteralT | 2299 typename ParserBase<Impl>::FunctionLiteralT |
2278 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, | 2300 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, |
2279 bool* ok) { | 2301 bool* ok) { |
2280 // Makes a concise method which evaluates and returns the initialized value | 2302 // Makes a concise method which evaluates and returns the initialized value |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2322 IdentifierT name = impl()->EmptyIdentifier(); | 2344 IdentifierT name = impl()->EmptyIdentifier(); |
2323 Token::Value name_token = peek(); | 2345 Token::Value name_token = peek(); |
2324 int next_beg_pos = scanner()->peek_location().beg_pos; | 2346 int next_beg_pos = scanner()->peek_location().beg_pos; |
2325 int next_end_pos = scanner()->peek_location().end_pos; | 2347 int next_end_pos = scanner()->peek_location().end_pos; |
2326 | 2348 |
2327 ExpressionT name_expression = ParsePropertyName( | 2349 ExpressionT name_expression = ParsePropertyName( |
2328 &name, &kind, &is_generator, &is_get, &is_set, &is_async, | 2350 &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
2329 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2351 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2330 | 2352 |
2331 switch (kind) { | 2353 switch (kind) { |
2354 case PropertyKind::kSpreadProperty: { | |
2355 if (allow_harmony_object_spread()) { | |
adamk
2016/12/29 00:48:45
This can be a DCHECK, since ParsePropertyName shou
gsathya
2016/12/29 06:40:56
Done.
| |
2356 DCHECK(!is_get && !is_set && !is_generator && !is_async); | |
adamk
2016/12/29 00:48:45
you should add !*is_computed_name to this list.
gsathya
2016/12/29 06:40:56
Done.
| |
2357 DCHECK(name_token == Token::ELLIPSIS); | |
2358 | |
2359 *is_computed_name = true; | |
2360 *ok = true; | |
adamk
2016/12/29 00:48:45
No need to set *ok to true, that's how it starts.
gsathya
2016/12/29 06:40:56
Done.
| |
2361 | |
2362 return factory()->NewObjectLiteralProperty( | |
2363 impl()->GetLiteralTheHole(kNoSourcePosition), name_expression, | |
2364 ObjectLiteralProperty::SPREAD, true); | |
2365 } | |
2366 } | |
2367 | |
2332 case PropertyKind::kValueProperty: { | 2368 case PropertyKind::kValueProperty: { |
2333 DCHECK(!is_get && !is_set && !is_generator && !is_async); | 2369 DCHECK(!is_get && !is_set && !is_generator && !is_async); |
2334 | 2370 |
2335 if (!*is_computed_name) { | 2371 if (!*is_computed_name) { |
2336 checker->CheckDuplicateProto(name_token); | 2372 checker->CheckDuplicateProto(name_token); |
2337 } | 2373 } |
2338 Consume(Token::COLON); | 2374 Consume(Token::COLON); |
2339 int beg_pos = peek_position(); | 2375 int beg_pos = peek_position(); |
2340 ExpressionT value = ParseAssignmentExpression( | 2376 ExpressionT value = ParseAssignmentExpression( |
2341 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2377 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
(...skipping 3156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5498 has_seen_constructor_ = true; | 5534 has_seen_constructor_ = true; |
5499 return; | 5535 return; |
5500 } | 5536 } |
5501 } | 5537 } |
5502 | 5538 |
5503 | 5539 |
5504 } // namespace internal | 5540 } // namespace internal |
5505 } // namespace v8 | 5541 } // namespace v8 |
5506 | 5542 |
5507 #endif // V8_PARSING_PARSER_BASE_H | 5543 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |