Chromium Code Reviews| 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 |