| 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 |