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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), | 212 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), |
213 function_literal_id_(0), | 213 function_literal_id_(0), |
214 allow_natives_(false), | 214 allow_natives_(false), |
215 allow_tailcalls_(false), | 215 allow_tailcalls_(false), |
216 allow_harmony_do_expressions_(false), | 216 allow_harmony_do_expressions_(false), |
217 allow_harmony_function_sent_(false), | 217 allow_harmony_function_sent_(false), |
218 allow_harmony_async_await_(false), | 218 allow_harmony_async_await_(false), |
219 allow_harmony_restrictive_generators_(false), | 219 allow_harmony_restrictive_generators_(false), |
220 allow_harmony_trailing_commas_(false), | 220 allow_harmony_trailing_commas_(false), |
221 allow_harmony_class_fields_(false), | 221 allow_harmony_class_fields_(false), |
222 allow_harmony_object_spread_(false) {} | 222 allow_harmony_object_rest_spread_(false) {} |
223 | 223 |
224 #define ALLOW_ACCESSORS(name) \ | 224 #define ALLOW_ACCESSORS(name) \ |
225 bool allow_##name() const { return allow_##name##_; } \ | 225 bool allow_##name() const { return allow_##name##_; } \ |
226 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 226 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
227 | 227 |
228 ALLOW_ACCESSORS(natives); | 228 ALLOW_ACCESSORS(natives); |
229 ALLOW_ACCESSORS(tailcalls); | 229 ALLOW_ACCESSORS(tailcalls); |
230 ALLOW_ACCESSORS(harmony_do_expressions); | 230 ALLOW_ACCESSORS(harmony_do_expressions); |
231 ALLOW_ACCESSORS(harmony_function_sent); | 231 ALLOW_ACCESSORS(harmony_function_sent); |
232 ALLOW_ACCESSORS(harmony_async_await); | 232 ALLOW_ACCESSORS(harmony_async_await); |
233 ALLOW_ACCESSORS(harmony_restrictive_generators); | 233 ALLOW_ACCESSORS(harmony_restrictive_generators); |
234 ALLOW_ACCESSORS(harmony_trailing_commas); | 234 ALLOW_ACCESSORS(harmony_trailing_commas); |
235 ALLOW_ACCESSORS(harmony_class_fields); | 235 ALLOW_ACCESSORS(harmony_class_fields); |
236 ALLOW_ACCESSORS(harmony_object_spread); | 236 ALLOW_ACCESSORS(harmony_object_rest_spread); |
237 | 237 |
238 #undef ALLOW_ACCESSORS | 238 #undef ALLOW_ACCESSORS |
239 | 239 |
240 uintptr_t stack_limit() const { return stack_limit_; } | 240 uintptr_t stack_limit() const { return stack_limit_; } |
241 | 241 |
242 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 242 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
243 | 243 |
244 void set_default_eager_compile_hint( | 244 void set_default_eager_compile_hint( |
245 FunctionLiteral::EagerCompileHint eager_compile_hint) { | 245 FunctionLiteral::EagerCompileHint eager_compile_hint) { |
246 default_eager_compile_hint_ = eager_compile_hint; | 246 default_eager_compile_hint_ = eager_compile_hint; |
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1162 bool* is_async, bool* is_computed_name, | 1162 bool* is_async, bool* is_computed_name, |
1163 bool* ok); | 1163 bool* ok); |
1164 ExpressionT ParseObjectLiteral(bool* ok); | 1164 ExpressionT ParseObjectLiteral(bool* ok); |
1165 ClassLiteralPropertyT ParseClassPropertyDefinition( | 1165 ClassLiteralPropertyT ParseClassPropertyDefinition( |
1166 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, | 1166 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, |
1167 bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, | 1167 bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, |
1168 bool* is_static, bool* has_name_static_property, bool* ok); | 1168 bool* is_static, bool* has_name_static_property, bool* ok); |
1169 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, | 1169 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, |
1170 bool* ok); | 1170 bool* ok); |
1171 ObjectLiteralPropertyT ParseObjectPropertyDefinition( | 1171 ObjectLiteralPropertyT ParseObjectPropertyDefinition( |
1172 ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok); | 1172 ObjectLiteralChecker* checker, bool* is_computed_name, |
1173 bool* is_rest_property, bool* ok); | |
1173 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1174 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
1174 bool maybe_arrow, bool* ok); | 1175 bool maybe_arrow, bool* ok); |
1175 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1176 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
1176 bool* ok) { | 1177 bool* ok) { |
1177 return ParseArguments(first_spread_pos, false, ok); | 1178 return ParseArguments(first_spread_pos, false, ok); |
1178 } | 1179 } |
1179 | 1180 |
1180 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 1181 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
1181 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); | 1182 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); |
1182 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 1183 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1452 int function_literal_id_; | 1453 int function_literal_id_; |
1453 | 1454 |
1454 bool allow_natives_; | 1455 bool allow_natives_; |
1455 bool allow_tailcalls_; | 1456 bool allow_tailcalls_; |
1456 bool allow_harmony_do_expressions_; | 1457 bool allow_harmony_do_expressions_; |
1457 bool allow_harmony_function_sent_; | 1458 bool allow_harmony_function_sent_; |
1458 bool allow_harmony_async_await_; | 1459 bool allow_harmony_async_await_; |
1459 bool allow_harmony_restrictive_generators_; | 1460 bool allow_harmony_restrictive_generators_; |
1460 bool allow_harmony_trailing_commas_; | 1461 bool allow_harmony_trailing_commas_; |
1461 bool allow_harmony_class_fields_; | 1462 bool allow_harmony_class_fields_; |
1462 bool allow_harmony_object_spread_; | 1463 bool allow_harmony_object_rest_spread_; |
1463 | 1464 |
1464 friend class DiscardableZoneScope; | 1465 friend class DiscardableZoneScope; |
1465 }; | 1466 }; |
1466 | 1467 |
1467 template <typename Impl> | 1468 template <typename Impl> |
1468 ParserBase<Impl>::FunctionState::FunctionState( | 1469 ParserBase<Impl>::FunctionState::FunctionState( |
1469 FunctionState** function_state_stack, ScopeState** scope_stack, | 1470 FunctionState** function_state_stack, ScopeState** scope_stack, |
1470 DeclarationScope* scope) | 1471 DeclarationScope* scope) |
1471 : ScopeState(scope_stack, scope), | 1472 : ScopeState(scope_stack, scope), |
1472 next_materialized_literal_index_(0), | 1473 next_materialized_literal_index_(0), |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2107 Consume(Token::LBRACK); | 2108 Consume(Token::LBRACK); |
2108 ExpressionClassifier computed_name_classifier(this); | 2109 ExpressionClassifier computed_name_classifier(this); |
2109 expression = ParseAssignmentExpression(true, CHECK_OK); | 2110 expression = ParseAssignmentExpression(true, CHECK_OK); |
2110 impl()->RewriteNonPattern(CHECK_OK); | 2111 impl()->RewriteNonPattern(CHECK_OK); |
2111 impl()->AccumulateFormalParameterContainmentErrors(); | 2112 impl()->AccumulateFormalParameterContainmentErrors(); |
2112 Expect(Token::RBRACK, CHECK_OK); | 2113 Expect(Token::RBRACK, CHECK_OK); |
2113 break; | 2114 break; |
2114 } | 2115 } |
2115 | 2116 |
2116 case Token::ELLIPSIS: | 2117 case Token::ELLIPSIS: |
2117 if (allow_harmony_object_spread()) { | 2118 if (allow_harmony_object_rest_spread()) { |
2118 // TODO(gsathya): Implement destructuring/rest | |
2119 classifier()->RecordPatternError(scanner()->location(), | |
2120 MessageTemplate::kUnexpectedToken); | |
2121 | |
2122 *name = impl()->EmptyIdentifier(); | 2119 *name = impl()->EmptyIdentifier(); |
2123 Consume(Token::ELLIPSIS); | 2120 Consume(Token::ELLIPSIS); |
2124 ExpressionClassifier spread_classifier(this); | 2121 ExpressionClassifier spread_classifier(this); |
2125 expression = ParseAssignmentExpression(true, CHECK_OK); | 2122 expression = ParseAssignmentExpression(true, CHECK_OK); |
2126 impl()->RewriteNonPattern(CHECK_OK); | 2123 impl()->RewriteNonPattern(CHECK_OK); |
2127 impl()->AccumulateFormalParameterContainmentErrors(); | 2124 impl()->AccumulateFormalParameterContainmentErrors(); |
2128 *kind = PropertyKind::kSpreadProperty; | 2125 *kind = PropertyKind::kSpreadProperty; |
2126 | |
2127 if (expression->IsAssignment()) { | |
2128 classifier()->RecordPatternError( | |
2129 scanner()->location(), | |
2130 MessageTemplate::kInvalidDestructuringTarget); | |
2131 } else { | |
2132 CheckDestructuringElement(expression, pos, | |
2133 scanner()->location().end_pos); | |
2134 } | |
2135 | |
2136 if (peek() != Token::RBRACE) { | |
adamk
2017/01/10 23:22:56
I don't think this is correct, since there could b
gsathya
2017/01/12 21:27:41
No trailing comma allowed after destructuring prop
| |
2137 classifier()->RecordPatternError(scanner()->location(), | |
2138 MessageTemplate::kElementAfterRest); | |
2139 } | |
2129 return expression; | 2140 return expression; |
2130 } | 2141 } |
2131 | 2142 |
2132 default: | 2143 default: |
2133 *name = ParseIdentifierName(CHECK_OK); | 2144 *name = ParseIdentifierName(CHECK_OK); |
2134 break; | 2145 break; |
2135 } | 2146 } |
2136 | 2147 |
2137 if (*kind == PropertyKind::kNotSet) { | 2148 if (*kind == PropertyKind::kNotSet) { |
2138 SetPropertyKindFromToken(peek(), kind); | 2149 SetPropertyKindFromToken(peek(), kind); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2328 FunctionLiteral::kNoDuplicateParameters, | 2339 FunctionLiteral::kNoDuplicateParameters, |
2329 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, | 2340 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, |
2330 initializer_scope->start_position(), true, GetNextFunctionLiteralId()); | 2341 initializer_scope->start_position(), true, GetNextFunctionLiteralId()); |
2331 return function_literal; | 2342 return function_literal; |
2332 } | 2343 } |
2333 | 2344 |
2334 template <typename Impl> | 2345 template <typename Impl> |
2335 typename ParserBase<Impl>::ObjectLiteralPropertyT | 2346 typename ParserBase<Impl>::ObjectLiteralPropertyT |
2336 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, | 2347 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, |
2337 bool* is_computed_name, | 2348 bool* is_computed_name, |
2349 bool* is_rest_property, | |
2338 bool* ok) { | 2350 bool* ok) { |
2339 bool is_get = false; | 2351 bool is_get = false; |
2340 bool is_set = false; | 2352 bool is_set = false; |
2341 bool is_generator = false; | 2353 bool is_generator = false; |
2342 bool is_async = false; | 2354 bool is_async = false; |
2343 PropertyKind kind = PropertyKind::kNotSet; | 2355 PropertyKind kind = PropertyKind::kNotSet; |
2344 | 2356 |
2345 IdentifierT name = impl()->EmptyIdentifier(); | 2357 IdentifierT name = impl()->EmptyIdentifier(); |
2346 Token::Value name_token = peek(); | 2358 Token::Value name_token = peek(); |
2347 int next_beg_pos = scanner()->peek_location().beg_pos; | 2359 int next_beg_pos = scanner()->peek_location().beg_pos; |
2348 int next_end_pos = scanner()->peek_location().end_pos; | 2360 int next_end_pos = scanner()->peek_location().end_pos; |
2349 | 2361 |
2350 ExpressionT name_expression = ParsePropertyName( | 2362 ExpressionT name_expression = ParsePropertyName( |
2351 &name, &kind, &is_generator, &is_get, &is_set, &is_async, | 2363 &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
2352 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2364 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2353 | 2365 |
2354 switch (kind) { | 2366 switch (kind) { |
2355 case PropertyKind::kSpreadProperty: | 2367 case PropertyKind::kSpreadProperty: |
2356 DCHECK(allow_harmony_object_spread()); | 2368 DCHECK(allow_harmony_object_rest_spread()); |
2357 DCHECK(!is_get && !is_set && !is_generator && !is_async && | 2369 DCHECK(!is_get && !is_set && !is_generator && !is_async && |
2358 !*is_computed_name); | 2370 !*is_computed_name); |
2359 DCHECK(name_token == Token::ELLIPSIS); | 2371 DCHECK(name_token == Token::ELLIPSIS); |
2360 | 2372 |
2361 *is_computed_name = true; | 2373 *is_computed_name = true; |
2374 *is_rest_property = true; | |
2362 | 2375 |
2363 return factory()->NewObjectLiteralProperty( | 2376 return factory()->NewObjectLiteralProperty( |
2364 impl()->GetLiteralTheHole(kNoSourcePosition), name_expression, | 2377 impl()->GetLiteralTheHole(kNoSourcePosition), name_expression, |
2365 ObjectLiteralProperty::SPREAD, true); | 2378 ObjectLiteralProperty::SPREAD, true); |
2366 | 2379 |
2367 case PropertyKind::kValueProperty: { | 2380 case PropertyKind::kValueProperty: { |
2368 DCHECK(!is_get && !is_set && !is_generator && !is_async); | 2381 DCHECK(!is_get && !is_set && !is_generator && !is_async); |
2369 | 2382 |
2370 if (!*is_computed_name) { | 2383 if (!*is_computed_name) { |
2371 checker->CheckDuplicateProto(name_token); | 2384 checker->CheckDuplicateProto(name_token); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2526 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 2539 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
2527 bool* ok) { | 2540 bool* ok) { |
2528 // ObjectLiteral :: | 2541 // ObjectLiteral :: |
2529 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2542 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2530 | 2543 |
2531 int pos = peek_position(); | 2544 int pos = peek_position(); |
2532 typename Types::ObjectPropertyList properties = | 2545 typename Types::ObjectPropertyList properties = |
2533 impl()->NewObjectPropertyList(4); | 2546 impl()->NewObjectPropertyList(4); |
2534 int number_of_boilerplate_properties = 0; | 2547 int number_of_boilerplate_properties = 0; |
2535 bool has_computed_names = false; | 2548 bool has_computed_names = false; |
2549 bool has_rest_property = false; | |
2536 ObjectLiteralChecker checker(this); | 2550 ObjectLiteralChecker checker(this); |
2537 | 2551 |
2538 Expect(Token::LBRACE, CHECK_OK); | 2552 Expect(Token::LBRACE, CHECK_OK); |
2539 | 2553 |
2540 while (peek() != Token::RBRACE) { | 2554 while (peek() != Token::RBRACE) { |
2541 FuncNameInferrer::State fni_state(fni_); | 2555 FuncNameInferrer::State fni_state(fni_); |
2542 | 2556 |
2543 bool is_computed_name = false; | 2557 bool is_computed_name = false; |
2544 ObjectLiteralPropertyT property = | 2558 bool is_rest_property = false; |
2545 ParseObjectPropertyDefinition(&checker, &is_computed_name, CHECK_OK); | 2559 ObjectLiteralPropertyT property = ParseObjectPropertyDefinition( |
2560 &checker, &is_computed_name, &is_rest_property, CHECK_OK); | |
2546 | 2561 |
2547 if (is_computed_name) { | 2562 if (is_computed_name) { |
2548 has_computed_names = true; | 2563 has_computed_names = true; |
2549 } | 2564 } |
2550 | 2565 |
2566 if (is_rest_property) { | |
2567 has_rest_property = true; | |
2568 } | |
2569 | |
2551 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2570 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
2552 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { | 2571 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { |
2553 number_of_boilerplate_properties++; | 2572 number_of_boilerplate_properties++; |
2554 } | 2573 } |
2555 properties->Add(property, zone()); | 2574 properties->Add(property, zone()); |
2556 | 2575 |
2557 if (peek() != Token::RBRACE) { | 2576 if (peek() != Token::RBRACE) { |
2558 // Need {} because of the CHECK_OK macro. | 2577 // Need {} because of the CHECK_OK macro. |
2559 Expect(Token::COMMA, CHECK_OK); | 2578 Expect(Token::COMMA, CHECK_OK); |
2560 } | 2579 } |
2561 | 2580 |
2562 if (fni_ != nullptr) fni_->Infer(); | 2581 if (fni_ != nullptr) fni_->Infer(); |
2563 } | 2582 } |
2564 Expect(Token::RBRACE, CHECK_OK); | 2583 Expect(Token::RBRACE, CHECK_OK); |
2565 | 2584 |
2566 // Computation of literal_index must happen before pre parse bailout. | 2585 // Computation of literal_index must happen before pre parse bailout. |
2567 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2586 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2568 | 2587 |
2569 return factory()->NewObjectLiteral(properties, | 2588 return factory()->NewObjectLiteral(properties, literal_index, |
2570 literal_index, | 2589 number_of_boilerplate_properties, pos, |
2571 number_of_boilerplate_properties, | 2590 has_rest_property); |
2572 pos); | |
2573 } | 2591 } |
2574 | 2592 |
2575 template <typename Impl> | 2593 template <typename Impl> |
2576 typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( | 2594 typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( |
2577 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { | 2595 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { |
2578 // Arguments :: | 2596 // Arguments :: |
2579 // '(' (AssignmentExpression)*[','] ')' | 2597 // '(' (AssignmentExpression)*[','] ')' |
2580 | 2598 |
2581 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2599 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2582 ExpressionListT result = impl()->NewExpressionList(4); | 2600 ExpressionListT result = impl()->NewExpressionList(4); |
(...skipping 2950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5533 has_seen_constructor_ = true; | 5551 has_seen_constructor_ = true; |
5534 return; | 5552 return; |
5535 } | 5553 } |
5536 } | 5554 } |
5537 | 5555 |
5538 | 5556 |
5539 } // namespace internal | 5557 } // namespace internal |
5540 } // namespace v8 | 5558 } // namespace v8 |
5541 | 5559 |
5542 #endif // V8_PARSING_PARSER_BASE_H | 5560 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |