Honor the declaration order of getter/setter in object literals

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@174 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
feng@chromium.org 2008-09-05 16:47:42 +00:00
parent ebfa9d37b6
commit ecbfddf052
2 changed files with 35 additions and 12 deletions

View File

@ -151,6 +151,13 @@ class Parser {
Expression* ParseObjectLiteral(bool* ok);
Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
// Decide if a property should be the object boilerplate.
bool IsBoilerplateProperty(ObjectLiteral::Property* property);
// If the property is CONSTANT type, it returns the literal value,
// otherwise, it return undefined literal as the placeholder
// in the object literal boilerplate.
Literal* GetBoilerplateValue(ObjectLiteral::Property* property);
enum FunctionLiteralType {
EXPRESSION,
DECLARATION,
@ -2643,6 +2650,19 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
}
bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
return property != NULL &&
property->kind() != ObjectLiteral::Property::PROTOTYPE;
}
Literal* Parser::GetBoilerplateValue(ObjectLiteral::Property* property) {
if (property->kind() == ObjectLiteral::Property::CONSTANT)
return property->value()->AsLiteral();
return GetLiteralUndefined();
}
Expression* Parser::ParseObjectLiteral(bool* ok) {
// ObjectLiteral ::
// '{' (
@ -2674,6 +2694,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
ParseFunctionLiteral(name, kNoPosition, DECLARATION, CHECK_OK);
ObjectLiteral::Property* property =
NEW(ObjectLiteral::Property(is_getter, value));
if (IsBoilerplateProperty(property))
number_of_boilerplate_properties++;
properties.Add(property);
if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
continue; // restart the while
@ -2717,11 +2739,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
NEW(ObjectLiteral::Property(key, value));
// Count CONSTANT or COMPUTED properties to maintain the enumeration order.
if ((property != NULL) &&
(property->kind() == ObjectLiteral::Property::CONSTANT ||
property->kind() == ObjectLiteral::Property::COMPUTED) ) {
if (IsBoilerplateProperty(property))
number_of_boilerplate_properties++;
}
properties.Add(property);
// TODO(1240767): Consider allowing trailing comma.
@ -2737,18 +2756,13 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
int position = 0;
for (int i = 0; i < properties.length(); i++) {
ObjectLiteral::Property* property = properties.at(i);
Handle<Object> key = property->key()->handle();
Literal* literal = NULL;
if (!IsBoilerplateProperty(property)) continue;
// Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
// value for COMPUTED properties, the real value is filled in at
// runtime. The enumeration order is maintained.
if (property->kind() == ObjectLiteral::Property::CONSTANT)
literal = property->value()->AsLiteral();
else if (property->kind() == ObjectLiteral::Property::COMPUTED)
literal = GetLiteralUndefined();
else
continue;
Handle<Object> key = property->key()->handle();
Literal* literal = GetBoilerplateValue(property);
// Add name, value pair to the fixed array.
constant_properties->set(position++, *key);

View File

@ -75,3 +75,12 @@ assertEquals('ab', result);
var result = '';
for (var p in {a : {v:1}, b : 1}) { result += p; }
assertEquals('ab', result);
var result = '';
for (var p in { get a() {}, b : 1}) { result += p; }
assertEquals('ab', result);
var result = '';
for (var p in { get a() {}, set a(x) {}, b : 1}) { result += p; }
assertEquals('ab', result);