| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index 87addfbb9e8e89ec27a0ec19187c7862e6774e38..15887bae08234a65b024940f0942750840630075 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -85,6 +85,7 @@ class ParserBase : public Traits {
|
| allow_natives_syntax_(false),
|
| allow_generators_(false),
|
| allow_arrow_functions_(false),
|
| + allow_harmony_object_literals_(false),
|
| zone_(zone),
|
| ast_node_id_gen_(ast_node_id_gen) {}
|
|
|
| @@ -100,6 +101,9 @@ class ParserBase : public Traits {
|
| return scanner()->HarmonyNumericLiterals();
|
| }
|
| bool allow_classes() const { return scanner()->HarmonyClasses(); }
|
| + bool allow_harmony_object_literals() const {
|
| + return allow_harmony_object_literals_;
|
| + }
|
|
|
| // Setters that determine whether certain syntactical constructs are
|
| // allowed to be parsed by this instance of the parser.
|
| @@ -114,8 +118,9 @@ class ParserBase : public Traits {
|
| void set_allow_harmony_numeric_literals(bool allow) {
|
| scanner()->SetHarmonyNumericLiterals(allow);
|
| }
|
| - void set_allow_classes(bool allow) {
|
| - scanner()->SetHarmonyClasses(allow);
|
| + void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); }
|
| + void set_allow_harmony_object_literals(bool allow) {
|
| + allow_harmony_object_literals_ = allow;
|
| }
|
|
|
| protected:
|
| @@ -481,6 +486,7 @@ class ParserBase : public Traits {
|
| ExpressionT ParseObjectLiteral(bool* ok);
|
| ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker,
|
| bool* ok);
|
| + IdentifierT ParsePropertyName(bool* is_getter, bool* is_setter, bool* ok);
|
| typename Traits::Type::ExpressionList ParseArguments(bool* ok);
|
| ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
|
| ExpressionT ParseYieldExpression(bool* ok);
|
| @@ -579,6 +585,7 @@ class ParserBase : public Traits {
|
| bool allow_natives_syntax_;
|
| bool allow_generators_;
|
| bool allow_arrow_functions_;
|
| + bool allow_harmony_object_literals_;
|
|
|
| typename Traits::Type::Zone* zone_; // Only used by Parser.
|
| AstNode::IdGen* ast_node_id_gen_;
|
| @@ -1054,8 +1061,8 @@ class PreParserFactory {
|
| FunctionLiteral::ParameterFlag has_duplicate_parameters,
|
| FunctionLiteral::FunctionType function_type,
|
| FunctionLiteral::IsFunctionFlag is_function,
|
| - FunctionLiteral::IsParenthesizedFlag is_parenthesized,
|
| - FunctionLiteral::KindFlag kind, int position) {
|
| + FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
|
| + int position) {
|
| return PreParserExpression::Default();
|
| }
|
|
|
| @@ -1331,14 +1338,10 @@ class PreParserTraits {
|
| // Temporary glue; these functions will move to ParserBase.
|
| PreParserExpression ParseV8Intrinsic(bool* ok);
|
| PreParserExpression ParseFunctionLiteral(
|
| - PreParserIdentifier name,
|
| - Scanner::Location function_name_location,
|
| - bool name_is_strict_reserved,
|
| - bool is_generator,
|
| - int function_token_position,
|
| - FunctionLiteral::FunctionType type,
|
| - FunctionLiteral::ArityRestriction arity_restriction,
|
| - bool* ok);
|
| + PreParserIdentifier name, Scanner::Location function_name_location,
|
| + bool name_is_strict_reserved, FunctionKind kind,
|
| + int function_token_position, FunctionLiteral::FunctionType type,
|
| + FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
|
|
|
| private:
|
| PreParser* pre_parser_;
|
| @@ -1469,14 +1472,10 @@ class PreParser : public ParserBase<PreParserTraits> {
|
| bool is_generator, bool* ok);
|
|
|
| Expression ParseFunctionLiteral(
|
| - Identifier name,
|
| - Scanner::Location function_name_location,
|
| - bool name_is_strict_reserved,
|
| - bool is_generator,
|
| - int function_token_pos,
|
| + Identifier name, Scanner::Location function_name_location,
|
| + bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
|
| FunctionLiteral::FunctionType function_type,
|
| - FunctionLiteral::ArityRestriction arity_restriction,
|
| - bool* ok);
|
| + FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
|
| void ParseLazyFunctionLiteralBody(bool* ok);
|
|
|
| bool CheckInOrOf(bool accept_OF);
|
| @@ -1852,84 +1851,85 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
|
|
|
|
|
| template <class Traits>
|
| -typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
|
| - Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, bool* ok) {
|
| - LiteralT key = this->EmptyLiteral();
|
| +typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName(
|
| + bool* is_getter, bool* is_setter, bool* ok) {
|
| Token::Value next = peek();
|
| - int next_pos = peek_position();
|
| -
|
| switch (next) {
|
| - case Token::STRING: {
|
| + case Token::STRING:
|
| Consume(Token::STRING);
|
| - IdentifierT string = this->GetSymbol(scanner_);
|
| - if (fni_ != NULL) this->PushLiteralName(fni_, string);
|
| - uint32_t index;
|
| - if (this->IsArrayIndex(string, &index)) {
|
| - key = factory()->NewNumberLiteral(index, next_pos);
|
| - break;
|
| - }
|
| - key = factory()->NewStringLiteral(string, next_pos);
|
| - break;
|
| - }
|
| - case Token::NUMBER: {
|
| + return this->GetSymbol(scanner_);
|
| + case Token::NUMBER:
|
| Consume(Token::NUMBER);
|
| - key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_,
|
| - factory());
|
| - break;
|
| - }
|
| - default: {
|
| - bool is_getter = false;
|
| - bool is_setter = false;
|
| - IdentifierT id = ParseIdentifierNameOrGetOrSet(
|
| - &is_getter, &is_setter, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| - if (fni_ != NULL) this->PushLiteralName(fni_, id);
|
| -
|
| - if ((is_getter || is_setter) && peek() != Token::COLON) {
|
| - // Special handling of getter and setter syntax:
|
| - // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
|
| - // We have already read the "get" or "set" keyword.
|
| - IdentifierT name = this->EmptyIdentifier();
|
| - switch (peek()) {
|
| - case Token::STRING:
|
| - Consume(Token::STRING);
|
| - name = this->GetSymbol(scanner_);
|
| - break;
|
| - case Token::NUMBER:
|
| - Consume(Token::NUMBER);
|
| - name = this->GetNumberAsSymbol(scanner_);
|
| - break;
|
| - default:
|
| - name = ParseIdentifierName(
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| - }
|
| - // Validate the property.
|
| - PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
|
| - checker->CheckProperty(next, type,
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| - typename Traits::Type::FunctionLiteral value =
|
| - this->ParseFunctionLiteral(
|
| - name, scanner()->location(),
|
| - false, // reserved words are allowed here
|
| - false, // not a generator
|
| - RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
|
| - is_getter ? FunctionLiteral::GETTER_ARITY
|
| - : FunctionLiteral::SETTER_ARITY,
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| - return factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
|
| - }
|
| - // Failed to parse as get/set property, so it's just a normal property
|
| - // (which might be called "get" or "set" or something else).
|
| - key = factory()->NewStringLiteral(id, next_pos);
|
| - }
|
| + return this->GetNumberAsSymbol(scanner_);
|
| + default:
|
| + return ParseIdentifierNameOrGetOrSet(is_getter, is_setter,
|
| + CHECK_OK_CUSTOM(EmptyIdentifier));
|
| }
|
| +}
|
| +
|
|
|
| - // Validate the property
|
| - checker->CheckProperty(next, kValueProperty,
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| +template <class Traits>
|
| +typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
|
| + Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, bool* ok) {
|
| + // TODO(arv): Add support for concise generator methods.
|
| + ExpressionT value = this->EmptyExpression();
|
| + bool is_getter = false;
|
| + bool is_setter = false;
|
| + Token::Value name_token = peek();
|
| + int next_pos = peek_position();
|
| + IdentifierT name = ParsePropertyName(
|
| + &is_getter, &is_setter, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + if (fni_ != NULL) this->PushLiteralName(fni_, name);
|
| +
|
| + if (peek() == Token::COLON) {
|
| + // PropertyDefinition : PropertyName ':' AssignmentExpression
|
| + checker->CheckProperty(name_token, kValueProperty,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + Consume(Token::COLON);
|
| + value = this->ParseAssignmentExpression(
|
| + true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| +
|
| + } else if (allow_harmony_object_literals_ && peek() == Token::LPAREN) {
|
| + // Concise Method
|
| + checker->CheckProperty(name_token, kValueProperty,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + value = this->ParseFunctionLiteral(
|
| + name, scanner()->location(),
|
| + false, // reserved words are allowed here
|
| + FunctionKind::kConciseMethod, RelocInfo::kNoPosition,
|
| + FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::NORMAL_ARITY,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| +
|
| + } else if (is_getter || is_setter) {
|
| + // Accessor
|
| + bool dont_care = false;
|
| + name_token = peek();
|
| + name = ParsePropertyName(&dont_care, &dont_care,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + // Validate the property.
|
| + checker->CheckProperty(name_token,
|
| + is_getter ? kGetterProperty : kSetterProperty,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
|
| + name, scanner()->location(),
|
| + false, // reserved words are allowed here
|
| + FunctionKind::kNormalFunction, RelocInfo::kNoPosition,
|
| + FunctionLiteral::ANONYMOUS_EXPRESSION,
|
| + is_getter ? FunctionLiteral::GETTER_ARITY
|
| + : FunctionLiteral::SETTER_ARITY,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + return factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
|
| + } else {
|
| + Token::Value next = Next();
|
| + ReportUnexpectedToken(next);
|
| + *ok = false;
|
| + return this->EmptyObjectLiteralProperty();
|
| + }
|
|
|
| - Expect(Token::COLON, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| - ExpressionT value = this->ParseAssignmentExpression(
|
| - true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + uint32_t index;
|
| + LiteralT key = this->IsArrayIndex(name, &index)
|
| + ? factory()->NewNumberLiteral(index, next_pos)
|
| + : factory()->NewStringLiteral(name, next_pos);
|
|
|
| return factory()->NewObjectLiteralProperty(key, value);
|
| }
|
| @@ -2428,14 +2428,12 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) {
|
| function_name_location = scanner()->location();
|
| function_type = FunctionLiteral::NAMED_EXPRESSION;
|
| }
|
| - result = this->ParseFunctionLiteral(name,
|
| - function_name_location,
|
| - is_strict_reserved_name,
|
| - is_generator,
|
| - function_token_position,
|
| - function_type,
|
| - FunctionLiteral::NORMAL_ARITY,
|
| - CHECK_OK);
|
| + result = this->ParseFunctionLiteral(
|
| + name, function_name_location, is_strict_reserved_name,
|
| + is_generator ? FunctionKind::kGeneratorFunction
|
| + : FunctionKind::kNormalFunction,
|
| + function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
|
| + CHECK_OK);
|
| } else if (peek() == Token::SUPER) {
|
| int beg_pos = position();
|
| Consume(Token::SUPER);
|
| @@ -2596,7 +2594,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<
|
| materialized_literal_count, expected_property_count, handler_count,
|
| num_parameters, FunctionLiteral::kNoDuplicateParameters,
|
| FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
|
| - FunctionLiteral::kNotParenthesized, FunctionLiteral::kArrowFunction,
|
| + FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction,
|
| start_pos);
|
|
|
| function_literal->set_function_token_position(start_pos);
|
|
|