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 |