| 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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
| 7 | 7 |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
| (...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1417 return result; | 1417 return result; |
| 1418 } | 1418 } |
| 1419 | 1419 |
| 1420 template <typename Impl> | 1420 template <typename Impl> |
| 1421 typename ParserBase<Impl>::IdentifierT | 1421 typename ParserBase<Impl>::IdentifierT |
| 1422 ParserBase<Impl>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1422 ParserBase<Impl>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
| 1423 bool* ok) { | 1423 bool* ok) { |
| 1424 Token::Value next = Next(); | 1424 Token::Value next = Next(); |
| 1425 if (next == Token::IDENTIFIER || next == Token::ASYNC || | 1425 if (next == Token::IDENTIFIER || next == Token::ASYNC || |
| 1426 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { | 1426 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { |
| 1427 IdentifierT name = this->GetSymbol(scanner()); | 1427 IdentifierT name = impl()->GetSymbol(); |
| 1428 // When this function is used to read a formal parameter, we don't always | 1428 // When this function is used to read a formal parameter, we don't always |
| 1429 // know whether the function is going to be strict or sloppy. Indeed for | 1429 // know whether the function is going to be strict or sloppy. Indeed for |
| 1430 // arrow functions we don't always know that the identifier we are reading | 1430 // arrow functions we don't always know that the identifier we are reading |
| 1431 // is actually a formal parameter. Therefore besides the errors that we | 1431 // is actually a formal parameter. Therefore besides the errors that we |
| 1432 // must detect because we know we're in strict mode, we also record any | 1432 // must detect because we know we're in strict mode, we also record any |
| 1433 // error that we might make in the future once we know the language mode. | 1433 // error that we might make in the future once we know the language mode. |
| 1434 if (impl()->IsEvalOrArguments(name)) { | 1434 if (impl()->IsEvalOrArguments(name)) { |
| 1435 classifier->RecordStrictModeFormalParameterError( | 1435 classifier->RecordStrictModeFormalParameterError( |
| 1436 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1436 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 1437 if (is_strict(language_mode())) { | 1437 if (is_strict(language_mode())) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1460 ReportUnexpectedToken(next); | 1460 ReportUnexpectedToken(next); |
| 1461 *ok = false; | 1461 *ok = false; |
| 1462 return impl()->EmptyIdentifier(); | 1462 return impl()->EmptyIdentifier(); |
| 1463 } | 1463 } |
| 1464 if (next == Token::LET || | 1464 if (next == Token::LET || |
| 1465 (next == Token::ESCAPED_STRICT_RESERVED_WORD && | 1465 (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
| 1466 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { | 1466 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { |
| 1467 classifier->RecordLetPatternError(scanner()->location(), | 1467 classifier->RecordLetPatternError(scanner()->location(), |
| 1468 MessageTemplate::kLetInLexicalBinding); | 1468 MessageTemplate::kLetInLexicalBinding); |
| 1469 } | 1469 } |
| 1470 return this->GetSymbol(scanner()); | 1470 return impl()->GetSymbol(); |
| 1471 } else { | 1471 } else { |
| 1472 this->ReportUnexpectedToken(next); | 1472 this->ReportUnexpectedToken(next); |
| 1473 *ok = false; | 1473 *ok = false; |
| 1474 return impl()->EmptyIdentifier(); | 1474 return impl()->EmptyIdentifier(); |
| 1475 } | 1475 } |
| 1476 } | 1476 } |
| 1477 | 1477 |
| 1478 template <class Impl> | 1478 template <class Impl> |
| 1479 typename ParserBase<Impl>::IdentifierT | 1479 typename ParserBase<Impl>::IdentifierT |
| 1480 ParserBase<Impl>::ParseIdentifierOrStrictReservedWord( | 1480 ParserBase<Impl>::ParseIdentifierOrStrictReservedWord( |
| 1481 FunctionKind function_kind, bool* is_strict_reserved, bool* ok) { | 1481 FunctionKind function_kind, bool* is_strict_reserved, bool* ok) { |
| 1482 Token::Value next = Next(); | 1482 Token::Value next = Next(); |
| 1483 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ && | 1483 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ && |
| 1484 !IsAsyncFunction(function_kind)) || | 1484 !IsAsyncFunction(function_kind)) || |
| 1485 next == Token::ASYNC) { | 1485 next == Token::ASYNC) { |
| 1486 *is_strict_reserved = false; | 1486 *is_strict_reserved = false; |
| 1487 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1487 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
| 1488 next == Token::STATIC || | 1488 next == Token::STATIC || |
| 1489 (next == Token::YIELD && !IsGeneratorFunction(function_kind))) { | 1489 (next == Token::YIELD && !IsGeneratorFunction(function_kind))) { |
| 1490 *is_strict_reserved = true; | 1490 *is_strict_reserved = true; |
| 1491 } else { | 1491 } else { |
| 1492 ReportUnexpectedToken(next); | 1492 ReportUnexpectedToken(next); |
| 1493 *ok = false; | 1493 *ok = false; |
| 1494 return impl()->EmptyIdentifier(); | 1494 return impl()->EmptyIdentifier(); |
| 1495 } | 1495 } |
| 1496 | 1496 |
| 1497 return this->GetSymbol(scanner()); | 1497 return impl()->GetSymbol(); |
| 1498 } | 1498 } |
| 1499 | 1499 |
| 1500 template <typename Impl> | 1500 template <typename Impl> |
| 1501 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName( | 1501 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName( |
| 1502 bool* ok) { | 1502 bool* ok) { |
| 1503 Token::Value next = Next(); | 1503 Token::Value next = Next(); |
| 1504 if (next != Token::IDENTIFIER && next != Token::ASYNC && | 1504 if (next != Token::IDENTIFIER && next != Token::ASYNC && |
| 1505 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && | 1505 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && |
| 1506 next != Token::STATIC && next != Token::YIELD && | 1506 next != Token::STATIC && next != Token::YIELD && |
| 1507 next != Token::FUTURE_STRICT_RESERVED_WORD && | 1507 next != Token::FUTURE_STRICT_RESERVED_WORD && |
| 1508 next != Token::ESCAPED_KEYWORD && | 1508 next != Token::ESCAPED_KEYWORD && |
| 1509 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1509 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
| 1510 this->ReportUnexpectedToken(next); | 1510 this->ReportUnexpectedToken(next); |
| 1511 *ok = false; | 1511 *ok = false; |
| 1512 return impl()->EmptyIdentifier(); | 1512 return impl()->EmptyIdentifier(); |
| 1513 } | 1513 } |
| 1514 | 1514 |
| 1515 return this->GetSymbol(scanner()); | 1515 return impl()->GetSymbol(); |
| 1516 } | 1516 } |
| 1517 | 1517 |
| 1518 template <typename Impl> | 1518 template <typename Impl> |
| 1519 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( | 1519 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( |
| 1520 bool* ok) { | 1520 bool* ok) { |
| 1521 int pos = peek_position(); | 1521 int pos = peek_position(); |
| 1522 if (!scanner()->ScanRegExpPattern()) { | 1522 if (!scanner()->ScanRegExpPattern()) { |
| 1523 Next(); | 1523 Next(); |
| 1524 ReportMessage(MessageTemplate::kUnterminatedRegExp); | 1524 ReportMessage(MessageTemplate::kUnterminatedRegExp); |
| 1525 *ok = false; | 1525 *ok = false; |
| 1526 return impl()->EmptyExpression(); | 1526 return impl()->EmptyExpression(); |
| 1527 } | 1527 } |
| 1528 | 1528 |
| 1529 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1529 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 1530 | 1530 |
| 1531 IdentifierT js_pattern = this->GetNextSymbol(scanner()); | 1531 IdentifierT js_pattern = impl()->GetNextSymbol(); |
| 1532 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); | 1532 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); |
| 1533 if (flags.IsNothing()) { | 1533 if (flags.IsNothing()) { |
| 1534 Next(); | 1534 Next(); |
| 1535 ReportMessage(MessageTemplate::kMalformedRegExpFlags); | 1535 ReportMessage(MessageTemplate::kMalformedRegExpFlags); |
| 1536 *ok = false; | 1536 *ok = false; |
| 1537 return impl()->EmptyExpression(); | 1537 return impl()->EmptyExpression(); |
| 1538 } | 1538 } |
| 1539 int js_flags = flags.FromJust(); | 1539 int js_flags = flags.FromJust(); |
| 1540 Next(); | 1540 Next(); |
| 1541 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | 1541 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1559 // '(' Expression ')' | 1559 // '(' Expression ')' |
| 1560 // TemplateLiteral | 1560 // TemplateLiteral |
| 1561 // do Block | 1561 // do Block |
| 1562 // AsyncFunctionExpression | 1562 // AsyncFunctionExpression |
| 1563 | 1563 |
| 1564 int beg_pos = peek_position(); | 1564 int beg_pos = peek_position(); |
| 1565 switch (peek()) { | 1565 switch (peek()) { |
| 1566 case Token::THIS: { | 1566 case Token::THIS: { |
| 1567 BindingPatternUnexpectedToken(classifier); | 1567 BindingPatternUnexpectedToken(classifier); |
| 1568 Consume(Token::THIS); | 1568 Consume(Token::THIS); |
| 1569 return this->ThisExpression(beg_pos); | 1569 return impl()->ThisExpression(beg_pos); |
| 1570 } | 1570 } |
| 1571 | 1571 |
| 1572 case Token::NULL_LITERAL: | 1572 case Token::NULL_LITERAL: |
| 1573 case Token::TRUE_LITERAL: | 1573 case Token::TRUE_LITERAL: |
| 1574 case Token::FALSE_LITERAL: | 1574 case Token::FALSE_LITERAL: |
| 1575 case Token::SMI: | 1575 case Token::SMI: |
| 1576 case Token::NUMBER: | 1576 case Token::NUMBER: |
| 1577 BindingPatternUnexpectedToken(classifier); | 1577 BindingPatternUnexpectedToken(classifier); |
| 1578 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1578 return impl()->ExpressionFromLiteral(Next(), beg_pos); |
| 1579 | 1579 |
| 1580 case Token::ASYNC: | 1580 case Token::ASYNC: |
| 1581 if (allow_harmony_async_await() && | 1581 if (allow_harmony_async_await() && |
| 1582 !scanner()->HasAnyLineTerminatorAfterNext() && | 1582 !scanner()->HasAnyLineTerminatorAfterNext() && |
| 1583 PeekAhead() == Token::FUNCTION) { | 1583 PeekAhead() == Token::FUNCTION) { |
| 1584 Consume(Token::ASYNC); | 1584 Consume(Token::ASYNC); |
| 1585 return impl()->ParseAsyncFunctionExpression(CHECK_OK); | 1585 return impl()->ParseAsyncFunctionExpression(CHECK_OK); |
| 1586 } | 1586 } |
| 1587 // CoverCallExpressionAndAsyncArrowHead | 1587 // CoverCallExpressionAndAsyncArrowHead |
| 1588 *is_async = true; | 1588 *is_async = true; |
| 1589 /* falls through */ | 1589 /* falls through */ |
| 1590 case Token::IDENTIFIER: | 1590 case Token::IDENTIFIER: |
| 1591 case Token::LET: | 1591 case Token::LET: |
| 1592 case Token::STATIC: | 1592 case Token::STATIC: |
| 1593 case Token::YIELD: | 1593 case Token::YIELD: |
| 1594 case Token::AWAIT: | 1594 case Token::AWAIT: |
| 1595 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1595 case Token::ESCAPED_STRICT_RESERVED_WORD: |
| 1596 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1596 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1597 // Using eval or arguments in this context is OK even in strict mode. | 1597 // Using eval or arguments in this context is OK even in strict mode. |
| 1598 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1598 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
| 1599 return this->ExpressionFromIdentifier(name, beg_pos, | 1599 return impl()->ExpressionFromIdentifier(name, beg_pos, |
| 1600 scanner()->location().end_pos); | 1600 scanner()->location().end_pos); |
| 1601 } | 1601 } |
| 1602 | 1602 |
| 1603 case Token::STRING: { | 1603 case Token::STRING: { |
| 1604 BindingPatternUnexpectedToken(classifier); | 1604 BindingPatternUnexpectedToken(classifier); |
| 1605 Consume(Token::STRING); | 1605 Consume(Token::STRING); |
| 1606 return this->ExpressionFromString(beg_pos, scanner(), factory()); | 1606 return impl()->ExpressionFromString(beg_pos); |
| 1607 } | 1607 } |
| 1608 | 1608 |
| 1609 case Token::ASSIGN_DIV: | 1609 case Token::ASSIGN_DIV: |
| 1610 case Token::DIV: | 1610 case Token::DIV: |
| 1611 classifier->RecordBindingPatternError( | 1611 classifier->RecordBindingPatternError( |
| 1612 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); | 1612 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); |
| 1613 return this->ParseRegExpLiteral(ok); | 1613 return this->ParseRegExpLiteral(ok); |
| 1614 | 1614 |
| 1615 case Token::LBRACK: | 1615 case Token::LBRACK: |
| 1616 return this->ParseArrayLiteral(classifier, ok); | 1616 return this->ParseArrayLiteral(classifier, ok); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1794 return result; | 1794 return result; |
| 1795 } | 1795 } |
| 1796 | 1796 |
| 1797 template <typename Impl> | 1797 template <typename Impl> |
| 1798 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( | 1798 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( |
| 1799 ExpressionClassifier* classifier, bool* ok) { | 1799 ExpressionClassifier* classifier, bool* ok) { |
| 1800 // ArrayLiteral :: | 1800 // ArrayLiteral :: |
| 1801 // '[' Expression? (',' Expression?)* ']' | 1801 // '[' Expression? (',' Expression?)* ']' |
| 1802 | 1802 |
| 1803 int pos = peek_position(); | 1803 int pos = peek_position(); |
| 1804 typename Traits::Type::ExpressionList values = | 1804 typename Traits::Type::ExpressionList values = impl()->NewExpressionList(4); |
| 1805 this->NewExpressionList(4, zone_); | |
| 1806 int first_spread_index = -1; | 1805 int first_spread_index = -1; |
| 1807 Expect(Token::LBRACK, CHECK_OK); | 1806 Expect(Token::LBRACK, CHECK_OK); |
| 1808 while (peek() != Token::RBRACK) { | 1807 while (peek() != Token::RBRACK) { |
| 1809 ExpressionT elem; | 1808 ExpressionT elem; |
| 1810 if (peek() == Token::COMMA) { | 1809 if (peek() == Token::COMMA) { |
| 1811 elem = impl()->GetLiteralTheHole(peek_position()); | 1810 elem = impl()->GetLiteralTheHole(peek_position()); |
| 1812 } else if (peek() == Token::ELLIPSIS) { | 1811 } else if (peek() == Token::ELLIPSIS) { |
| 1813 int start_pos = peek_position(); | 1812 int start_pos = peek_position(); |
| 1814 Consume(Token::ELLIPSIS); | 1813 Consume(Token::ELLIPSIS); |
| 1815 int expr_pos = peek_position(); | 1814 int expr_pos = peek_position(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 // "12" -> 12 | 1881 // "12" -> 12 |
| 1883 // 12.3 -> "12.3" | 1882 // 12.3 -> "12.3" |
| 1884 // 12.30 -> "12.3" | 1883 // 12.30 -> "12.3" |
| 1885 // identifier -> "identifier" | 1884 // identifier -> "identifier" |
| 1886 // | 1885 // |
| 1887 // This is important because we use the property name as a key in a hash | 1886 // This is important because we use the property name as a key in a hash |
| 1888 // table when we compute constant properties. | 1887 // table when we compute constant properties. |
| 1889 switch (token) { | 1888 switch (token) { |
| 1890 case Token::STRING: | 1889 case Token::STRING: |
| 1891 Consume(Token::STRING); | 1890 Consume(Token::STRING); |
| 1892 *name = this->GetSymbol(scanner()); | 1891 *name = impl()->GetSymbol(); |
| 1893 break; | 1892 break; |
| 1894 | 1893 |
| 1895 case Token::SMI: | 1894 case Token::SMI: |
| 1896 Consume(Token::SMI); | 1895 Consume(Token::SMI); |
| 1897 *name = this->GetNumberAsSymbol(scanner()); | 1896 *name = impl()->GetNumberAsSymbol(); |
| 1898 break; | 1897 break; |
| 1899 | 1898 |
| 1900 case Token::NUMBER: | 1899 case Token::NUMBER: |
| 1901 Consume(Token::NUMBER); | 1900 Consume(Token::NUMBER); |
| 1902 *name = this->GetNumberAsSymbol(scanner()); | 1901 *name = impl()->GetNumberAsSymbol(); |
| 1903 break; | 1902 break; |
| 1904 | 1903 |
| 1905 case Token::LBRACK: { | 1904 case Token::LBRACK: { |
| 1906 *is_computed_name = true; | 1905 *is_computed_name = true; |
| 1907 Consume(Token::LBRACK); | 1906 Consume(Token::LBRACK); |
| 1908 ExpressionClassifier computed_name_classifier(this); | 1907 ExpressionClassifier computed_name_classifier(this); |
| 1909 ExpressionT expression = | 1908 ExpressionT expression = |
| 1910 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); | 1909 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); |
| 1911 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 1910 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK); |
| 1912 classifier->Accumulate(&computed_name_classifier, | 1911 classifier->Accumulate(&computed_name_classifier, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2006 classifier->RecordLetPatternError( | 2005 classifier->RecordLetPatternError( |
| 2007 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 2006 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
| 2008 } | 2007 } |
| 2009 if (name_token == Token::AWAIT) { | 2008 if (name_token == Token::AWAIT) { |
| 2010 DCHECK(!is_async_function()); | 2009 DCHECK(!is_async_function()); |
| 2011 classifier->RecordAsyncArrowFormalParametersError( | 2010 classifier->RecordAsyncArrowFormalParametersError( |
| 2012 Scanner::Location(next_beg_pos, next_end_pos), | 2011 Scanner::Location(next_beg_pos, next_end_pos), |
| 2013 MessageTemplate::kAwaitBindingIdentifier); | 2012 MessageTemplate::kAwaitBindingIdentifier); |
| 2014 } | 2013 } |
| 2015 ExpressionT lhs = | 2014 ExpressionT lhs = |
| 2016 this->ExpressionFromIdentifier(*name, next_beg_pos, next_end_pos); | 2015 impl()->ExpressionFromIdentifier(*name, next_beg_pos, next_end_pos); |
| 2017 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 2016 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
| 2018 | 2017 |
| 2019 ExpressionT value; | 2018 ExpressionT value; |
| 2020 if (peek() == Token::ASSIGN) { | 2019 if (peek() == Token::ASSIGN) { |
| 2021 Consume(Token::ASSIGN); | 2020 Consume(Token::ASSIGN); |
| 2022 ExpressionClassifier rhs_classifier(this); | 2021 ExpressionClassifier rhs_classifier(this); |
| 2023 ExpressionT rhs = this->ParseAssignmentExpression( | 2022 ExpressionT rhs = this->ParseAssignmentExpression( |
| 2024 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2023 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2025 impl()->RewriteNonPattern(&rhs_classifier, | 2024 impl()->RewriteNonPattern(&rhs_classifier, |
| 2026 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2025 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2145 return impl()->EmptyObjectLiteralProperty(); | 2144 return impl()->EmptyObjectLiteralProperty(); |
| 2146 } | 2145 } |
| 2147 | 2146 |
| 2148 template <typename Impl> | 2147 template <typename Impl> |
| 2149 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 2148 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
| 2150 ExpressionClassifier* classifier, bool* ok) { | 2149 ExpressionClassifier* classifier, bool* ok) { |
| 2151 // ObjectLiteral :: | 2150 // ObjectLiteral :: |
| 2152 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2151 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
| 2153 | 2152 |
| 2154 int pos = peek_position(); | 2153 int pos = peek_position(); |
| 2155 typename Traits::Type::PropertyList properties = | 2154 typename Traits::Type::PropertyList properties = impl()->NewPropertyList(4); |
| 2156 this->NewPropertyList(4, zone_); | |
| 2157 int number_of_boilerplate_properties = 0; | 2155 int number_of_boilerplate_properties = 0; |
| 2158 bool has_computed_names = false; | 2156 bool has_computed_names = false; |
| 2159 ObjectLiteralChecker checker(this); | 2157 ObjectLiteralChecker checker(this); |
| 2160 | 2158 |
| 2161 Expect(Token::LBRACE, CHECK_OK); | 2159 Expect(Token::LBRACE, CHECK_OK); |
| 2162 | 2160 |
| 2163 while (peek() != Token::RBRACE) { | 2161 while (peek() != Token::RBRACE) { |
| 2164 FuncNameInferrer::State fni_state(fni_); | 2162 FuncNameInferrer::State fni_state(fni_); |
| 2165 | 2163 |
| 2166 const bool in_class = false; | 2164 const bool in_class = false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2203 | 2201 |
| 2204 template <typename Impl> | 2202 template <typename Impl> |
| 2205 typename ParserBase<Impl>::Traits::Type::ExpressionList | 2203 typename ParserBase<Impl>::Traits::Type::ExpressionList |
| 2206 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, | 2204 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, |
| 2207 bool maybe_arrow, | 2205 bool maybe_arrow, |
| 2208 ExpressionClassifier* classifier, bool* ok) { | 2206 ExpressionClassifier* classifier, bool* ok) { |
| 2209 // Arguments :: | 2207 // Arguments :: |
| 2210 // '(' (AssignmentExpression)*[','] ')' | 2208 // '(' (AssignmentExpression)*[','] ')' |
| 2211 | 2209 |
| 2212 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2210 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 2213 typename Traits::Type::ExpressionList result = | 2211 typename Traits::Type::ExpressionList result = impl()->NewExpressionList(4); |
| 2214 this->NewExpressionList(4, zone_); | |
| 2215 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2212 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2216 bool done = (peek() == Token::RPAREN); | 2213 bool done = (peek() == Token::RPAREN); |
| 2217 bool was_unspread = false; | 2214 bool was_unspread = false; |
| 2218 int unspread_sequences_count = 0; | 2215 int unspread_sequences_count = 0; |
| 2219 while (!done) { | 2216 while (!done) { |
| 2220 int start_pos = peek_position(); | 2217 int start_pos = peek_position(); |
| 2221 bool is_spread = Check(Token::ELLIPSIS); | 2218 bool is_spread = Check(Token::ELLIPSIS); |
| 2222 int expr_pos = peek_position(); | 2219 int expr_pos = peek_position(); |
| 2223 | 2220 |
| 2224 ExpressionT argument = this->ParseAssignmentExpression( | 2221 ExpressionT argument = this->ParseAssignmentExpression( |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2326 } else { | 2323 } else { |
| 2327 expression = this->ParseConditionalExpression( | 2324 expression = this->ParseConditionalExpression( |
| 2328 accept_IN, &arrow_formals_classifier, CHECK_OK); | 2325 accept_IN, &arrow_formals_classifier, CHECK_OK); |
| 2329 } | 2326 } |
| 2330 | 2327 |
| 2331 if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() && | 2328 if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() && |
| 2332 PeekAhead() == Token::ARROW) { | 2329 PeekAhead() == Token::ARROW) { |
| 2333 // async Identifier => AsyncConciseBody | 2330 // async Identifier => AsyncConciseBody |
| 2334 IdentifierT name = | 2331 IdentifierT name = |
| 2335 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | 2332 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); |
| 2336 expression = this->ExpressionFromIdentifier( | 2333 expression = impl()->ExpressionFromIdentifier( |
| 2337 name, position(), scanner()->location().end_pos, InferName::kNo); | 2334 name, position(), scanner()->location().end_pos, InferName::kNo); |
| 2338 if (fni_) { | 2335 if (fni_) { |
| 2339 // Remove `async` keyword from inferred name stack. | 2336 // Remove `async` keyword from inferred name stack. |
| 2340 fni_->RemoveAsyncKeywordFromEnd(); | 2337 fni_->RemoveAsyncKeywordFromEnd(); |
| 2341 } | 2338 } |
| 2342 } | 2339 } |
| 2343 | 2340 |
| 2344 if (peek() == Token::ARROW) { | 2341 if (peek() == Token::ARROW) { |
| 2345 Scanner::Location arrow_loc = scanner()->peek_location(); | 2342 Scanner::Location arrow_loc = scanner()->peek_location(); |
| 2346 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2343 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2921 if (spread_pos.IsValid()) { | 2918 if (spread_pos.IsValid()) { |
| 2922 args = impl()->PrepareSpreadArguments(args); | 2919 args = impl()->PrepareSpreadArguments(args); |
| 2923 result = impl()->SpreadCall(result, args, pos); | 2920 result = impl()->SpreadCall(result, args, pos); |
| 2924 } else { | 2921 } else { |
| 2925 result = factory()->NewCall(result, args, pos, is_possibly_eval); | 2922 result = factory()->NewCall(result, args, pos, is_possibly_eval); |
| 2926 } | 2923 } |
| 2927 | 2924 |
| 2928 // Explicit calls to the super constructor using super() perform an | 2925 // Explicit calls to the super constructor using super() perform an |
| 2929 // implicit binding assignment to the 'this' variable. | 2926 // implicit binding assignment to the 'this' variable. |
| 2930 if (is_super_call) { | 2927 if (is_super_call) { |
| 2931 ExpressionT this_expr = this->ThisExpression(pos); | 2928 ExpressionT this_expr = impl()->ThisExpression(pos); |
| 2932 result = | 2929 result = |
| 2933 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 2930 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
| 2934 } | 2931 } |
| 2935 | 2932 |
| 2936 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2933 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 2937 break; | 2934 break; |
| 2938 } | 2935 } |
| 2939 | 2936 |
| 2940 case Token::PERIOD: { | 2937 case Token::PERIOD: { |
| 2941 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2938 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3018 result = impl()->SpreadCallNew(result, args, new_pos); | 3015 result = impl()->SpreadCallNew(result, args, new_pos); |
| 3019 } else { | 3016 } else { |
| 3020 result = factory()->NewCallNew(result, args, new_pos); | 3017 result = factory()->NewCallNew(result, args, new_pos); |
| 3021 } | 3018 } |
| 3022 // The expression can still continue with . or [ after the arguments. | 3019 // The expression can still continue with . or [ after the arguments. |
| 3023 result = this->ParseMemberExpressionContinuation(result, is_async, | 3020 result = this->ParseMemberExpressionContinuation(result, is_async, |
| 3024 classifier, CHECK_OK); | 3021 classifier, CHECK_OK); |
| 3025 return result; | 3022 return result; |
| 3026 } | 3023 } |
| 3027 // NewExpression without arguments. | 3024 // NewExpression without arguments. |
| 3028 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 3025 return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos); |
| 3029 new_pos); | |
| 3030 } | 3026 } |
| 3031 // No 'new' or 'super' keyword. | 3027 // No 'new' or 'super' keyword. |
| 3032 return this->ParseMemberExpression(classifier, is_async, ok); | 3028 return this->ParseMemberExpression(classifier, is_async, ok); |
| 3033 } | 3029 } |
| 3034 | 3030 |
| 3035 template <typename Impl> | 3031 template <typename Impl> |
| 3036 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( | 3032 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( |
| 3037 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 3033 ExpressionClassifier* classifier, bool* is_async, bool* ok) { |
| 3038 // MemberExpression :: | 3034 // MemberExpression :: |
| 3039 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 3035 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3058 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); | 3054 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); |
| 3059 | 3055 |
| 3060 if (!is_generator()) { | 3056 if (!is_generator()) { |
| 3061 // TODO(neis): allow escaping into closures? | 3057 // TODO(neis): allow escaping into closures? |
| 3062 impl()->ReportMessageAt(scanner()->location(), | 3058 impl()->ReportMessageAt(scanner()->location(), |
| 3063 MessageTemplate::kUnexpectedFunctionSent); | 3059 MessageTemplate::kUnexpectedFunctionSent); |
| 3064 *ok = false; | 3060 *ok = false; |
| 3065 return impl()->EmptyExpression(); | 3061 return impl()->EmptyExpression(); |
| 3066 } | 3062 } |
| 3067 | 3063 |
| 3068 return this->FunctionSentExpression(factory(), pos); | 3064 return impl()->FunctionSentExpression(pos); |
| 3069 } | 3065 } |
| 3070 | 3066 |
| 3071 FunctionKind function_kind = Check(Token::MUL) | 3067 FunctionKind function_kind = Check(Token::MUL) |
| 3072 ? FunctionKind::kGeneratorFunction | 3068 ? FunctionKind::kGeneratorFunction |
| 3073 : FunctionKind::kNormalFunction; | 3069 : FunctionKind::kNormalFunction; |
| 3074 IdentifierT name = impl()->EmptyIdentifier(); | 3070 IdentifierT name = impl()->EmptyIdentifier(); |
| 3075 bool is_strict_reserved_name = false; | 3071 bool is_strict_reserved_name = false; |
| 3076 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3072 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3077 FunctionLiteral::FunctionType function_type = | 3073 FunctionLiteral::FunctionType function_type = |
| 3078 FunctionLiteral::kAnonymousExpression; | 3074 FunctionLiteral::kAnonymousExpression; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3105 bool is_new, bool* ok) { | 3101 bool is_new, bool* ok) { |
| 3106 Expect(Token::SUPER, CHECK_OK); | 3102 Expect(Token::SUPER, CHECK_OK); |
| 3107 int pos = position(); | 3103 int pos = position(); |
| 3108 | 3104 |
| 3109 DeclarationScope* scope = GetReceiverScope(); | 3105 DeclarationScope* scope = GetReceiverScope(); |
| 3110 FunctionKind kind = scope->function_kind(); | 3106 FunctionKind kind = scope->function_kind(); |
| 3111 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3107 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
| 3112 IsClassConstructor(kind)) { | 3108 IsClassConstructor(kind)) { |
| 3113 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3109 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
| 3114 scope->RecordSuperPropertyUsage(); | 3110 scope->RecordSuperPropertyUsage(); |
| 3115 return this->NewSuperPropertyReference(factory(), pos); | 3111 return impl()->NewSuperPropertyReference(pos); |
| 3116 } | 3112 } |
| 3117 // new super() is never allowed. | 3113 // new super() is never allowed. |
| 3118 // super() is only allowed in derived constructor | 3114 // super() is only allowed in derived constructor |
| 3119 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3115 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
| 3120 // TODO(rossberg): This might not be the correct FunctionState for the | 3116 // TODO(rossberg): This might not be the correct FunctionState for the |
| 3121 // method here. | 3117 // method here. |
| 3122 return this->NewSuperCallReference(factory(), pos); | 3118 return impl()->NewSuperCallReference(pos); |
| 3123 } | 3119 } |
| 3124 } | 3120 } |
| 3125 | 3121 |
| 3126 impl()->ReportMessageAt(scanner()->location(), | 3122 impl()->ReportMessageAt(scanner()->location(), |
| 3127 MessageTemplate::kUnexpectedSuper); | 3123 MessageTemplate::kUnexpectedSuper); |
| 3128 *ok = false; | 3124 *ok = false; |
| 3129 return impl()->EmptyExpression(); | 3125 return impl()->EmptyExpression(); |
| 3130 } | 3126 } |
| 3131 | 3127 |
| 3132 template <typename Impl> | 3128 template <typename Impl> |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3149 int pos = position(); | 3145 int pos = position(); |
| 3150 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); | 3146 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); |
| 3151 | 3147 |
| 3152 if (!GetReceiverScope()->is_function_scope()) { | 3148 if (!GetReceiverScope()->is_function_scope()) { |
| 3153 impl()->ReportMessageAt(scanner()->location(), | 3149 impl()->ReportMessageAt(scanner()->location(), |
| 3154 MessageTemplate::kUnexpectedNewTarget); | 3150 MessageTemplate::kUnexpectedNewTarget); |
| 3155 *ok = false; | 3151 *ok = false; |
| 3156 return impl()->EmptyExpression(); | 3152 return impl()->EmptyExpression(); |
| 3157 } | 3153 } |
| 3158 | 3154 |
| 3159 return this->NewTargetExpression(pos); | 3155 return impl()->NewTargetExpression(pos); |
| 3160 } | 3156 } |
| 3161 | 3157 |
| 3162 template <typename Impl> | 3158 template <typename Impl> |
| 3163 typename ParserBase<Impl>::ExpressionT | 3159 typename ParserBase<Impl>::ExpressionT |
| 3164 ParserBase<Impl>::ParseMemberExpressionContinuation( | 3160 ParserBase<Impl>::ParseMemberExpressionContinuation( |
| 3165 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | 3161 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
| 3166 bool* ok) { | 3162 bool* ok) { |
| 3167 // Parses this part of MemberExpression: | 3163 // Parses this part of MemberExpression: |
| 3168 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3164 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 3169 while (true) { | 3165 while (true) { |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3425 | 3421 |
| 3426 Expect(Token::ARROW, CHECK_OK); | 3422 Expect(Token::ARROW, CHECK_OK); |
| 3427 | 3423 |
| 3428 if (peek() == Token::LBRACE) { | 3424 if (peek() == Token::LBRACE) { |
| 3429 // Multiple statement body | 3425 // Multiple statement body |
| 3430 Consume(Token::LBRACE); | 3426 Consume(Token::LBRACE); |
| 3431 DCHECK_EQ(scope(), formal_parameters.scope); | 3427 DCHECK_EQ(scope(), formal_parameters.scope); |
| 3432 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | 3428 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
| 3433 formal_parameters.scope->AllowsLazyParsing()); | 3429 formal_parameters.scope->AllowsLazyParsing()); |
| 3434 if (is_lazily_parsed) { | 3430 if (is_lazily_parsed) { |
| 3435 body = this->NewStatementList(0, zone()); | 3431 body = impl()->NewStatementList(0); |
| 3436 impl()->SkipLazyFunctionBody(&materialized_literal_count, | 3432 impl()->SkipLazyFunctionBody(&materialized_literal_count, |
| 3437 &expected_property_count, CHECK_OK); | 3433 &expected_property_count, CHECK_OK); |
| 3438 if (formal_parameters.materialized_literals_count > 0) { | 3434 if (formal_parameters.materialized_literals_count > 0) { |
| 3439 materialized_literal_count += | 3435 materialized_literal_count += |
| 3440 formal_parameters.materialized_literals_count; | 3436 formal_parameters.materialized_literals_count; |
| 3441 } | 3437 } |
| 3442 } else { | 3438 } else { |
| 3443 body = impl()->ParseEagerFunctionBody( | 3439 body = impl()->ParseEagerFunctionBody( |
| 3444 impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters, | 3440 impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters, |
| 3445 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3441 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
| 3446 materialized_literal_count = | 3442 materialized_literal_count = |
| 3447 function_state.materialized_literal_count(); | 3443 function_state.materialized_literal_count(); |
| 3448 expected_property_count = function_state.expected_property_count(); | 3444 expected_property_count = function_state.expected_property_count(); |
| 3449 } | 3445 } |
| 3450 } else { | 3446 } else { |
| 3451 // Single-expression body | 3447 // Single-expression body |
| 3452 int pos = position(); | 3448 int pos = position(); |
| 3453 DCHECK(ReturnExprContext::kInsideValidBlock == | 3449 DCHECK(ReturnExprContext::kInsideValidBlock == |
| 3454 function_state_->return_expr_context()); | 3450 function_state_->return_expr_context()); |
| 3455 ReturnExprScope allow_tail_calls( | 3451 ReturnExprScope allow_tail_calls( |
| 3456 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 3452 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
| 3457 body = this->NewStatementList(1, zone()); | 3453 body = impl()->NewStatementList(1); |
| 3458 this->AddParameterInitializationBlock(formal_parameters, body, is_async, | 3454 this->AddParameterInitializationBlock(formal_parameters, body, is_async, |
| 3459 CHECK_OK); | 3455 CHECK_OK); |
| 3460 ExpressionClassifier classifier(this); | 3456 ExpressionClassifier classifier(this); |
| 3461 if (is_async) { | 3457 if (is_async) { |
| 3462 impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN, | 3458 impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN, |
| 3463 &classifier, pos, CHECK_OK); | 3459 &classifier, pos, CHECK_OK); |
| 3464 impl()->RewriteNonPattern(&classifier, CHECK_OK); | 3460 impl()->RewriteNonPattern(&classifier, CHECK_OK); |
| 3465 } else { | 3461 } else { |
| 3466 ExpressionT expression = | 3462 ExpressionT expression = |
| 3467 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 3463 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3716 has_seen_constructor_ = true; | 3712 has_seen_constructor_ = true; |
| 3717 return; | 3713 return; |
| 3718 } | 3714 } |
| 3719 } | 3715 } |
| 3720 | 3716 |
| 3721 | 3717 |
| 3722 } // namespace internal | 3718 } // namespace internal |
| 3723 } // namespace v8 | 3719 } // namespace v8 |
| 3724 | 3720 |
| 3725 #endif // V8_PARSING_PARSER_BASE_H | 3721 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |