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); |