Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/preparser.h

Issue 332443002: Add support for computed property names in object literals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Dynamic part of object literal initialized with PutOwnProperty Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/func-name-inferrer.h" 8 #include "src/func-name-inferrer.h"
9 #include "src/hashmap.h" 9 #include "src/hashmap.h"
10 #include "src/scopes.h" 10 #include "src/scopes.h"
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 int literal_index, 762 int literal_index,
763 int pos) { 763 int pos) {
764 return PreParserExpression::Default(); 764 return PreParserExpression::Default();
765 } 765 }
766 PreParserExpression NewObjectLiteralProperty(bool is_getter, 766 PreParserExpression NewObjectLiteralProperty(bool is_getter,
767 PreParserExpression value, 767 PreParserExpression value,
768 int pos) { 768 int pos) {
769 return PreParserExpression::Default(); 769 return PreParserExpression::Default();
770 } 770 }
771 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, 771 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
772 PreParserExpression value) { 772 PreParserExpression value,
773 bool is_computed_name) {
773 return PreParserExpression::Default(); 774 return PreParserExpression::Default();
774 } 775 }
775 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, 776 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
776 int literal_index, 777 int literal_index,
777 int boilerplate_properties, 778 int boilerplate_properties,
778 bool has_function, 779 bool has_function,
779 int pos) { 780 int pos) {
780 return PreParserExpression::Default(); 781 return PreParserExpression::Default();
781 } 782 }
782 PreParserExpression NewVariableProxy(void* generator_variable) { 783 PreParserExpression NewVariableProxy(void* generator_variable) {
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 return factory()->NewArrayLiteral(values, literal_index, pos); 1490 return factory()->NewArrayLiteral(values, literal_index, pos);
1490 } 1491 }
1491 1492
1492 1493
1493 template <class Traits> 1494 template <class Traits>
1494 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( 1495 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
1495 bool* ok) { 1496 bool* ok) {
1496 // ObjectLiteral :: 1497 // ObjectLiteral ::
1497 // '{' (( 1498 // '{' ((
1498 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1499 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
1499 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1500 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)|
1501 // ('[' AssignmentExpression ']' ':' AssignmentExpression)
1500 // ) ',')* '}' 1502 // ) ',')* '}'
1501 // (Except that trailing comma is not required and not allowed.) 1503 // (Except that trailing comma is not required and not allowed.)
1502 1504
1503 int pos = peek_position(); 1505 int pos = peek_position();
1504 typename Traits::Type::PropertyList properties = 1506 typename Traits::Type::PropertyList properties =
1505 this->NewPropertyList(4, zone_); 1507 this->NewPropertyList(4, zone_);
1506 int number_of_boilerplate_properties = 0; 1508 int number_of_boilerplate_properties = 0;
1507 bool has_function = false; 1509 bool has_function = false;
1510 bool has_computed_names = false;
1508 1511
1509 ObjectLiteralChecker checker(this, strict_mode()); 1512 ObjectLiteralChecker checker(this, strict_mode());
1510 1513
1511 Expect(Token::LBRACE, CHECK_OK); 1514 Expect(Token::LBRACE, CHECK_OK);
1512 1515
1513 while (peek() != Token::RBRACE) { 1516 while (peek() != Token::RBRACE) {
1514 if (fni_ != NULL) fni_->Enter(); 1517 if (fni_ != NULL) fni_->Enter();
1515 1518
1516 typename Traits::Type::Literal key = this->EmptyLiteral(); 1519 bool is_computed_name = false;
1520 ExpressionT key = this->EmptyLiteral();
1517 Token::Value next = peek(); 1521 Token::Value next = peek();
1518 int next_pos = peek_position(); 1522 int next_pos = peek_position();
1519 1523
1520 switch (next) { 1524 switch (next) {
1521 case Token::FUTURE_RESERVED_WORD: 1525 case Token::FUTURE_RESERVED_WORD:
1522 case Token::FUTURE_STRICT_RESERVED_WORD: 1526 case Token::FUTURE_STRICT_RESERVED_WORD:
1523 case Token::IDENTIFIER: { 1527 case Token::IDENTIFIER: {
1524 bool is_getter = false; 1528 bool is_getter = false;
1525 bool is_setter = false; 1529 bool is_setter = false;
1526 IdentifierT id = 1530 IdentifierT id =
1527 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1531 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1528 if (fni_ != NULL) this->PushLiteralName(fni_, id); 1532 if (fni_ != NULL) this->PushLiteralName(fni_, id);
1529 1533
1530 if ((is_getter || is_setter) && peek() != Token::COLON) { 1534 if ((is_getter || is_setter) && peek() != Token::COLON) {
1531 // Special handling of getter and setter syntax: 1535 // Special handling of getter and setter syntax:
1532 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 1536 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
1533 // We have already read the "get" or "set" keyword. 1537 // We have already read the "get" or "set" keyword.
1534 Token::Value next = Next(); 1538 Token::Value next = Next();
1535 if (next != i::Token::IDENTIFIER && 1539 if (next != i::Token::IDENTIFIER &&
1536 next != i::Token::FUTURE_RESERVED_WORD && 1540 next != i::Token::FUTURE_RESERVED_WORD &&
1537 next != i::Token::FUTURE_STRICT_RESERVED_WORD && 1541 next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1538 next != i::Token::NUMBER && 1542 next != i::Token::NUMBER &&
1539 next != i::Token::STRING && 1543 next != i::Token::STRING &&
1540 !Token::IsKeyword(next)) { 1544 !Token::IsKeyword(next)) {
1545 // FIXME(wingo): Add support for computed property names here, as in
1546 // get [AssignmentExpression]() { .. }.
1541 ReportUnexpectedToken(next); 1547 ReportUnexpectedToken(next);
1542 *ok = false; 1548 *ok = false;
1543 return this->EmptyLiteral(); 1549 return this->EmptyLiteral();
1544 } 1550 }
1545 // Validate the property. 1551 // Validate the property.
1546 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1552 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1547 checker.CheckProperty(next, type, CHECK_OK); 1553 checker.CheckProperty(next, type, CHECK_OK);
1548 IdentifierT name = this->GetSymbol(scanner_); 1554 IdentifierT name = this->GetSymbol(scanner_);
1549 typename Traits::Type::FunctionLiteral value = 1555 typename Traits::Type::FunctionLiteral value =
1550 this->ParseFunctionLiteral( 1556 this->ParseFunctionLiteral(
1551 name, scanner()->location(), 1557 name, scanner()->location(),
1552 false, // reserved words are allowed here 1558 false, // reserved words are allowed here
1553 false, // not a generator 1559 false, // not a generator
1554 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 1560 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1555 CHECK_OK); 1561 CHECK_OK);
1556 // Allow any number of parameters for compatibilty with JSC. 1562 // Allow any number of parameters for compatibilty with JSC.
1557 // Specification only allows zero parameters for get and one for set. 1563 // Specification only allows zero parameters for get and one for set.
1558 typename Traits::Type::ObjectLiteralProperty property = 1564 typename Traits::Type::ObjectLiteralProperty property =
1559 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); 1565 factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
1560 if (this->IsBoilerplateProperty(property)) { 1566 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
1561 number_of_boilerplate_properties++; 1567 number_of_boilerplate_properties++;
1562 } 1568 }
1563 properties->Add(property, zone()); 1569 properties->Add(property, zone());
1564 if (peek() != Token::RBRACE) { 1570 if (peek() != Token::RBRACE) {
1565 // Need {} because of the CHECK_OK macro. 1571 // Need {} because of the CHECK_OK macro.
1566 Expect(Token::COMMA, CHECK_OK); 1572 Expect(Token::COMMA, CHECK_OK);
1567 } 1573 }
1568 1574
1569 if (fni_ != NULL) { 1575 if (fni_ != NULL) {
1570 fni_->Infer(); 1576 fni_->Infer();
(...skipping 17 matching lines...) Expand all
1588 } 1594 }
1589 key = factory()->NewLiteral(string, next_pos); 1595 key = factory()->NewLiteral(string, next_pos);
1590 break; 1596 break;
1591 } 1597 }
1592 case Token::NUMBER: { 1598 case Token::NUMBER: {
1593 Consume(Token::NUMBER); 1599 Consume(Token::NUMBER);
1594 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_, 1600 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_,
1595 factory()); 1601 factory());
1596 break; 1602 break;
1597 } 1603 }
1604 case Token::LBRACK: {
1605 Consume(Token::LBRACK);
1606 has_computed_names = true;
1607 is_computed_name = true;
Michael Starzinger 2014/06/13 08:14:18 Shouldn't the detection of this syntax live behind
rossberg 2014/06/13 15:19:24 I agree, we should have --harmony-object-literals
wingo 2014/06/16 08:32:27 Done.
1608 key = this->ParseAssignmentExpression(true, CHECK_OK);
1609 Expect(Token::RBRACK, CHECK_OK);
1610 break;
1611 }
1598 default: 1612 default:
1599 if (Token::IsKeyword(next)) { 1613 if (Token::IsKeyword(next)) {
1600 Consume(next); 1614 Consume(next);
1601 IdentifierT string = this->GetSymbol(scanner_); 1615 IdentifierT string = this->GetSymbol(scanner_);
1602 key = factory()->NewLiteral(string, next_pos); 1616 key = factory()->NewLiteral(string, next_pos);
1603 } else { 1617 } else {
1604 Token::Value next = Next(); 1618 Token::Value next = Next();
1605 ReportUnexpectedToken(next); 1619 ReportUnexpectedToken(next);
1606 *ok = false; 1620 *ok = false;
1607 return this->EmptyLiteral(); 1621 return this->EmptyLiteral();
1608 } 1622 }
1609 } 1623 }
1610 1624
1611 // Validate the property 1625 // Validate the property
1612 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1626 if (!is_computed_name) {
1627 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1628 }
1613 1629
1614 Expect(Token::COLON, CHECK_OK); 1630 Expect(Token::COLON, CHECK_OK);
1615 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK); 1631 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK);
1616 1632
1617 typename Traits::Type::ObjectLiteralProperty property = 1633 typename Traits::Type::ObjectLiteralProperty property =
1618 factory()->NewObjectLiteralProperty(key, value); 1634 factory()->NewObjectLiteralProperty(key, value, is_computed_name);
1619 1635
1620 // Mark top-level object literals that contain function literals and 1636 // Mark top-level object literals that contain function literals and
1621 // pretenure the literal so it can be added as a constant function 1637 // pretenure the literal so it can be added as a constant function
1622 // property. (Parser only.) 1638 // property. (Parser only.)
1623 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value, 1639 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
1624 &has_function); 1640 &has_function);
1625 1641
1626 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 1642 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
1627 if (this->IsBoilerplateProperty(property)) { 1643 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
1628 number_of_boilerplate_properties++; 1644 number_of_boilerplate_properties++;
1629 } 1645 }
1630 properties->Add(property, zone()); 1646 properties->Add(property, zone());
1631 1647
1632 // TODO(1240767): Consider allowing trailing comma. 1648 // TODO(1240767): Consider allowing trailing comma.
1633 if (peek() != Token::RBRACE) { 1649 if (peek() != Token::RBRACE) {
1634 // Need {} because of the CHECK_OK macro. 1650 // Need {} because of the CHECK_OK macro.
1635 Expect(Token::COMMA, CHECK_OK); 1651 Expect(Token::COMMA, CHECK_OK);
1636 } 1652 }
1637 1653
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
2161 parser()->ReportMessage("accessor_get_set"); 2177 parser()->ReportMessage("accessor_get_set");
2162 } 2178 }
2163 *ok = false; 2179 *ok = false;
2164 } 2180 }
2165 } 2181 }
2166 2182
2167 2183
2168 } } // v8::internal 2184 } } // v8::internal
2169 2185
2170 #endif // V8_PREPARSER_H 2186 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698