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 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 | 1278 |
1279 | 1279 |
1280 Statement* Parser::ParseStatementListItem(bool* ok) { | 1280 Statement* Parser::ParseStatementListItem(bool* ok) { |
1281 // (Ecma 262 6th Edition, 13.1): | 1281 // (Ecma 262 6th Edition, 13.1): |
1282 // StatementListItem: | 1282 // StatementListItem: |
1283 // Statement | 1283 // Statement |
1284 // Declaration | 1284 // Declaration |
1285 const Token::Value peeked = peek(); | 1285 const Token::Value peeked = peek(); |
1286 switch (peeked) { | 1286 switch (peeked) { |
1287 case Token::FUNCTION: | 1287 case Token::FUNCTION: |
1288 return ParseHoistableDeclaration(NULL, ok); | 1288 return ParseHoistableDeclaration(NULL, false, ok); |
1289 case Token::CLASS: | 1289 case Token::CLASS: |
1290 Consume(Token::CLASS); | 1290 Consume(Token::CLASS); |
1291 return ParseClassDeclaration(NULL, ok); | 1291 return ParseClassDeclaration(NULL, false, ok); |
1292 case Token::CONST: | 1292 case Token::CONST: |
1293 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1293 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1294 case Token::VAR: | 1294 case Token::VAR: |
1295 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1295 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1296 case Token::LET: | 1296 case Token::LET: |
1297 if (IsNextLetKeyword()) { | 1297 if (IsNextLetKeyword()) { |
1298 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1298 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1299 } | 1299 } |
1300 break; | 1300 break; |
1301 case Token::ASYNC: | 1301 case Token::ASYNC: |
1302 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && | 1302 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && |
1303 !scanner()->HasAnyLineTerminatorAfterNext()) { | 1303 !scanner()->HasAnyLineTerminatorAfterNext()) { |
1304 Consume(Token::ASYNC); | 1304 Consume(Token::ASYNC); |
1305 return ParseAsyncFunctionDeclaration(NULL, ok); | 1305 return ParseAsyncFunctionDeclaration(NULL, false, ok); |
1306 } | 1306 } |
1307 /* falls through */ | 1307 /* falls through */ |
1308 default: | 1308 default: |
1309 break; | 1309 break; |
1310 } | 1310 } |
1311 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); | 1311 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); |
1312 } | 1312 } |
1313 | 1313 |
1314 | 1314 |
1315 Statement* Parser::ParseModuleItem(bool* ok) { | 1315 Statement* Parser::ParseModuleItem(bool* ok) { |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1569 // 'export' 'default' AssignmentExpression[In] ';' | 1569 // 'export' 'default' AssignmentExpression[In] ';' |
1570 | 1570 |
1571 Expect(Token::DEFAULT, CHECK_OK); | 1571 Expect(Token::DEFAULT, CHECK_OK); |
1572 Scanner::Location default_loc = scanner()->location(); | 1572 Scanner::Location default_loc = scanner()->location(); |
1573 | 1573 |
1574 const AstRawString* default_string = ast_value_factory()->default_string(); | 1574 const AstRawString* default_string = ast_value_factory()->default_string(); |
1575 ZoneList<const AstRawString*> names(1, zone()); | 1575 ZoneList<const AstRawString*> names(1, zone()); |
1576 Statement* result = nullptr; | 1576 Statement* result = nullptr; |
1577 Expression* default_export = nullptr; | 1577 Expression* default_export = nullptr; |
1578 switch (peek()) { | 1578 switch (peek()) { |
1579 case Token::FUNCTION: { | 1579 case Token::FUNCTION: |
1580 Consume(Token::FUNCTION); | 1580 result = ParseHoistableDeclaration(&names, true, CHECK_OK); |
1581 int pos = position(); | |
1582 bool is_generator = Check(Token::MUL); | |
1583 if (peek() == Token::LPAREN) { | |
1584 // FunctionDeclaration[+Default] :: | |
1585 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' | |
1586 // | |
1587 // GeneratorDeclaration[+Default] :: | |
1588 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' | |
1589 default_export = ParseFunctionLiteral( | |
1590 default_string, Scanner::Location::invalid(), | |
1591 kSkipFunctionNameCheck, | |
1592 is_generator ? FunctionKind::kGeneratorFunction | |
1593 : FunctionKind::kNormalFunction, | |
1594 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | |
1595 result = factory()->NewEmptyStatement(kNoSourcePosition); | |
1596 } else { | |
1597 result = ParseHoistableDeclaration( | |
1598 pos, is_generator ? ParseFunctionFlags::kIsGenerator | |
1599 : ParseFunctionFlags::kIsNormal, | |
1600 &names, CHECK_OK); | |
1601 } | |
1602 break; | 1581 break; |
1603 } | |
1604 | 1582 |
1605 case Token::CLASS: | 1583 case Token::CLASS: |
1606 Consume(Token::CLASS); | 1584 Consume(Token::CLASS); |
1607 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { | 1585 result = ParseClassDeclaration(&names, true, CHECK_OK); |
1608 // ClassDeclaration[+Default] :: | |
1609 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' | |
1610 default_export = ParseClassLiteral(nullptr, default_string, | |
1611 Scanner::Location::invalid(), false, | |
1612 position(), CHECK_OK); | |
1613 result = factory()->NewEmptyStatement(kNoSourcePosition); | |
1614 } else { | |
1615 result = ParseClassDeclaration(&names, CHECK_OK); | |
1616 } | |
1617 break; | 1586 break; |
1618 | 1587 |
1619 case Token::ASYNC: | 1588 case Token::ASYNC: |
1620 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && | 1589 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && |
1621 !scanner()->HasAnyLineTerminatorAfterNext()) { | 1590 !scanner()->HasAnyLineTerminatorAfterNext()) { |
1622 Consume(Token::ASYNC); | 1591 Consume(Token::ASYNC); |
1623 Consume(Token::FUNCTION); | 1592 result = ParseAsyncFunctionDeclaration(&names, true, CHECK_OK); |
1624 int pos = position(); | |
1625 if (peek() == Token::LPAREN) { | |
1626 // AsyncFunctionDeclaration[+Default] :: | |
1627 // async [no LineTerminator here] function ( FormalParameters ) { | |
1628 // AsyncFunctionBody | |
1629 // } | |
1630 default_export = ParseFunctionLiteral( | |
1631 default_string, Scanner::Location::invalid(), | |
1632 kSkipFunctionNameCheck, FunctionKind::kAsyncFunction, pos, | |
1633 FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | |
1634 result = factory()->NewEmptyStatement(kNoSourcePosition); | |
1635 } else { | |
1636 result = ParseHoistableDeclaration(pos, ParseFunctionFlags::kIsAsync, | |
1637 &names, CHECK_OK); | |
1638 } | |
1639 break; | 1593 break; |
1640 } | 1594 } |
1641 /* falls through */ | 1595 /* falls through */ |
1642 | 1596 |
1643 default: { | 1597 default: { |
1644 int pos = peek_position(); | 1598 int pos = peek_position(); |
1645 ExpressionClassifier classifier(this); | 1599 ExpressionClassifier classifier(this); |
1646 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); | 1600 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); |
1647 RewriteNonPattern(&classifier, CHECK_OK); | 1601 RewriteNonPattern(&classifier, CHECK_OK); |
1648 | 1602 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1743 scope_->module()->AddModuleRequest(indirect_export_module_specifier, | 1697 scope_->module()->AddModuleRequest(indirect_export_module_specifier, |
1744 zone()); | 1698 zone()); |
1745 for (int i = 0; i < length; ++i) { | 1699 for (int i = 0; i < length; ++i) { |
1746 // TODO(ES6): scope_->module()->AddIndirectExport(...);( | 1700 // TODO(ES6): scope_->module()->AddIndirectExport(...);( |
1747 } | 1701 } |
1748 } | 1702 } |
1749 return factory()->NewEmptyStatement(pos); | 1703 return factory()->NewEmptyStatement(pos); |
1750 } | 1704 } |
1751 | 1705 |
1752 case Token::FUNCTION: | 1706 case Token::FUNCTION: |
1753 result = ParseHoistableDeclaration(&names, CHECK_OK); | 1707 result = ParseHoistableDeclaration(&names, false, CHECK_OK); |
1754 break; | 1708 break; |
1755 | 1709 |
1756 case Token::CLASS: | 1710 case Token::CLASS: |
1757 Consume(Token::CLASS); | 1711 Consume(Token::CLASS); |
1758 result = ParseClassDeclaration(&names, CHECK_OK); | 1712 result = ParseClassDeclaration(&names, false, CHECK_OK); |
1759 break; | 1713 break; |
1760 | 1714 |
1761 case Token::VAR: | 1715 case Token::VAR: |
1762 case Token::LET: | 1716 case Token::LET: |
1763 case Token::CONST: | 1717 case Token::CONST: |
1764 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); | 1718 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); |
1765 break; | 1719 break; |
1766 | 1720 |
1767 case Token::ASYNC: | 1721 case Token::ASYNC: |
1768 if (allow_harmony_async_await()) { | 1722 if (allow_harmony_async_await()) { |
1769 Consume(Token::ASYNC); | 1723 Consume(Token::ASYNC); |
1770 result = ParseAsyncFunctionDeclaration(&names, CHECK_OK); | 1724 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); |
1771 break; | 1725 break; |
1772 } | 1726 } |
1773 /* falls through */ | 1727 /* falls through */ |
1774 | 1728 |
1775 default: | 1729 default: |
1776 *ok = false; | 1730 *ok = false; |
1777 ReportUnexpectedToken(scanner()->current_token()); | 1731 ReportUnexpectedToken(scanner()->current_token()); |
1778 return NULL; | 1732 return NULL; |
1779 } | 1733 } |
1780 | 1734 |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2132 Declaration* declaration = | 2086 Declaration* declaration = |
2133 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos); | 2087 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos); |
2134 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2088 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
2135 NativeFunctionLiteral* lit = | 2089 NativeFunctionLiteral* lit = |
2136 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); | 2090 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); |
2137 return factory()->NewExpressionStatement( | 2091 return factory()->NewExpressionStatement( |
2138 factory()->NewAssignment(Token::INIT, proxy, lit, kNoSourcePosition), | 2092 factory()->NewAssignment(Token::INIT, proxy, lit, kNoSourcePosition), |
2139 pos); | 2093 pos); |
2140 } | 2094 } |
2141 | 2095 |
2142 | |
2143 Statement* Parser::ParseHoistableDeclaration( | 2096 Statement* Parser::ParseHoistableDeclaration( |
2144 ZoneList<const AstRawString*>* names, bool* ok) { | 2097 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { |
2145 Expect(Token::FUNCTION, CHECK_OK); | 2098 Expect(Token::FUNCTION, CHECK_OK); |
2146 int pos = position(); | 2099 int pos = position(); |
2147 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; | 2100 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
2148 if (Check(Token::MUL)) { | 2101 if (Check(Token::MUL)) { |
2149 flags |= ParseFunctionFlags::kIsGenerator; | 2102 flags |= ParseFunctionFlags::kIsGenerator; |
2150 } | 2103 } |
2151 return ParseHoistableDeclaration(pos, flags, names, ok); | 2104 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); |
2152 } | 2105 } |
2153 | 2106 |
2154 Statement* Parser::ParseAsyncFunctionDeclaration( | 2107 Statement* Parser::ParseAsyncFunctionDeclaration( |
2155 ZoneList<const AstRawString*>* names, bool* ok) { | 2108 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { |
2156 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); | 2109 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
2157 int pos = position(); | 2110 int pos = position(); |
2158 if (scanner()->HasAnyLineTerminatorBeforeNext()) { | 2111 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
2159 *ok = false; | 2112 *ok = false; |
2160 ReportUnexpectedToken(scanner()->current_token()); | 2113 ReportUnexpectedToken(scanner()->current_token()); |
2161 return nullptr; | 2114 return nullptr; |
2162 } | 2115 } |
2163 Expect(Token::FUNCTION, CHECK_OK); | 2116 Expect(Token::FUNCTION, CHECK_OK); |
2164 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; | 2117 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; |
2165 return ParseHoistableDeclaration(pos, flags, names, ok); | 2118 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); |
2166 } | 2119 } |
2167 | 2120 |
2168 Statement* Parser::ParseHoistableDeclaration( | 2121 Statement* Parser::ParseHoistableDeclaration( |
2169 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, | 2122 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, |
2170 bool* ok) { | 2123 bool default_export, bool* ok) { |
2171 // FunctionDeclaration :: | 2124 // FunctionDeclaration :: |
2172 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2125 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 2126 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' |
2173 // GeneratorDeclaration :: | 2127 // GeneratorDeclaration :: |
2174 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2128 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 2129 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' |
| 2130 // |
| 2131 // The anonymous forms are allowed iff [default_export] is true. |
2175 // | 2132 // |
2176 // 'function' and '*' (if present) have been consumed by the caller. | 2133 // 'function' and '*' (if present) have been consumed by the caller. |
| 2134 |
2177 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; | 2135 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; |
2178 const bool is_async = flags & ParseFunctionFlags::kIsAsync; | 2136 const bool is_async = flags & ParseFunctionFlags::kIsAsync; |
2179 DCHECK(!is_generator || !is_async); | 2137 DCHECK(!is_generator || !is_async); |
2180 | 2138 |
2181 bool is_strict_reserved = false; | 2139 const AstRawString* name; |
2182 const AstRawString* name = ParseIdentifierOrStrictReservedWord( | 2140 FunctionNameValidity name_validity; |
2183 &is_strict_reserved, CHECK_OK); | 2141 const AstRawString* variable_name; |
| 2142 if (default_export && peek() == Token::LPAREN) { |
| 2143 name = ast_value_factory()->default_string(); |
| 2144 name_validity = kSkipFunctionNameCheck; |
| 2145 variable_name = ast_value_factory()->star_default_star_string(); |
| 2146 } else { |
| 2147 bool is_strict_reserved; |
| 2148 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 2149 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved |
| 2150 : kFunctionNameValidityUnknown; |
| 2151 variable_name = name; |
| 2152 } |
2184 | 2153 |
2185 if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) { | 2154 if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) { |
2186 ReportMessageAt(scanner()->location(), | 2155 ReportMessageAt(scanner()->location(), |
2187 MessageTemplate::kAwaitBindingIdentifier); | 2156 MessageTemplate::kAwaitBindingIdentifier); |
2188 *ok = false; | 2157 *ok = false; |
2189 return nullptr; | 2158 return nullptr; |
2190 } | 2159 } |
2191 | 2160 |
2192 FuncNameInferrer::State fni_state(fni_); | 2161 FuncNameInferrer::State fni_state(fni_); |
2193 if (fni_ != NULL) fni_->PushEnclosingName(name); | 2162 if (fni_ != NULL) fni_->PushEnclosingName(name); |
2194 FunctionLiteral* fun = ParseFunctionLiteral( | 2163 FunctionLiteral* fun = ParseFunctionLiteral( |
2195 name, scanner()->location(), | 2164 name, scanner()->location(), name_validity, |
2196 is_strict_reserved ? kFunctionNameIsStrictReserved | |
2197 : kFunctionNameValidityUnknown, | |
2198 is_generator ? FunctionKind::kGeneratorFunction | 2165 is_generator ? FunctionKind::kGeneratorFunction |
2199 : is_async ? FunctionKind::kAsyncFunction | 2166 : is_async ? FunctionKind::kAsyncFunction |
2200 : FunctionKind::kNormalFunction, | 2167 : FunctionKind::kNormalFunction, |
2201 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 2168 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
2202 | 2169 |
2203 // Even if we're not at the top-level of the global or a function | 2170 // Even if we're not at the top-level of the global or a function |
2204 // scope, we treat it as such and introduce the function with its | 2171 // scope, we treat it as such and introduce the function with its |
2205 // initial value upon entering the corresponding scope. | 2172 // initial value upon entering the corresponding scope. |
2206 // In ES6, a function behaves as a lexical binding, except in | 2173 // In ES6, a function behaves as a lexical binding, except in |
2207 // a script scope, or the initial scope of eval or another function. | 2174 // a script scope, or the initial scope of eval or another function. |
2208 VariableMode mode = | 2175 VariableMode mode = |
2209 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET | 2176 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET |
2210 : VAR; | 2177 : VAR; |
2211 VariableProxy* proxy = NewUnresolved(name, mode); | 2178 VariableProxy* proxy = NewUnresolved(variable_name, mode); |
2212 Declaration* declaration = | 2179 Declaration* declaration = |
2213 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 2180 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
2214 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2181 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
2215 if (names) names->Add(name, zone()); | 2182 if (names) names->Add(variable_name, zone()); |
2216 EmptyStatement* empty = factory()->NewEmptyStatement(kNoSourcePosition); | 2183 EmptyStatement* empty = factory()->NewEmptyStatement(kNoSourcePosition); |
2217 // Async functions don't undergo sloppy mode block scoped hoisting, and don't | 2184 // Async functions don't undergo sloppy mode block scoped hoisting, and don't |
2218 // allow duplicates in a block. Both are represented by the | 2185 // allow duplicates in a block. Both are represented by the |
2219 // sloppy_block_function_map. Don't add them to the map for async functions. | 2186 // sloppy_block_function_map. Don't add them to the map for async functions. |
2220 // Generators are also supposed to be prohibited; currently doing this behind | 2187 // Generators are also supposed to be prohibited; currently doing this behind |
2221 // a flag and UseCounting violations to assess web compatibility. | 2188 // a flag and UseCounting violations to assess web compatibility. |
2222 if (is_sloppy(language_mode()) && !scope_->is_declaration_scope() && | 2189 if (is_sloppy(language_mode()) && !scope_->is_declaration_scope() && |
2223 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { | 2190 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { |
2224 SloppyBlockFunctionStatement* delegate = | 2191 SloppyBlockFunctionStatement* delegate = |
2225 factory()->NewSloppyBlockFunctionStatement(empty, scope_); | 2192 factory()->NewSloppyBlockFunctionStatement(empty, scope_); |
2226 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name, | 2193 scope_->DeclarationScope()->sloppy_block_function_map()->Declare( |
2227 delegate); | 2194 variable_name, delegate); |
2228 return delegate; | 2195 return delegate; |
2229 } | 2196 } |
2230 return empty; | 2197 return empty; |
2231 } | 2198 } |
2232 | 2199 |
2233 | |
2234 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, | 2200 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, |
2235 bool* ok) { | 2201 bool default_export, bool* ok) { |
2236 // ClassDeclaration :: | 2202 // ClassDeclaration :: |
2237 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' | 2203 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' |
| 2204 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' |
| 2205 // |
| 2206 // The anonymous form is allowed iff [default_export] is true. |
2238 // | 2207 // |
2239 // 'class' is expected to be consumed by the caller. | 2208 // 'class' is expected to be consumed by the caller. |
2240 // | 2209 // |
2241 // A ClassDeclaration | 2210 // A ClassDeclaration |
2242 // | 2211 // |
2243 // class C { ... } | 2212 // class C { ... } |
2244 // | 2213 // |
2245 // has the same semantics as: | 2214 // has the same semantics as: |
2246 // | 2215 // |
2247 // let C = class C { ... }; | 2216 // let C = class C { ... }; |
2248 // | 2217 // |
2249 // so rewrite it as such. | 2218 // so rewrite it as such. |
2250 | 2219 |
2251 int pos = position(); | 2220 int pos = position(); |
2252 bool is_strict_reserved = false; | 2221 |
2253 const AstRawString* name = | 2222 const AstRawString* name; |
2254 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 2223 bool is_strict_reserved; |
| 2224 const AstRawString* variable_name; |
| 2225 if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) { |
| 2226 name = ast_value_factory()->default_string(); |
| 2227 is_strict_reserved = false; |
| 2228 variable_name = ast_value_factory()->star_default_star_string(); |
| 2229 } else { |
| 2230 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 2231 variable_name = name; |
| 2232 } |
| 2233 |
2255 ClassLiteral* value = ParseClassLiteral(nullptr, name, scanner()->location(), | 2234 ClassLiteral* value = ParseClassLiteral(nullptr, name, scanner()->location(), |
2256 is_strict_reserved, pos, CHECK_OK); | 2235 is_strict_reserved, pos, CHECK_OK); |
2257 | 2236 |
2258 VariableProxy* proxy = NewUnresolved(name, LET); | 2237 VariableProxy* proxy = NewUnresolved(variable_name, LET); |
2259 Declaration* declaration = | 2238 Declaration* declaration = |
2260 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); | 2239 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); |
2261 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2240 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
2262 proxy->var()->set_initializer_position(position()); | 2241 proxy->var()->set_initializer_position(position()); |
2263 Assignment* assignment = | 2242 Assignment* assignment = |
2264 factory()->NewAssignment(Token::INIT, proxy, value, pos); | 2243 factory()->NewAssignment(Token::INIT, proxy, value, pos); |
2265 Statement* assignment_statement = | 2244 Statement* assignment_statement = |
2266 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 2245 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
2267 if (names) names->Add(name, zone()); | 2246 if (names) names->Add(variable_name, zone()); |
2268 return assignment_statement; | 2247 return assignment_statement; |
2269 } | 2248 } |
2270 | 2249 |
2271 | 2250 |
2272 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, | 2251 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, |
2273 bool finalize_block_scope, bool* ok) { | 2252 bool finalize_block_scope, bool* ok) { |
2274 // The harmony mode uses block elements instead of statements. | 2253 // The harmony mode uses block elements instead of statements. |
2275 // | 2254 // |
2276 // Block :: | 2255 // Block :: |
2277 // '{' StatementList '}' | 2256 // '{' StatementList '}' |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2517 if (Check(Token::MUL)) { | 2496 if (Check(Token::MUL)) { |
2518 flags |= ParseFunctionFlags::kIsGenerator; | 2497 flags |= ParseFunctionFlags::kIsGenerator; |
2519 if (allow_harmony_restrictive_declarations()) { | 2498 if (allow_harmony_restrictive_declarations()) { |
2520 ParserTraits::ReportMessageAt(scanner()->location(), | 2499 ParserTraits::ReportMessageAt(scanner()->location(), |
2521 MessageTemplate::kGeneratorInLegacyContext); | 2500 MessageTemplate::kGeneratorInLegacyContext); |
2522 *ok = false; | 2501 *ok = false; |
2523 return nullptr; | 2502 return nullptr; |
2524 } | 2503 } |
2525 } | 2504 } |
2526 | 2505 |
2527 return ParseHoistableDeclaration(pos, flags, nullptr, CHECK_OK); | 2506 return ParseHoistableDeclaration(pos, flags, nullptr, false, CHECK_OK); |
2528 } | 2507 } |
2529 | 2508 |
2530 Statement* Parser::ParseExpressionOrLabelledStatement( | 2509 Statement* Parser::ParseExpressionOrLabelledStatement( |
2531 ZoneList<const AstRawString*>* labels, | 2510 ZoneList<const AstRawString*>* labels, |
2532 AllowLabelledFunctionStatement allow_function, bool* ok) { | 2511 AllowLabelledFunctionStatement allow_function, bool* ok) { |
2533 // ExpressionStatement | LabelledStatement :: | 2512 // ExpressionStatement | LabelledStatement :: |
2534 // Expression ';' | 2513 // Expression ';' |
2535 // Identifier ':' Statement | 2514 // Identifier ':' Statement |
2536 // | 2515 // |
2537 // ExpressionStatement[Yield] : | 2516 // ExpressionStatement[Yield] : |
(...skipping 4480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7018 try_block, target); | 6997 try_block, target); |
7019 final_loop = target; | 6998 final_loop = target; |
7020 } | 6999 } |
7021 | 7000 |
7022 return final_loop; | 7001 return final_loop; |
7023 } | 7002 } |
7024 | 7003 |
7025 | 7004 |
7026 } // namespace internal | 7005 } // namespace internal |
7027 } // namespace v8 | 7006 } // namespace v8 |
OLD | NEW |