Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: src/parsing/parser.cc

Issue 1589173002: [modules] Support parsing anonymous default exports (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add negative generator test Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-rewriter.h" 9 #include "src/ast/ast-expression-rewriter.h"
10 #include "src/ast/ast-expression-visitor.h" 10 #include "src/ast/ast-expression-visitor.h"
(...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 } 1268 }
1269 1269
1270 switch (peek()) { 1270 switch (peek()) {
1271 case Token::FUNCTION: 1271 case Token::FUNCTION:
1272 return ParseFunctionDeclaration(NULL, ok); 1272 return ParseFunctionDeclaration(NULL, ok);
1273 case Token::CLASS: 1273 case Token::CLASS:
1274 if (scope_->class_declaration_group_start() < 0) { 1274 if (scope_->class_declaration_group_start() < 0) {
1275 scope_->set_class_declaration_group_start( 1275 scope_->set_class_declaration_group_start(
1276 scanner()->peek_location().beg_pos); 1276 scanner()->peek_location().beg_pos);
1277 } 1277 }
1278 Consume(Token::CLASS);
1278 return ParseClassDeclaration(NULL, ok); 1279 return ParseClassDeclaration(NULL, ok);
1279 case Token::CONST: 1280 case Token::CONST:
1280 if (allow_const()) { 1281 if (allow_const()) {
1281 return ParseVariableStatement(kStatementListItem, NULL, ok); 1282 return ParseVariableStatement(kStatementListItem, NULL, ok);
1282 } 1283 }
1283 break; 1284 break;
1284 case Token::VAR: 1285 case Token::VAR:
1285 return ParseVariableStatement(kStatementListItem, NULL, ok); 1286 return ParseVariableStatement(kStatementListItem, NULL, ok);
1286 case Token::LET: 1287 case Token::LET:
1287 if (IsNextLetKeyword()) { 1288 if (IsNextLetKeyword()) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 1553
1553 Statement* Parser::ParseExportDefault(bool* ok) { 1554 Statement* Parser::ParseExportDefault(bool* ok) {
1554 // Supports the following productions, starting after the 'default' token: 1555 // Supports the following productions, starting after the 'default' token:
1555 // 'export' 'default' FunctionDeclaration 1556 // 'export' 'default' FunctionDeclaration
1556 // 'export' 'default' ClassDeclaration 1557 // 'export' 'default' ClassDeclaration
1557 // 'export' 'default' AssignmentExpression[In] ';' 1558 // 'export' 'default' AssignmentExpression[In] ';'
1558 1559
1559 Expect(Token::DEFAULT, CHECK_OK); 1560 Expect(Token::DEFAULT, CHECK_OK);
1560 Scanner::Location default_loc = scanner()->location(); 1561 Scanner::Location default_loc = scanner()->location();
1561 1562
1563 const AstRawString* default_string = ast_value_factory()->default_string();
1562 ZoneList<const AstRawString*> names(1, zone()); 1564 ZoneList<const AstRawString*> names(1, zone());
1563 Statement* result = NULL; 1565 Statement* result = nullptr;
1566 Expression* default_export = nullptr;
1564 switch (peek()) { 1567 switch (peek()) {
1565 case Token::FUNCTION: 1568 case Token::FUNCTION: {
1566 // TODO(ES6): Support parsing anonymous function declarations here. 1569 Consume(Token::FUNCTION);
1567 result = ParseFunctionDeclaration(&names, CHECK_OK); 1570 int pos = position();
1571 bool is_generator = Check(Token::MUL);
1572 if (peek() == Token::LPAREN) {
1573 // FunctionDeclaration[+Default] ::
1574 // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
1575 //
1576 // GeneratorDeclaration[+Default] ::
1577 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
1578 default_export = ParseFunctionLiteral(
1579 default_string, Scanner::Location::invalid(),
1580 kSkipFunctionNameCheck,
1581 is_generator ? FunctionKind::kGeneratorFunction
1582 : FunctionKind::kNormalFunction,
1583 pos, FunctionLiteral::kDeclaration, FunctionLiteral::kNormalArity,
1584 language_mode(), CHECK_OK);
1585 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1586 } else {
1587 result = ParseFunctionDeclaration(pos, is_generator, &names, CHECK_OK);
1588 }
1568 break; 1589 break;
1590 }
1569 1591
1570 case Token::CLASS: 1592 case Token::CLASS:
1571 // TODO(ES6): Support parsing anonymous class declarations here. 1593 Consume(Token::CLASS);
1572 result = ParseClassDeclaration(&names, CHECK_OK); 1594 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) {
1595 // ClassDeclaration[+Default] ::
1596 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
1597 default_export =
1598 ParseClassLiteral(default_string, Scanner::Location::invalid(),
1599 false, position(), CHECK_OK);
1600 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1601 } else {
1602 result = ParseClassDeclaration(&names, CHECK_OK);
1603 }
1573 break; 1604 break;
1574 1605
1575 default: { 1606 default: {
1576 int pos = peek_position(); 1607 int pos = peek_position();
1577 ExpressionClassifier classifier; 1608 ExpressionClassifier classifier;
1578 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); 1609 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
1579 expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK); 1610 expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK);
1580 1611
1581 ExpectSemicolon(CHECK_OK); 1612 ExpectSemicolon(CHECK_OK);
1582 result = factory()->NewExpressionStatement(expr, pos); 1613 result = factory()->NewExpressionStatement(expr, pos);
1583 break; 1614 break;
1584 } 1615 }
1585 } 1616 }
1586 1617
1587 const AstRawString* default_string = ast_value_factory()->default_string();
1588
1589 DCHECK_LE(names.length(), 1); 1618 DCHECK_LE(names.length(), 1);
1590 if (names.length() == 1) { 1619 if (names.length() == 1) {
1591 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok); 1620 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
1592 if (!*ok) { 1621 if (!*ok) {
1593 ParserTraits::ReportMessageAt( 1622 ParserTraits::ReportMessageAt(
1594 default_loc, MessageTemplate::kDuplicateExport, default_string); 1623 default_loc, MessageTemplate::kDuplicateExport, default_string);
1595 return NULL; 1624 return nullptr;
1596 } 1625 }
1597 } else { 1626 } else {
1598 // TODO(ES6): Assign result to a const binding with the name "*default*" 1627 // TODO(ES6): Assign result to a const binding with the name "*default*"
1599 // and add an export entry with "*default*" as the local name. 1628 // and add an export entry with "*default*" as the local name.
1629 USE(default_export);
1600 } 1630 }
1601 1631
1602 return result; 1632 return result;
1603 } 1633 }
1604 1634
1605 1635
1606 Statement* Parser::ParseExportDeclaration(bool* ok) { 1636 Statement* Parser::ParseExportDeclaration(bool* ok) {
1607 // ExportDeclaration: 1637 // ExportDeclaration:
1608 // 'export' '*' 'from' ModuleSpecifier ';' 1638 // 'export' '*' 'from' ModuleSpecifier ';'
1609 // 'export' ExportClause ('from' ModuleSpecifier)? ';' 1639 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 } 1710 }
1681 } 1711 }
1682 return factory()->NewEmptyStatement(pos); 1712 return factory()->NewEmptyStatement(pos);
1683 } 1713 }
1684 1714
1685 case Token::FUNCTION: 1715 case Token::FUNCTION:
1686 result = ParseFunctionDeclaration(&names, CHECK_OK); 1716 result = ParseFunctionDeclaration(&names, CHECK_OK);
1687 break; 1717 break;
1688 1718
1689 case Token::CLASS: 1719 case Token::CLASS:
1720 Consume(Token::CLASS);
1690 result = ParseClassDeclaration(&names, CHECK_OK); 1721 result = ParseClassDeclaration(&names, CHECK_OK);
1691 break; 1722 break;
1692 1723
1693 case Token::VAR: 1724 case Token::VAR:
1694 case Token::LET: 1725 case Token::LET:
1695 case Token::CONST: 1726 case Token::CONST:
1696 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); 1727 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1697 break; 1728 break;
1698 1729
1699 default: 1730 default:
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
2083 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( 2114 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2084 name, extension_, RelocInfo::kNoPosition); 2115 name, extension_, RelocInfo::kNoPosition);
2085 return factory()->NewExpressionStatement( 2116 return factory()->NewExpressionStatement(
2086 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), 2117 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition),
2087 pos); 2118 pos);
2088 } 2119 }
2089 2120
2090 2121
2091 Statement* Parser::ParseFunctionDeclaration( 2122 Statement* Parser::ParseFunctionDeclaration(
2092 ZoneList<const AstRawString*>* names, bool* ok) { 2123 ZoneList<const AstRawString*>* names, bool* ok) {
2093 // FunctionDeclaration ::
2094 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
2095 // GeneratorDeclaration ::
2096 // 'function' '*' Identifier '(' FormalParameterListopt ')'
2097 // '{' FunctionBody '}'
2098 Expect(Token::FUNCTION, CHECK_OK); 2124 Expect(Token::FUNCTION, CHECK_OK);
2099 int pos = position(); 2125 int pos = position();
2100 bool is_generator = Check(Token::MUL); 2126 bool is_generator = Check(Token::MUL);
2127 return ParseFunctionDeclaration(pos, is_generator, names, ok);
2128 }
2129
2130
2131 Statement* Parser::ParseFunctionDeclaration(
2132 int pos, bool is_generator, ZoneList<const AstRawString*>* names,
2133 bool* ok) {
2134 // FunctionDeclaration ::
2135 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2136 // GeneratorDeclaration ::
2137 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2138 //
2139 // 'function' and '*' (if present) have been consumed by the caller.
2101 bool is_strict_reserved = false; 2140 bool is_strict_reserved = false;
2102 const AstRawString* name = ParseIdentifierOrStrictReservedWord( 2141 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2103 &is_strict_reserved, CHECK_OK); 2142 &is_strict_reserved, CHECK_OK);
2104 2143
2105 FuncNameInferrer::State fni_state(fni_); 2144 FuncNameInferrer::State fni_state(fni_);
2106 if (fni_ != NULL) fni_->PushEnclosingName(name); 2145 if (fni_ != NULL) fni_->PushEnclosingName(name);
2107 FunctionLiteral* fun = ParseFunctionLiteral( 2146 FunctionLiteral* fun = ParseFunctionLiteral(
2108 name, scanner()->location(), 2147 name, scanner()->location(),
2109 is_strict_reserved ? kFunctionNameIsStrictReserved 2148 is_strict_reserved ? kFunctionNameIsStrictReserved
2110 : kFunctionNameValidityUnknown, 2149 : kFunctionNameValidityUnknown,
(...skipping 30 matching lines...) Expand all
2141 } 2180 }
2142 return empty; 2181 return empty;
2143 } 2182 }
2144 2183
2145 2184
2146 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, 2185 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2147 bool* ok) { 2186 bool* ok) {
2148 // ClassDeclaration :: 2187 // ClassDeclaration ::
2149 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' 2188 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2150 // 2189 //
2190 // 'class' is expected to be consumed by the caller.
2191 //
2151 // A ClassDeclaration 2192 // A ClassDeclaration
2152 // 2193 //
2153 // class C { ... } 2194 // class C { ... }
2154 // 2195 //
2155 // has the same semantics as: 2196 // has the same semantics as:
2156 // 2197 //
2157 // let C = class C { ... }; 2198 // let C = class C { ... };
2158 // 2199 //
2159 // so rewrite it as such. 2200 // so rewrite it as such.
2160 2201
2161 Expect(Token::CLASS, CHECK_OK);
2162 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { 2202 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2163 ReportMessage(MessageTemplate::kSloppyLexical); 2203 ReportMessage(MessageTemplate::kSloppyLexical);
2164 *ok = false; 2204 *ok = false;
2165 return NULL; 2205 return NULL;
2166 } 2206 }
2167 2207
2168 int pos = position(); 2208 int pos = position();
2169 bool is_strict_reserved = false; 2209 bool is_strict_reserved = false;
2170 const AstRawString* name = 2210 const AstRawString* name =
2171 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 2211 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
(...skipping 3526 matching lines...) Expand 10 before | Expand all | Expand 10 after
5698 auto class_literal = value->AsClassLiteral(); 5738 auto class_literal = value->AsClassLiteral();
5699 if (class_literal->raw_name() == nullptr) { 5739 if (class_literal->raw_name() == nullptr) {
5700 class_literal->set_raw_name(name); 5740 class_literal->set_raw_name(name);
5701 } 5741 }
5702 } 5742 }
5703 } 5743 }
5704 5744
5705 5745
5706 } // namespace internal 5746 } // namespace internal
5707 } // namespace v8 5747 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698