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

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: 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
1562 ZoneList<const AstRawString*> names(1, zone()); 1563 ZoneList<const AstRawString*> names(1, zone());
1563 Statement* result = NULL; 1564 Statement* result = nullptr;
1565 Expression* default_export = nullptr;
1564 switch (peek()) { 1566 switch (peek()) {
1565 case Token::FUNCTION: 1567 case Token::FUNCTION: {
1566 // TODO(ES6): Support parsing anonymous function declarations here. 1568 Consume(Token::FUNCTION);
1567 result = ParseFunctionDeclaration(&names, CHECK_OK); 1569 int pos = position();
1570 bool is_generator = Check(Token::MUL);
1571 if (peek() == Token::LPAREN) {
1572 // FunctionDeclaration[+Default] ::
1573 // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
1574 //
1575 // GeneratorDeclaration[+Default] ::
1576 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
1577 default_export = ParseFunctionLiteral(
caitp (gmail) 2016/01/14 23:12:53 per 14.1.20, you probably want the SetFunctionName
adamk 2016/01/15 00:06:29 Done.
1578 nullptr, scanner()->location(), kSkipFunctionNameCheck,
1579 is_generator ? FunctionKind::kGeneratorFunction
1580 : FunctionKind::kNormalFunction,
1581 pos, FunctionLiteral::kDeclaration, FunctionLiteral::kNormalArity,
1582 language_mode(), CHECK_OK);
1583 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1584 } else {
1585 result = ParseFunctionDeclaration(pos, is_generator, &names, CHECK_OK);
1586 }
1568 break; 1587 break;
1588 }
1569 1589
1570 case Token::CLASS: 1590 case Token::CLASS:
1571 // TODO(ES6): Support parsing anonymous class declarations here. 1591 Consume(Token::CLASS);
1572 result = ParseClassDeclaration(&names, CHECK_OK); 1592 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) {
1593 // ClassDeclaration[+Default] ::
1594 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
1595 default_export = ParseClassLiteral(
caitp (gmail) 2016/01/14 23:12:53 here too, per 15.2.3.11
adamk 2016/01/15 00:06:29 Done.
1596 nullptr, Scanner::Location::invalid(), false, position(), CHECK_OK);
1597 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1598 } else {
1599 result = ParseClassDeclaration(&names, CHECK_OK);
1600 }
1573 break; 1601 break;
1574 1602
1575 default: { 1603 default: {
1576 int pos = peek_position(); 1604 int pos = peek_position();
1577 ExpressionClassifier classifier; 1605 ExpressionClassifier classifier;
1578 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); 1606 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
1579 expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK); 1607 expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK);
1580 1608
1581 ExpectSemicolon(CHECK_OK); 1609 ExpectSemicolon(CHECK_OK);
1582 result = factory()->NewExpressionStatement(expr, pos); 1610 result = factory()->NewExpressionStatement(expr, pos);
1583 break; 1611 break;
1584 } 1612 }
1585 } 1613 }
1586 1614
1587 const AstRawString* default_string = ast_value_factory()->default_string(); 1615 const AstRawString* default_string = ast_value_factory()->default_string();
1588 1616
1589 DCHECK_LE(names.length(), 1); 1617 DCHECK_LE(names.length(), 1);
1590 if (names.length() == 1) { 1618 if (names.length() == 1) {
1591 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok); 1619 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
1592 if (!*ok) { 1620 if (!*ok) {
1593 ParserTraits::ReportMessageAt( 1621 ParserTraits::ReportMessageAt(
1594 default_loc, MessageTemplate::kDuplicateExport, default_string); 1622 default_loc, MessageTemplate::kDuplicateExport, default_string);
1595 return NULL; 1623 return nullptr;
1596 } 1624 }
1597 } else { 1625 } else {
1598 // TODO(ES6): Assign result to a const binding with the name "*default*" 1626 // TODO(ES6): Assign result to a const binding with the name "*default*"
1599 // and add an export entry with "*default*" as the local name. 1627 // and add an export entry with "*default*" as the local name.
1628 USE(default_export);
1600 } 1629 }
1601 1630
1602 return result; 1631 return result;
1603 } 1632 }
1604 1633
1605 1634
1606 Statement* Parser::ParseExportDeclaration(bool* ok) { 1635 Statement* Parser::ParseExportDeclaration(bool* ok) {
1607 // ExportDeclaration: 1636 // ExportDeclaration:
1608 // 'export' '*' 'from' ModuleSpecifier ';' 1637 // 'export' '*' 'from' ModuleSpecifier ';'
1609 // 'export' ExportClause ('from' ModuleSpecifier)? ';' 1638 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 } 1709 }
1681 } 1710 }
1682 return factory()->NewEmptyStatement(pos); 1711 return factory()->NewEmptyStatement(pos);
1683 } 1712 }
1684 1713
1685 case Token::FUNCTION: 1714 case Token::FUNCTION:
1686 result = ParseFunctionDeclaration(&names, CHECK_OK); 1715 result = ParseFunctionDeclaration(&names, CHECK_OK);
1687 break; 1716 break;
1688 1717
1689 case Token::CLASS: 1718 case Token::CLASS:
1719 Consume(Token::CLASS);
1690 result = ParseClassDeclaration(&names, CHECK_OK); 1720 result = ParseClassDeclaration(&names, CHECK_OK);
1691 break; 1721 break;
1692 1722
1693 case Token::VAR: 1723 case Token::VAR:
1694 case Token::LET: 1724 case Token::LET:
1695 case Token::CONST: 1725 case Token::CONST:
1696 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); 1726 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1697 break; 1727 break;
1698 1728
1699 default: 1729 default:
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
2083 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( 2113 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2084 name, extension_, RelocInfo::kNoPosition); 2114 name, extension_, RelocInfo::kNoPosition);
2085 return factory()->NewExpressionStatement( 2115 return factory()->NewExpressionStatement(
2086 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), 2116 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition),
2087 pos); 2117 pos);
2088 } 2118 }
2089 2119
2090 2120
2091 Statement* Parser::ParseFunctionDeclaration( 2121 Statement* Parser::ParseFunctionDeclaration(
2092 ZoneList<const AstRawString*>* names, bool* ok) { 2122 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); 2123 Expect(Token::FUNCTION, CHECK_OK);
2099 int pos = position(); 2124 int pos = position();
2100 bool is_generator = Check(Token::MUL); 2125 bool is_generator = Check(Token::MUL);
2126 return ParseFunctionDeclaration(pos, is_generator, names, ok);
2127 }
2128
2129
2130 Statement* Parser::ParseFunctionDeclaration(
2131 int pos, bool is_generator, ZoneList<const AstRawString*>* names,
2132 bool* ok) {
2133 // FunctionDeclaration ::
2134 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2135 // GeneratorDeclaration ::
2136 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2137 //
2138 // 'function' and '*' (if present) have been consumed by the caller.
2101 bool is_strict_reserved = false; 2139 bool is_strict_reserved = false;
2102 const AstRawString* name = ParseIdentifierOrStrictReservedWord( 2140 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2103 &is_strict_reserved, CHECK_OK); 2141 &is_strict_reserved, CHECK_OK);
2104 2142
2105 FuncNameInferrer::State fni_state(fni_); 2143 FuncNameInferrer::State fni_state(fni_);
2106 if (fni_ != NULL) fni_->PushEnclosingName(name); 2144 if (fni_ != NULL) fni_->PushEnclosingName(name);
2107 FunctionLiteral* fun = ParseFunctionLiteral( 2145 FunctionLiteral* fun = ParseFunctionLiteral(
2108 name, scanner()->location(), 2146 name, scanner()->location(),
2109 is_strict_reserved ? kFunctionNameIsStrictReserved 2147 is_strict_reserved ? kFunctionNameIsStrictReserved
2110 : kFunctionNameValidityUnknown, 2148 : kFunctionNameValidityUnknown,
(...skipping 30 matching lines...) Expand all
2141 } 2179 }
2142 return empty; 2180 return empty;
2143 } 2181 }
2144 2182
2145 2183
2146 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, 2184 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2147 bool* ok) { 2185 bool* ok) {
2148 // ClassDeclaration :: 2186 // ClassDeclaration ::
2149 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' 2187 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2150 // 2188 //
2189 // 'class' is expected to be consumed by the caller.
2190 //
2151 // A ClassDeclaration 2191 // A ClassDeclaration
2152 // 2192 //
2153 // class C { ... } 2193 // class C { ... }
2154 // 2194 //
2155 // has the same semantics as: 2195 // has the same semantics as:
2156 // 2196 //
2157 // let C = class C { ... }; 2197 // let C = class C { ... };
2158 // 2198 //
2159 // so rewrite it as such. 2199 // so rewrite it as such.
2160 2200
2161 Expect(Token::CLASS, CHECK_OK);
2162 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { 2201 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2163 ReportMessage(MessageTemplate::kSloppyLexical); 2202 ReportMessage(MessageTemplate::kSloppyLexical);
2164 *ok = false; 2203 *ok = false;
2165 return NULL; 2204 return NULL;
2166 } 2205 }
2167 2206
2168 int pos = position(); 2207 int pos = position();
2169 bool is_strict_reserved = false; 2208 bool is_strict_reserved = false;
2170 const AstRawString* name = 2209 const AstRawString* name =
2171 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 2210 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
(...skipping 3526 matching lines...) Expand 10 before | Expand all | Expand 10 after
5698 auto class_literal = value->AsClassLiteral(); 5737 auto class_literal = value->AsClassLiteral();
5699 if (class_literal->raw_name() == nullptr) { 5738 if (class_literal->raw_name() == nullptr) {
5700 class_literal->set_raw_name(name); 5739 class_literal->set_raw_name(name);
5701 } 5740 }
5702 } 5741 }
5703 } 5742 }
5704 5743
5705 5744
5706 } // namespace internal 5745 } // namespace internal
5707 } // namespace v8 5746 } // 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