Chromium Code Reviews| 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 |