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