| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index bf1a348211e138273d2fff6ee7463d2880341ad6..e935b7b4a728b192240e15aeb031b790fdf77e4b 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -210,6 +210,7 @@ class Parser {
|
| Expression* ParsePrimaryExpression(bool* ok);
|
| Expression* ParseArrayLiteral(bool* ok);
|
| Expression* ParseObjectLiteral(bool* ok);
|
| + ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
|
| Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
|
|
|
| // Populate the constant properties fixed array for a materialized object
|
| @@ -3376,11 +3377,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
|
| // default case.
|
|
|
| default: {
|
| - Token::Value tok = peek();
|
| - // Token::Peek returns the value of the next token but
|
| - // location() gives info about the current token.
|
| - // Therefore, we need to read ahead to the next token
|
| - Next();
|
| + Token::Value tok = Next();
|
| ReportUnexpectedToken(tok);
|
| *ok = false;
|
| return NULL;
|
| @@ -3584,6 +3581,35 @@ void Parser::BuildObjectLiteralConstantProperties(
|
| }
|
|
|
|
|
| +ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
|
| + bool* ok) {
|
| + // Special handling of getter and setter syntax:
|
| + // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
|
| + // We have already read the "get" or "set" keyword.
|
| + Token::Value next = Next();
|
| + if (next == Token::IDENTIFIER ||
|
| + next == Token::STRING ||
|
| + next == Token::NUMBER ||
|
| + Token::IsKeyword(next)) {
|
| + Handle<String> name =
|
| + factory()->LookupSymbol(scanner_.literal_string(),
|
| + scanner_.literal_length());
|
| + FunctionLiteral* value =
|
| + ParseFunctionLiteral(name,
|
| + RelocInfo::kNoPosition,
|
| + DECLARATION,
|
| + CHECK_OK);
|
| + ObjectLiteral::Property* property =
|
| + NEW(ObjectLiteral::Property(is_getter, value));
|
| + return property;
|
| + } else {
|
| + ReportUnexpectedToken(next);
|
| + *ok = false;
|
| + return NULL;
|
| + }
|
| +}
|
| +
|
| +
|
| Expression* Parser::ParseObjectLiteral(bool* ok) {
|
| // ObjectLiteral ::
|
| // '{' (
|
| @@ -3601,64 +3627,39 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
| Token::Value next = peek();
|
| switch (next) {
|
| case Token::IDENTIFIER: {
|
| - // Store identifier keys as literal symbols to avoid
|
| - // resolving them when compiling code for the object
|
| - // literal.
|
| bool is_getter = false;
|
| bool is_setter = false;
|
| Handle<String> id =
|
| ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
|
| - if (is_getter || is_setter) {
|
| - // Special handling of getter and setter syntax.
|
| - Handle<String> name;
|
| - next = peek();
|
| - if (next == Token::IDENTIFIER ||
|
| - next == Token::STRING ||
|
| - next == Token::NUMBER ||
|
| - Token::IsKeyword(next)) {
|
| - Consume(next);
|
| - Handle<String> name =
|
| - factory()->LookupSymbol(scanner_.literal_string(),
|
| - scanner_.literal_length());
|
| - FunctionLiteral* value =
|
| - ParseFunctionLiteral(name,
|
| - RelocInfo::kNoPosition,
|
| - DECLARATION,
|
| - CHECK_OK);
|
| + if ((is_getter || is_setter) && peek() != Token::COLON) {
|
| ObjectLiteral::Property* property =
|
| - NEW(ObjectLiteral::Property(is_getter, value));
|
| + ParseObjectLiteralGetSet(is_getter, CHECK_OK);
|
| if (IsBoilerplateProperty(property)) {
|
| number_of_boilerplate_properties++;
|
| }
|
| properties.Add(property);
|
| if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
|
| continue; // restart the while
|
| - }
|
| }
|
| + // Failed to parse as get/set property, so it's just a property
|
| + // called "get" or "set".
|
| key = NEW(Literal(id));
|
| break;
|
| }
|
| -#define CASE_KEYWORD(name, ignore1, ignore2) \
|
| - case Token::name:
|
| - TOKEN_LIST(IGNORE_TOKEN, CASE_KEYWORD, IGNORE_TOKEN)
|
| -#undef CASE_KEYWORD
|
| - // FALLTHROUGH - keyword tokens fall through to the same code as strings.
|
| case Token::STRING: {
|
| - Consume(next);
|
| + Consume(Token::STRING);
|
| Handle<String> string =
|
| factory()->LookupSymbol(scanner_.literal_string(),
|
| scanner_.literal_length());
|
| uint32_t index;
|
| - if (next == Token::STRING &&
|
| - !string.is_null() &&
|
| + if (!string.is_null() &&
|
| string->AsArrayIndex(&index)) {
|
| key = NewNumberLiteral(index);
|
| - } else {
|
| - key = NEW(Literal(string));
|
| + break;
|
| }
|
| + key = NEW(Literal(string));
|
| break;
|
| }
|
| -
|
| case Token::NUMBER: {
|
| Consume(Token::NUMBER);
|
| double value =
|
| @@ -3666,10 +3667,20 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
| key = NewNumberLiteral(value);
|
| break;
|
| }
|
| -
|
| default:
|
| - Expect(Token::RBRACE, CHECK_OK);
|
| - break;
|
| + if (Token::IsKeyword(next)) {
|
| + Consume(next);
|
| + Handle<String> string =
|
| + factory()->LookupSymbol(scanner_.literal_string(),
|
| + scanner_.literal_length());
|
| + key = NEW(Literal(string));
|
| + } else {
|
| + // Unexpected token.
|
| + Token::Value next = Next();
|
| + ReportUnexpectedToken(next);
|
| + *ok = false;
|
| + return NULL;
|
| + }
|
| }
|
|
|
| Expect(Token::COLON, CHECK_OK);
|
|
|