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