Commit 53690b68 authored by lrn@chromium.org's avatar lrn@chromium.org

Changed layout of object literal parser.

Review URL: http://codereview.chromium.org/3032064

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5206 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 53e22e38
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment