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

Unified Diff: src/parser.cc

Issue 934323004: Teach ModuleDescriptor about basic local exports (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Handled review comments, added message tests Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index bb8cb52b75068f0aee6941880fd7d1ecfe58bd29..1bbc88f00f3f27804a8ef8769d7f7dfcf386a17c 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1281,8 +1281,11 @@ Statement* Parser::ParseModule(bool* ok) {
ModuleDescriptor* descriptor = scope->module();
for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
it.Advance()) {
- if (scope->LookupLocal(it.name()) == NULL) {
- ParserTraits::ReportMessage("module_export_undefined", it.name());
+ if (scope->LookupLocal(it.local_name()) == NULL) {
+ // TODO(adamk): Pass both local_name and export_name once ParserTraits
+ // supports multiple arg error messages.
+ // Also try to report this at a better location.
+ ParserTraits::ReportMessage("module_export_undefined", it.local_name());
*ok = false;
return NULL;
}
@@ -1303,7 +1306,9 @@ Literal* Parser::ParseModuleSpecifier(bool* ok) {
}
-void* Parser::ParseExportClause(ZoneList<const AstRawString*>* names,
+void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
+ ZoneList<Scanner::Location>* export_locations,
+ ZoneList<const AstRawString*>* local_names,
Scanner::Location* reserved_loc, bool* ok) {
// ExportClause :
// '{' '}'
@@ -1328,14 +1333,17 @@ void* Parser::ParseExportClause(ZoneList<const AstRawString*>* names,
!Token::IsIdentifier(name_tok, STRICT, false)) {
*reserved_loc = scanner()->location();
}
- const AstRawString* name = ParseIdentifierName(CHECK_OK);
- names->Add(name, zone());
+ const AstRawString* local_name = ParseIdentifierName(CHECK_OK);
const AstRawString* export_name = NULL;
if (CheckContextualKeyword(CStrVector("as"))) {
export_name = ParseIdentifierName(CHECK_OK);
}
- // TODO(ES6): Return the export_name as well as the name.
- USE(export_name);
+ if (export_name == NULL) {
+ export_name = local_name;
+ }
+ export_names->Add(export_name, zone());
+ local_names->Add(local_name, zone());
+ export_locations->Add(scanner()->location(), zone());
if (peek() == Token::RBRACE) break;
Expect(Token::COMMA, CHECK_OK);
}
@@ -1479,16 +1487,20 @@ Statement* Parser::ParseExportDefault(bool* ok) {
// 'export' 'default' ClassDeclaration
// 'export' 'default' AssignmentExpression[In] ';'
+ Expect(Token::DEFAULT, CHECK_OK);
+ Scanner::Location default_loc = scanner()->location();
+
+ ZoneList<const AstRawString*> names(1, zone());
Statement* result = NULL;
switch (peek()) {
case Token::FUNCTION:
// TODO(ES6): Support parsing anonymous function declarations here.
- result = ParseFunctionDeclaration(NULL, CHECK_OK);
+ result = ParseFunctionDeclaration(&names, CHECK_OK);
break;
case Token::CLASS:
// TODO(ES6): Support parsing anonymous class declarations here.
- result = ParseClassDeclaration(NULL, CHECK_OK);
+ result = ParseClassDeclaration(&names, CHECK_OK);
break;
default: {
@@ -1500,7 +1512,20 @@ Statement* Parser::ParseExportDefault(bool* ok) {
}
}
- // TODO(ES6): Add default export to scope_->module()
+ const AstRawString* default_string = ast_value_factory()->default_string();
+
+ DCHECK_LE(names.length(), 1);
+ if (names.length() == 1) {
+ scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
+ if (!*ok) {
+ ParserTraits::ReportMessageAt(default_loc, "duplicate_export",
+ default_string);
+ return NULL;
+ }
+ } else {
+ // TODO(ES6): Assign result to a const binding with the name "*default*"
+ // and add an export entry with "*default*" as the local name.
+ }
return result;
}
@@ -1519,10 +1544,8 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
Statement* result = NULL;
ZoneList<const AstRawString*> names(1, zone());
- bool is_export_from = false;
switch (peek()) {
case Token::DEFAULT:
- Consume(Token::DEFAULT);
return ParseExportDefault(ok);
case Token::MUL: {
@@ -1530,12 +1553,9 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
Literal* module = ParseModuleSpecifier(CHECK_OK);
ExpectSemicolon(CHECK_OK);
- // TODO(ES6): Do something with the return value
- // of ParseModuleSpecifier.
+ // TODO(ES6): scope_->module()->AddStarExport(...)
USE(module);
- is_export_from = true;
- result = factory()->NewEmptyStatement(pos);
- break;
+ return factory()->NewEmptyStatement(pos);
}
case Token::LBRACE: {
@@ -1551,13 +1571,14 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
// encountered, and then throw a SyntaxError if we are in the
// non-FromClause case.
Scanner::Location reserved_loc = Scanner::Location::invalid();
- ParseExportClause(&names, &reserved_loc, CHECK_OK);
+ ZoneList<const AstRawString*> export_names(1, zone());
+ ZoneList<Scanner::Location> export_locations(1, zone());
+ ZoneList<const AstRawString*> local_names(1, zone());
+ ParseExportClause(&export_names, &export_locations, &local_names,
+ &reserved_loc, CHECK_OK);
+ Literal* indirect_export_module_specifier = NULL;
if (CheckContextualKeyword(CStrVector("from"))) {
- Literal* module = ParseModuleSpecifier(CHECK_OK);
- // TODO(ES6): Do something with the return value
- // of ParseModuleSpecifier.
- USE(module);
- is_export_from = true;
+ indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK);
} else if (reserved_loc.IsValid()) {
// No FromClause, so reserved words are invalid in ExportClause.
*ok = false;
@@ -1565,8 +1586,25 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
return NULL;
}
ExpectSemicolon(CHECK_OK);
- result = factory()->NewEmptyStatement(pos);
- break;
+ const int length = export_names.length();
+ DCHECK_EQ(length, local_names.length());
+ DCHECK_EQ(length, export_locations.length());
+ if (indirect_export_module_specifier == NULL) {
+ for (int i = 0; i < length; ++i) {
+ scope_->module()->AddLocalExport(export_names[i], local_names[i],
+ zone(), ok);
+ if (!*ok) {
+ ParserTraits::ReportMessageAt(export_locations[i],
+ "duplicate_export", export_names[i]);
+ return NULL;
+ }
+ }
+ } else {
+ for (int i = 0; i < length; ++i) {
+ // TODO(ES6): scope_->module()->AddIndirectExport(...);(
+ }
+ }
+ return factory()->NewEmptyStatement(pos);
}
case Token::FUNCTION:
@@ -1589,37 +1627,18 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
return NULL;
}
- // Every export of a module may be assigned.
+ // Extract declared names into export declarations.
+ ModuleDescriptor* descriptor = scope_->module();
for (int i = 0; i < names.length(); ++i) {
- Variable* var = scope_->Lookup(names[i]);
- if (var == NULL) {
- // TODO(sigurds) This is an export that has no definition yet,
- // not clear what to do in this case.
- continue;
- }
- if (!IsImmutableVariableMode(var->mode())) {
- var->set_maybe_assigned();
- }
- }
-
- // TODO(ES6): Handle 'export from' once imports are properly implemented.
- // For now we just drop such exports on the floor.
- if (!is_export_from) {
- // Extract declared names into export declarations and module descriptor.
- ModuleDescriptor* descriptor = scope_->module();
- for (int i = 0; i < names.length(); ++i) {
- // TODO(adamk): Make early errors here provide the right error message
- // (duplicate exported names).
- descriptor->Add(names[i], zone(), CHECK_OK);
- // TODO(rossberg): Rethink whether we actually need to store export
- // declarations (for compilation?).
- // ExportDeclaration* declaration =
- // factory()->NewExportDeclaration(proxy, scope_, position);
- // scope_->AddDeclaration(declaration);
+ descriptor->AddLocalExport(names[i], names[i], zone(), ok);
+ if (!*ok) {
+ // TODO(adamk): Possibly report this error at the right place.
+ ParserTraits::ReportMessage("duplicate_export", names[i]);
+ return NULL;
}
}
- DCHECK(result != NULL);
+ DCHECK_NOT_NULL(result);
return result;
}
« no previous file with comments | « src/parser.h ('k') | src/scopeinfo.cc » ('j') | test/message/export-duplicate.out » ('J')

Powered by Google App Engine
This is Rietveld 408576698