Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |