Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index dd5f9bd0d05080f0ba0f328a80ea0e9611ce1e30..bf1a348211e138273d2fff6ee7463d2880341ad6 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -265,6 +265,7 @@ class Parser { |
Literal* GetLiteralNumber(double value); |
Handle<String> ParseIdentifier(bool* ok); |
+ Handle<String> ParseIdentifierName(bool* ok); |
Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, |
bool* is_set, |
bool* ok); |
@@ -3121,7 +3122,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
case Token::PERIOD: { |
Consume(Token::PERIOD); |
int pos = scanner().location().beg_pos; |
- Handle<String> name = ParseIdentifier(CHECK_OK); |
+ Handle<String> name = ParseIdentifierName(CHECK_OK); |
result = factory()->NewProperty(result, NEW(Literal(name)), pos); |
break; |
} |
@@ -3207,7 +3208,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
case Token::PERIOD: { |
Consume(Token::PERIOD); |
int pos = scanner().location().beg_pos; |
- Handle<String> name = ParseIdentifier(CHECK_OK); |
+ Handle<String> name = ParseIdentifierName(CHECK_OK); |
result = factory()->NewProperty(result, NEW(Literal(name)), pos); |
break; |
} |
@@ -3586,8 +3587,8 @@ void Parser::BuildObjectLiteralConstantProperties( |
Expression* Parser::ParseObjectLiteral(bool* ok) { |
// ObjectLiteral :: |
// '{' ( |
- // ((Identifier | String | Number) ':' AssignmentExpression) |
- // | (('get' | 'set') FunctionLiteral) |
+ // ((IdentifierName | String | Number) ':' AssignmentExpression) |
+ // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
// )*[','] '}' |
ZoneListWrapper<ObjectLiteral::Property> properties = |
@@ -3597,7 +3598,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { |
Expect(Token::LBRACE, CHECK_OK); |
while (peek() != Token::RBRACE) { |
Literal* key = NULL; |
- switch (peek()) { |
+ 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 |
@@ -3608,15 +3610,26 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { |
ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
if (is_getter || is_setter) { |
// Special handling of getter and setter syntax. |
- if (peek() == Token::IDENTIFIER) { |
- Handle<String> name = ParseIdentifier(CHECK_OK); |
+ 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); |
+ ParseFunctionLiteral(name, |
+ RelocInfo::kNoPosition, |
+ DECLARATION, |
+ CHECK_OK); |
ObjectLiteral::Property* property = |
NEW(ObjectLiteral::Property(is_getter, value)); |
- if (IsBoilerplateProperty(property)) |
+ if (IsBoilerplateProperty(property)) { |
number_of_boilerplate_properties++; |
+ } |
properties.Add(property); |
if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
continue; // restart the while |
@@ -3625,14 +3638,20 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { |
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(Token::STRING); |
+ Consume(next); |
Handle<String> string = |
factory()->LookupSymbol(scanner_.literal_string(), |
scanner_.literal_length()); |
uint32_t index; |
- if (!string.is_null() && string->AsArrayIndex(&index)) { |
+ if (next == Token::STRING && |
+ !string.is_null() && |
+ string->AsArrayIndex(&index)) { |
key = NewNumberLiteral(index); |
} else { |
key = NEW(Literal(string)); |
@@ -4008,6 +4027,19 @@ Handle<String> Parser::ParseIdentifier(bool* ok) { |
scanner_.literal_length()); |
} |
+ |
+Handle<String> Parser::ParseIdentifierName(bool* ok) { |
+ Token::Value next = Next(); |
+ if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { |
+ ReportUnexpectedToken(next); |
+ *ok = false; |
+ return Handle<String>(); |
+ } |
+ return factory()->LookupSymbol(scanner_.literal_string(), |
+ scanner_.literal_length()); |
+} |
+ |
+ |
// This function reads an identifier and determines whether or not it |
// is 'get' or 'set'. The reason for not using ParseIdentifier and |
// checking on the output is that this involves heap allocation which |