Revision: 23249
Author: [email protected]
Date: Wed Aug 20 15:51:07 2014 UTC
Log: Refactor ParseObjectLiteral
This extracts the parsing of the ObjectLiteralProperty into its own
function. This is in preparation for adding support for parsing classes.
BUG=None
LOG=Y
[email protected], [email protected]
Review URL: https://codereview.chromium.org/458613004
http://code.google.com/p/v8/source/detail?r=23249
Modified:
/branches/bleeding_edge/src/parser.h
/branches/bleeding_edge/src/preparser.h
=======================================
--- /branches/bleeding_edge/src/parser.h Mon Aug 18 12:35:34 2014 UTC
+++ /branches/bleeding_edge/src/parser.h Wed Aug 20 15:51:07 2014 UTC
@@ -439,7 +439,8 @@
}
static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
- Scope* scope, Expression* value, bool* has_function) {
+ Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
+ Expression* value = property->value();
if (scope->DeclarationScope()->is_global_scope() &&
value->AsFunctionLiteral() != NULL) {
*has_function = true;
@@ -529,6 +530,7 @@
static Literal* EmptyLiteral() {
return NULL;
}
+ static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return
NULL; }
// Used in error return values.
static ZoneList<Expression*>* NullExpressionList() {
=======================================
--- /branches/bleeding_edge/src/preparser.h Wed Aug 20 14:25:48 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h Wed Aug 20 15:51:07 2014 UTC
@@ -30,7 +30,7 @@
// interface as AstNodeFactory, so ParserBase doesn't need to care which
one is
// used.
-// - Miscellanous other tasks interleaved with the recursive descent. For
+// - Miscellaneous other tasks interleaved with the recursive descent. For
// example, Parser keeps track of which function literals should be marked
as
// pretenured, and PreParser doesn't care.
@@ -63,6 +63,8 @@
typedef typename Traits::Type::Expression ExpressionT;
typedef typename Traits::Type::Identifier IdentifierT;
typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
+ typedef typename Traits::Type::Literal LiteralT;
+ typedef typename Traits::Type::ObjectLiteralProperty
ObjectLiteralPropertyT;
ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension*
extension,
ParserRecorder* log, typename Traits::Type::Zone* zone,
@@ -474,6 +476,7 @@
ExpressionT ParseExpression(bool accept_IN, bool* ok);
ExpressionT ParseArrayLiteral(bool* ok);
ExpressionT ParseObjectLiteral(bool* ok);
+ ObjectLiteralPropertyT ParsePropertyDefinition(bool* ok);
typename Traits::Type::ExpressionList ParseArguments(bool* ok);
ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
ExpressionT ParseYieldExpression(bool* ok);
@@ -1109,7 +1112,8 @@
}
static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
- PreParserScope* scope, PreParserExpression value, bool*
has_function) {}
+ PreParserScope* scope, PreParserExpression property, bool*
has_function) {
+ }
static void CheckAssigningFunctionLiteralToProperty(
PreParserExpression left, PreParserExpression right) {}
@@ -1181,6 +1185,9 @@
static PreParserExpression EmptyLiteral() {
return PreParserExpression::Default();
}
+ static PreParserExpression EmptyObjectLiteralProperty() {
+ return PreParserExpression::Default();
+ }
static PreParserExpressionList NullExpressionList() {
return PreParserExpressionList();
}
@@ -1791,17 +1798,92 @@
return factory()->NewArrayLiteral(values, literal_index, pos);
}
+
+
+template <class Traits>
+typename ParserBase<Traits>::ObjectLiteralPropertyT
+ParserBase<Traits>::ParsePropertyDefinition(bool* ok) {
+ LiteralT key = this->EmptyLiteral();
+ Token::Value next = peek();
+ int next_pos = peek_position();
+
+ switch (next) {
+ 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: {
+ 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);
+ // TODO(arv): Fix issue with numeric keys. get 1.0() should be
+ // treated as if the key was '1'
+ // https://code.google.com/p/v8/issues/detail?id=3507
+ name = this->GetSymbol(scanner_);
+ break;
+ default:
+ name = ParseIdentifierName(
+ 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);
+ }
+ }
+
+ Expect(Token::COLON, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ ExpressionT value = this->ParseAssignmentExpression(
+ true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+
+ return factory()->NewObjectLiteralProperty(key, value);
+}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseObjectLiteral(
bool* ok) {
// ObjectLiteral ::
- // '{' ((
- // ((IdentifierName | String | Number) ':' AssignmentExpression) |
- // (('get' | 'set') (IdentifierName | String | Number)
FunctionLiteral)
- // ) ',')* '}'
- // (Except that the trailing comma is not required.)
+ // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
int pos = peek_position();
typename Traits::Type::PropertyList properties =
@@ -1814,112 +1896,12 @@
while (peek() != Token::RBRACE) {
if (fni_ != NULL) fni_->Enter();
- typename Traits::Type::Literal key = this->EmptyLiteral();
- Token::Value next = peek();
- int next_pos = peek_position();
-
- switch (next) {
- case Token::FUTURE_RESERVED_WORD:
- case Token::FUTURE_STRICT_RESERVED_WORD:
- case Token::LET:
- case Token::YIELD:
- case Token::IDENTIFIER: {
- bool is_getter = false;
- bool is_setter = false;
- IdentifierT id =
- ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter,
CHECK_OK);
- 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.
- Token::Value next = Next();
- if (next != i::Token::IDENTIFIER &&
- next != i::Token::FUTURE_RESERVED_WORD &&
- next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
- next != i::Token::LET &&
- next != i::Token::YIELD &&
- next != i::Token::NUMBER &&
- next != i::Token::STRING &&
- !Token::IsKeyword(next)) {
- ReportUnexpectedToken(next);
- *ok = false;
- return this->EmptyLiteral();
- }
- IdentifierT name = this->GetSymbol(scanner_);
- 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);
- typename Traits::Type::ObjectLiteralProperty property =
- factory()->NewObjectLiteralProperty(is_getter, value,
next_pos);
- if (this->IsBoilerplateProperty(property)) {
- number_of_boilerplate_properties++;
- }
- properties->Add(property, zone());
- if (peek() != Token::RBRACE) {
- // Need {} because of the CHECK_OK macro.
- Expect(Token::COMMA, CHECK_OK);
- }
-
- if (fni_ != NULL) {
- fni_->Infer();
- fni_->Leave();
- }
- continue; // restart the while
- }
- // 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);
- break;
- }
- 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: {
- Consume(Token::NUMBER);
- key = this->ExpressionFromLiteral(Token::NUMBER, next_pos,
scanner_,
- factory());
- break;
- }
- default:
- if (Token::IsKeyword(next)) {
- Consume(next);
- IdentifierT string = this->GetSymbol(scanner_);
- key = factory()->NewStringLiteral(string, next_pos);
- } else {
- Token::Value next = Next();
- ReportUnexpectedToken(next);
- *ok = false;
- return this->EmptyLiteral();
- }
- }
-
- Expect(Token::COLON, CHECK_OK);
- ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK);
-
- typename Traits::Type::ObjectLiteralProperty property =
- factory()->NewObjectLiteralProperty(key, value);
+ ObjectLiteralPropertyT property =
this->ParsePropertyDefinition(CHECK_OK);
// Mark top-level object literals that contain function literals and
// pretenure the literal so it can be added as a constant function
// property. (Parser only.)
- this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
+ this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
&has_function);
// Count CONSTANT or COMPUTED properties to maintain the enumeration
order.
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.