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 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 } | 1268 } |
1269 | 1269 |
1270 switch (peek()) { | 1270 switch (peek()) { |
1271 case Token::FUNCTION: | 1271 case Token::FUNCTION: |
1272 return ParseFunctionDeclaration(NULL, ok); | 1272 return ParseFunctionDeclaration(NULL, ok); |
1273 case Token::CLASS: | 1273 case Token::CLASS: |
1274 if (scope_->class_declaration_group_start() < 0) { | 1274 if (scope_->class_declaration_group_start() < 0) { |
1275 scope_->set_class_declaration_group_start( | 1275 scope_->set_class_declaration_group_start( |
1276 scanner()->peek_location().beg_pos); | 1276 scanner()->peek_location().beg_pos); |
1277 } | 1277 } |
| 1278 Consume(Token::CLASS); |
1278 return ParseClassDeclaration(NULL, ok); | 1279 return ParseClassDeclaration(NULL, ok); |
1279 case Token::CONST: | 1280 case Token::CONST: |
1280 if (allow_const()) { | 1281 if (allow_const()) { |
1281 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1282 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1282 } | 1283 } |
1283 break; | 1284 break; |
1284 case Token::VAR: | 1285 case Token::VAR: |
1285 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1286 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1286 case Token::LET: | 1287 case Token::LET: |
1287 if (IsNextLetKeyword()) { | 1288 if (IsNextLetKeyword()) { |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 | 1553 |
1553 Statement* Parser::ParseExportDefault(bool* ok) { | 1554 Statement* Parser::ParseExportDefault(bool* ok) { |
1554 // Supports the following productions, starting after the 'default' token: | 1555 // Supports the following productions, starting after the 'default' token: |
1555 // 'export' 'default' FunctionDeclaration | 1556 // 'export' 'default' FunctionDeclaration |
1556 // 'export' 'default' ClassDeclaration | 1557 // 'export' 'default' ClassDeclaration |
1557 // 'export' 'default' AssignmentExpression[In] ';' | 1558 // 'export' 'default' AssignmentExpression[In] ';' |
1558 | 1559 |
1559 Expect(Token::DEFAULT, CHECK_OK); | 1560 Expect(Token::DEFAULT, CHECK_OK); |
1560 Scanner::Location default_loc = scanner()->location(); | 1561 Scanner::Location default_loc = scanner()->location(); |
1561 | 1562 |
| 1563 const AstRawString* default_string = ast_value_factory()->default_string(); |
1562 ZoneList<const AstRawString*> names(1, zone()); | 1564 ZoneList<const AstRawString*> names(1, zone()); |
1563 Statement* result = NULL; | 1565 Statement* result = nullptr; |
| 1566 Expression* default_export = nullptr; |
1564 switch (peek()) { | 1567 switch (peek()) { |
1565 case Token::FUNCTION: | 1568 case Token::FUNCTION: { |
1566 // TODO(ES6): Support parsing anonymous function declarations here. | 1569 Consume(Token::FUNCTION); |
1567 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1570 int pos = position(); |
| 1571 bool is_generator = Check(Token::MUL); |
| 1572 if (peek() == Token::LPAREN) { |
| 1573 // FunctionDeclaration[+Default] :: |
| 1574 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' |
| 1575 // |
| 1576 // GeneratorDeclaration[+Default] :: |
| 1577 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' |
| 1578 default_export = ParseFunctionLiteral( |
| 1579 default_string, Scanner::Location::invalid(), |
| 1580 kSkipFunctionNameCheck, |
| 1581 is_generator ? FunctionKind::kGeneratorFunction |
| 1582 : FunctionKind::kNormalFunction, |
| 1583 pos, FunctionLiteral::kDeclaration, FunctionLiteral::kNormalArity, |
| 1584 language_mode(), CHECK_OK); |
| 1585 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1586 } else { |
| 1587 result = ParseFunctionDeclaration(pos, is_generator, &names, CHECK_OK); |
| 1588 } |
1568 break; | 1589 break; |
| 1590 } |
1569 | 1591 |
1570 case Token::CLASS: | 1592 case Token::CLASS: |
1571 // TODO(ES6): Support parsing anonymous class declarations here. | 1593 Consume(Token::CLASS); |
1572 result = ParseClassDeclaration(&names, CHECK_OK); | 1594 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { |
| 1595 // ClassDeclaration[+Default] :: |
| 1596 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' |
| 1597 default_export = |
| 1598 ParseClassLiteral(default_string, Scanner::Location::invalid(), |
| 1599 false, position(), CHECK_OK); |
| 1600 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1601 } else { |
| 1602 result = ParseClassDeclaration(&names, CHECK_OK); |
| 1603 } |
1573 break; | 1604 break; |
1574 | 1605 |
1575 default: { | 1606 default: { |
1576 int pos = peek_position(); | 1607 int pos = peek_position(); |
1577 ExpressionClassifier classifier; | 1608 ExpressionClassifier classifier; |
1578 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); | 1609 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); |
1579 expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK); | 1610 expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK); |
1580 | 1611 |
1581 ExpectSemicolon(CHECK_OK); | 1612 ExpectSemicolon(CHECK_OK); |
1582 result = factory()->NewExpressionStatement(expr, pos); | 1613 result = factory()->NewExpressionStatement(expr, pos); |
1583 break; | 1614 break; |
1584 } | 1615 } |
1585 } | 1616 } |
1586 | 1617 |
1587 const AstRawString* default_string = ast_value_factory()->default_string(); | |
1588 | |
1589 DCHECK_LE(names.length(), 1); | 1618 DCHECK_LE(names.length(), 1); |
1590 if (names.length() == 1) { | 1619 if (names.length() == 1) { |
1591 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok); | 1620 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok); |
1592 if (!*ok) { | 1621 if (!*ok) { |
1593 ParserTraits::ReportMessageAt( | 1622 ParserTraits::ReportMessageAt( |
1594 default_loc, MessageTemplate::kDuplicateExport, default_string); | 1623 default_loc, MessageTemplate::kDuplicateExport, default_string); |
1595 return NULL; | 1624 return nullptr; |
1596 } | 1625 } |
1597 } else { | 1626 } else { |
1598 // TODO(ES6): Assign result to a const binding with the name "*default*" | 1627 // TODO(ES6): Assign result to a const binding with the name "*default*" |
1599 // and add an export entry with "*default*" as the local name. | 1628 // and add an export entry with "*default*" as the local name. |
| 1629 USE(default_export); |
1600 } | 1630 } |
1601 | 1631 |
1602 return result; | 1632 return result; |
1603 } | 1633 } |
1604 | 1634 |
1605 | 1635 |
1606 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1636 Statement* Parser::ParseExportDeclaration(bool* ok) { |
1607 // ExportDeclaration: | 1637 // ExportDeclaration: |
1608 // 'export' '*' 'from' ModuleSpecifier ';' | 1638 // 'export' '*' 'from' ModuleSpecifier ';' |
1609 // 'export' ExportClause ('from' ModuleSpecifier)? ';' | 1639 // 'export' ExportClause ('from' ModuleSpecifier)? ';' |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 } | 1710 } |
1681 } | 1711 } |
1682 return factory()->NewEmptyStatement(pos); | 1712 return factory()->NewEmptyStatement(pos); |
1683 } | 1713 } |
1684 | 1714 |
1685 case Token::FUNCTION: | 1715 case Token::FUNCTION: |
1686 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1716 result = ParseFunctionDeclaration(&names, CHECK_OK); |
1687 break; | 1717 break; |
1688 | 1718 |
1689 case Token::CLASS: | 1719 case Token::CLASS: |
| 1720 Consume(Token::CLASS); |
1690 result = ParseClassDeclaration(&names, CHECK_OK); | 1721 result = ParseClassDeclaration(&names, CHECK_OK); |
1691 break; | 1722 break; |
1692 | 1723 |
1693 case Token::VAR: | 1724 case Token::VAR: |
1694 case Token::LET: | 1725 case Token::LET: |
1695 case Token::CONST: | 1726 case Token::CONST: |
1696 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); | 1727 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); |
1697 break; | 1728 break; |
1698 | 1729 |
1699 default: | 1730 default: |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2083 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 2114 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
2084 name, extension_, RelocInfo::kNoPosition); | 2115 name, extension_, RelocInfo::kNoPosition); |
2085 return factory()->NewExpressionStatement( | 2116 return factory()->NewExpressionStatement( |
2086 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), | 2117 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), |
2087 pos); | 2118 pos); |
2088 } | 2119 } |
2089 | 2120 |
2090 | 2121 |
2091 Statement* Parser::ParseFunctionDeclaration( | 2122 Statement* Parser::ParseFunctionDeclaration( |
2092 ZoneList<const AstRawString*>* names, bool* ok) { | 2123 ZoneList<const AstRawString*>* names, bool* ok) { |
2093 // FunctionDeclaration :: | |
2094 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | |
2095 // GeneratorDeclaration :: | |
2096 // 'function' '*' Identifier '(' FormalParameterListopt ')' | |
2097 // '{' FunctionBody '}' | |
2098 Expect(Token::FUNCTION, CHECK_OK); | 2124 Expect(Token::FUNCTION, CHECK_OK); |
2099 int pos = position(); | 2125 int pos = position(); |
2100 bool is_generator = Check(Token::MUL); | 2126 bool is_generator = Check(Token::MUL); |
| 2127 return ParseFunctionDeclaration(pos, is_generator, names, ok); |
| 2128 } |
| 2129 |
| 2130 |
| 2131 Statement* Parser::ParseFunctionDeclaration( |
| 2132 int pos, bool is_generator, ZoneList<const AstRawString*>* names, |
| 2133 bool* ok) { |
| 2134 // FunctionDeclaration :: |
| 2135 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 2136 // GeneratorDeclaration :: |
| 2137 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 2138 // |
| 2139 // 'function' and '*' (if present) have been consumed by the caller. |
2101 bool is_strict_reserved = false; | 2140 bool is_strict_reserved = false; |
2102 const AstRawString* name = ParseIdentifierOrStrictReservedWord( | 2141 const AstRawString* name = ParseIdentifierOrStrictReservedWord( |
2103 &is_strict_reserved, CHECK_OK); | 2142 &is_strict_reserved, CHECK_OK); |
2104 | 2143 |
2105 FuncNameInferrer::State fni_state(fni_); | 2144 FuncNameInferrer::State fni_state(fni_); |
2106 if (fni_ != NULL) fni_->PushEnclosingName(name); | 2145 if (fni_ != NULL) fni_->PushEnclosingName(name); |
2107 FunctionLiteral* fun = ParseFunctionLiteral( | 2146 FunctionLiteral* fun = ParseFunctionLiteral( |
2108 name, scanner()->location(), | 2147 name, scanner()->location(), |
2109 is_strict_reserved ? kFunctionNameIsStrictReserved | 2148 is_strict_reserved ? kFunctionNameIsStrictReserved |
2110 : kFunctionNameValidityUnknown, | 2149 : kFunctionNameValidityUnknown, |
(...skipping 30 matching lines...) Expand all Loading... |
2141 } | 2180 } |
2142 return empty; | 2181 return empty; |
2143 } | 2182 } |
2144 | 2183 |
2145 | 2184 |
2146 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, | 2185 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, |
2147 bool* ok) { | 2186 bool* ok) { |
2148 // ClassDeclaration :: | 2187 // ClassDeclaration :: |
2149 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' | 2188 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' |
2150 // | 2189 // |
| 2190 // 'class' is expected to be consumed by the caller. |
| 2191 // |
2151 // A ClassDeclaration | 2192 // A ClassDeclaration |
2152 // | 2193 // |
2153 // class C { ... } | 2194 // class C { ... } |
2154 // | 2195 // |
2155 // has the same semantics as: | 2196 // has the same semantics as: |
2156 // | 2197 // |
2157 // let C = class C { ... }; | 2198 // let C = class C { ... }; |
2158 // | 2199 // |
2159 // so rewrite it as such. | 2200 // so rewrite it as such. |
2160 | 2201 |
2161 Expect(Token::CLASS, CHECK_OK); | |
2162 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2202 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2163 ReportMessage(MessageTemplate::kSloppyLexical); | 2203 ReportMessage(MessageTemplate::kSloppyLexical); |
2164 *ok = false; | 2204 *ok = false; |
2165 return NULL; | 2205 return NULL; |
2166 } | 2206 } |
2167 | 2207 |
2168 int pos = position(); | 2208 int pos = position(); |
2169 bool is_strict_reserved = false; | 2209 bool is_strict_reserved = false; |
2170 const AstRawString* name = | 2210 const AstRawString* name = |
2171 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 2211 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
(...skipping 3526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5698 auto class_literal = value->AsClassLiteral(); | 5738 auto class_literal = value->AsClassLiteral(); |
5699 if (class_literal->raw_name() == nullptr) { | 5739 if (class_literal->raw_name() == nullptr) { |
5700 class_literal->set_raw_name(name); | 5740 class_literal->set_raw_name(name); |
5701 } | 5741 } |
5702 } | 5742 } |
5703 } | 5743 } |
5704 | 5744 |
5705 | 5745 |
5706 } // namespace internal | 5746 } // namespace internal |
5707 } // namespace v8 | 5747 } // namespace v8 |
OLD | NEW |