 Chromium Code Reviews
 Chromium Code Reviews Issue 2620943002:
  [ESnext] Implement Object Rest  (Closed)
    
  
    Issue 2620943002:
  [ESnext] Implement Object Rest  (Closed) 
  | Index: src/parsing/parser-base.h | 
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h | 
| index 7a3aeb097becc2366607140be7db4a3257aae93d..a550887619dd759996a0c7aa7e447c3e77bff4ce 100644 | 
| --- a/src/parsing/parser-base.h | 
| +++ b/src/parsing/parser-base.h | 
| @@ -219,7 +219,7 @@ class ParserBase { | 
| allow_harmony_restrictive_generators_(false), | 
| allow_harmony_trailing_commas_(false), | 
| allow_harmony_class_fields_(false), | 
| - allow_harmony_object_spread_(false) {} | 
| + allow_harmony_object_rest_spread_(false) {} | 
| #define ALLOW_ACCESSORS(name) \ | 
| bool allow_##name() const { return allow_##name##_; } \ | 
| @@ -233,7 +233,7 @@ class ParserBase { | 
| ALLOW_ACCESSORS(harmony_restrictive_generators); | 
| ALLOW_ACCESSORS(harmony_trailing_commas); | 
| ALLOW_ACCESSORS(harmony_class_fields); | 
| - ALLOW_ACCESSORS(harmony_object_spread); | 
| + ALLOW_ACCESSORS(harmony_object_rest_spread); | 
| #undef ALLOW_ACCESSORS | 
| @@ -1169,7 +1169,8 @@ class ParserBase { | 
| FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, | 
| bool* ok); | 
| ObjectLiteralPropertyT ParseObjectPropertyDefinition( | 
| - ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok); | 
| + ObjectLiteralChecker* checker, bool* is_computed_name, | 
| + bool* is_rest_property, bool* ok); | 
| ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 
| bool maybe_arrow, bool* ok); | 
| ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 
| @@ -1459,7 +1460,7 @@ class ParserBase { | 
| bool allow_harmony_restrictive_generators_; | 
| bool allow_harmony_trailing_commas_; | 
| bool allow_harmony_class_fields_; | 
| - bool allow_harmony_object_spread_; | 
| + bool allow_harmony_object_rest_spread_; | 
| friend class DiscardableZoneScope; | 
| }; | 
| @@ -2114,11 +2115,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( | 
| } | 
| case Token::ELLIPSIS: | 
| - if (allow_harmony_object_spread()) { | 
| - // TODO(gsathya): Implement destructuring/rest | 
| - classifier()->RecordPatternError(scanner()->location(), | 
| - MessageTemplate::kUnexpectedToken); | 
| - | 
| + if (allow_harmony_object_rest_spread()) { | 
| *name = impl()->EmptyIdentifier(); | 
| Consume(Token::ELLIPSIS); | 
| ExpressionClassifier spread_classifier(this); | 
| @@ -2126,6 +2123,20 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( | 
| impl()->RewriteNonPattern(CHECK_OK); | 
| impl()->AccumulateFormalParameterContainmentErrors(); | 
| *kind = PropertyKind::kSpreadProperty; | 
| + | 
| + if (expression->IsAssignment()) { | 
| + classifier()->RecordPatternError( | 
| + scanner()->location(), | 
| + MessageTemplate::kInvalidDestructuringTarget); | 
| + } else { | 
| + CheckDestructuringElement(expression, pos, | 
| + scanner()->location().end_pos); | 
| + } | 
| + | 
| + 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
 | 
| + classifier()->RecordPatternError(scanner()->location(), | 
| + MessageTemplate::kElementAfterRest); | 
| + } | 
| return expression; | 
| } | 
| @@ -2335,6 +2346,7 @@ template <typename Impl> | 
| typename ParserBase<Impl>::ObjectLiteralPropertyT | 
| ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, | 
| bool* is_computed_name, | 
| + bool* is_rest_property, | 
| bool* ok) { | 
| bool is_get = false; | 
| bool is_set = false; | 
| @@ -2353,12 +2365,13 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, | 
| switch (kind) { | 
| case PropertyKind::kSpreadProperty: | 
| - DCHECK(allow_harmony_object_spread()); | 
| + DCHECK(allow_harmony_object_rest_spread()); | 
| DCHECK(!is_get && !is_set && !is_generator && !is_async && | 
| !*is_computed_name); | 
| DCHECK(name_token == Token::ELLIPSIS); | 
| *is_computed_name = true; | 
| + *is_rest_property = true; | 
| return factory()->NewObjectLiteralProperty( | 
| impl()->GetLiteralTheHole(kNoSourcePosition), name_expression, | 
| @@ -2533,6 +2546,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 
| impl()->NewObjectPropertyList(4); | 
| int number_of_boilerplate_properties = 0; | 
| bool has_computed_names = false; | 
| + bool has_rest_property = false; | 
| ObjectLiteralChecker checker(this); | 
| Expect(Token::LBRACE, CHECK_OK); | 
| @@ -2541,13 +2555,18 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 
| FuncNameInferrer::State fni_state(fni_); | 
| bool is_computed_name = false; | 
| - ObjectLiteralPropertyT property = | 
| - ParseObjectPropertyDefinition(&checker, &is_computed_name, CHECK_OK); | 
| + bool is_rest_property = false; | 
| + ObjectLiteralPropertyT property = ParseObjectPropertyDefinition( | 
| + &checker, &is_computed_name, &is_rest_property, CHECK_OK); | 
| if (is_computed_name) { | 
| has_computed_names = true; | 
| } | 
| + if (is_rest_property) { | 
| + has_rest_property = true; | 
| + } | 
| + | 
| // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 
| if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { | 
| number_of_boilerplate_properties++; | 
| @@ -2566,10 +2585,9 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 
| // Computation of literal_index must happen before pre parse bailout. | 
| int literal_index = function_state_->NextMaterializedLiteralIndex(); | 
| - return factory()->NewObjectLiteral(properties, | 
| - literal_index, | 
| - number_of_boilerplate_properties, | 
| - pos); | 
| + return factory()->NewObjectLiteral(properties, literal_index, | 
| + number_of_boilerplate_properties, pos, | 
| + has_rest_property); | 
| } | 
| template <typename Impl> |