Reland of "[modules] Make duplicate export error deterministic."

In case of duplicate exports, always report the error for the very last
    one.

(Fixed a bug.)

BUG=v8:5358,v8:1569

Review-Url: https://codereview.chromium.org/2340953002
Cr-Commit-Position: refs/heads/master@{#39434}
This commit is contained in:
neis 2016-09-14 18:36:11 -07:00 committed by Commit bot
parent 7776370c58
commit d383430d93
9 changed files with 40 additions and 19 deletions

View File

@ -134,19 +134,40 @@ void ModuleDescriptor::MakeIndirectExportsExplicit(Zone* zone) {
}
}
namespace {
const ModuleDescriptor::Entry* BetterDuplicate(
const ModuleDescriptor::Entry* candidate,
ZoneMap<const AstRawString*, const ModuleDescriptor::Entry*>& export_names,
const ModuleDescriptor::Entry* current_duplicate) {
DCHECK_NOT_NULL(candidate->export_name);
DCHECK(candidate->location.IsValid());
auto insert_result =
export_names.insert(std::make_pair(candidate->export_name, candidate));
if (insert_result.second) return current_duplicate;
if (current_duplicate == nullptr) {
current_duplicate = insert_result.first->second;
}
return (candidate->location.beg_pos > current_duplicate->location.beg_pos)
? candidate
: current_duplicate;
}
} // namespace
const ModuleDescriptor::Entry* ModuleDescriptor::FindDuplicateExport(
Zone* zone) const {
ZoneSet<const AstRawString*> export_names(zone);
const ModuleDescriptor::Entry* duplicate = nullptr;
ZoneMap<const AstRawString*, const ModuleDescriptor::Entry*> export_names(
zone);
for (const auto& it : regular_exports_) {
const Entry* entry = it.second;
DCHECK_NOT_NULL(entry->export_name);
if (!export_names.insert(entry->export_name).second) return entry;
duplicate = BetterDuplicate(it.second, export_names, duplicate);
}
for (auto entry : special_exports_) {
if (entry->export_name == nullptr) continue; // Star export.
if (!export_names.insert(entry->export_name).second) return entry;
duplicate = BetterDuplicate(entry, export_names, duplicate);
}
return nullptr;
return duplicate;
}
bool ModuleDescriptor::Validate(ModuleScope* module_scope,

View File

@ -151,8 +151,8 @@ class ModuleDescriptor : public ZoneObject {
ZoneMultimap<const AstRawString*, Entry*> regular_exports_;
ZoneMap<const AstRawString*, const Entry*> regular_imports_;
// If there are multiple export entries with the same export name, return one
// of them. Otherwise return nullptr.
// If there are multiple export entries with the same export name, return the
// last of them (in source order). Otherwise return nullptr.
const Entry* FindDuplicateExport(Zone* zone) const;
// Find any implicitly indirect exports and make them explicit.

View File

@ -4,6 +4,6 @@
//
// MODULE
var a, b;
var a, b, c;
export { a as c };
export { a, b as c };
export { a, b as c, c, b };

View File

@ -2,6 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
*%(basename)s:9: SyntaxError: Duplicate export of 'c'
export { a, b as c };
^
export { a, b as c, c, b };
^
SyntaxError: Duplicate export of 'c'

View File

@ -5,4 +5,5 @@
// MODULE
export default function f() {};
export default 42;
export default class C {};

View File

@ -1,7 +1,7 @@
# Copyright 2015 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
*%(basename)s:8: SyntaxError: Duplicate export of 'default'
*%(basename)s:9: SyntaxError: Duplicate export of 'default'
export default class C {};
^^^^^^^
SyntaxError: Duplicate export of 'default'

View File

@ -4,6 +4,7 @@
//
// MODULE
var a, b;
var a, b, c;
export { a };
export { a, b };
export { b, c };

View File

@ -1,7 +1,7 @@
# Copyright 2015 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
*%(basename)s:9: SyntaxError: Duplicate export of 'a'
export { a, b };
*%(basename)s:10: SyntaxError: Duplicate export of 'b'
export { b, c };
^
SyntaxError: Duplicate export of 'a'
SyntaxError: Duplicate export of 'b'

View File

@ -31,7 +31,5 @@
# escapes (we need to parse to distinguish octal escapes from valid
# back-references).
'strict-octal-regexp': [SKIP],
# See issue v8:5358
'export-duplicate-default': [SKIP],
}], # ALWAYS
]