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

Unified Diff: sdk/lib/_internal/compiler/implementation/library_loader.dart

Issue 25864002: Update handling of exports. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status Created 7 years, 2 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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/library_loader.dart
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 1342ce8cbe080f457dcb87324ba557ead384517b..bad6e10da309ea9cb592193a38dbb855c60de301 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -569,11 +569,13 @@ class ImportLink {
* the library dependency graph.
*/
class ExportLink {
+ final Export export;
final CombinatorFilter combinatorFilter;
final LibraryDependencyNode exportNode;
ExportLink(Export export, LibraryDependencyNode this.exportNode)
- : this.combinatorFilter = new CombinatorFilter.fromTag(export);
+ : this.export = export,
+ this.combinatorFilter = new CombinatorFilter.fromTag(export);
/**
* Exports [element] to the dependent library unless [element] is filtered by
@@ -582,7 +584,7 @@ class ExportLink {
*/
bool exportElement(Element element) {
if (combinatorFilter.exclude(element)) return false;
- return exportNode.addElementToPendingExports(element);
+ return exportNode.addElementToPendingExports(element, export);
}
}
@@ -622,12 +624,17 @@ class LibraryDependencyNode {
Map<SourceString, Element> exportScope =
new LinkedHashMap<SourceString, Element>();
+ /// Map from exported elements to the export directives that exported them.
+ Map<Element, Link<Export>> exporters = new Map<Element, Link<Export>>();
+
/**
* The set of exported elements that need to be propageted to dependent
* libraries as part of the work-list computation performed in
- * [LibraryDependencyHandler.computeExports].
+ * [LibraryDependencyHandler.computeExports]. Each export element is mapped
+ * to a list of exports directives that export it.
*/
- Set<Element> pendingExportSet = new Set<Element>();
+ Map<Element, Link<Export>> pendingExportMap =
+ new Map<Element, Link<Export>>();
LibraryDependencyNode(LibraryElement this.library);
@@ -656,15 +663,21 @@ class LibraryDependencyNode {
* the export scopes performed in [LibraryDependencyHandler.computeExports].
*/
void registerInitialExports() {
- pendingExportSet.addAll(library.getNonPrivateElementsInScope());
+ for (Element element in library.getNonPrivateElementsInScope()) {
+ pendingExportMap[element] = const Link<Export>();
+ }
}
void registerHandledExports(LibraryElement exportedLibraryElement,
+ Export export,
CombinatorFilter filter) {
assert(invariant(library, exportedLibraryElement.exportsHandled));
for (Element exportedElement in exportedLibraryElement.exports) {
if (!filter.exclude(exportedElement)) {
- pendingExportSet.add(exportedElement);
+ Link<Export> exports =
+ pendingExportMap.putIfAbsent(exportedElement,
+ () => const Link<Export>());
+ pendingExportMap[exportedElement] = exports.prepend(export);
}
}
}
@@ -688,9 +701,10 @@ class LibraryDependencyNode {
/**
* Copies and clears pending export set for this node.
*/
- List<Element> pullPendingExports() {
- List<Element> pendingExports = new List.from(pendingExportSet);
- pendingExportSet.clear();
+ Map<Element, Link<Export>> pullPendingExports() {
+ Map<Element, Link<Export>> pendingExports =
+ new Map<Element, Link<Export>>.from(pendingExportMap);
+ pendingExportMap.clear();
return pendingExports;
}
@@ -698,25 +712,53 @@ class LibraryDependencyNode {
* Adds [element] to the export scope for this node. If the [element] name
* is a duplicate, an error element is inserted into the export scope.
*/
- Element addElementToExportScope(Compiler compiler, Element element) {
+ Element addElementToExportScope(Compiler compiler, Element element,
+ Link<Export> exports) {
+
SourceString name = element.name;
+
+ void reportDuplicateExport(Element duplicate,
+ Link<Export> duplicateExports,
+ {bool reportError: true}) {
+ compiler.withCurrentElement(library, () {
+ for (Export export in duplicateExports) {
+ if (reportError) {
+ compiler.reportError(export,
+ MessageKind.DUPLICATE_EXPORT, {'name': name});
+ reportError = false;
+ } else {
+ compiler.reportInfo(export,
+ MessageKind.DUPLICATE_EXPORT_CONT, {'name': name});
+ }
+ }
+ });
+ }
+
+ void reportDuplicateExportDecl(Element duplicate,
+ Link<Export> duplicateExports) {
+ compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL,
+ {'name': name, 'uriString': duplicateExports.head.uri});
+ }
+
Element existingElement = exportScope[name];
- if (existingElement != null) {
+ if (existingElement != null && existingElement != element) {
if (existingElement.isErroneous()) {
- compiler.reportError(element, MessageKind.DUPLICATE_EXPORT,
- {'name': name});
+ reportDuplicateExport(element, exports);
+ reportDuplicateExportDecl(element, exports);
element = existingElement;
} else if (existingElement.getLibrary() != library) {
// Declared elements hide exported elements.
- compiler.reportError(existingElement, MessageKind.DUPLICATE_EXPORT,
- {'name': name});
- compiler.reportError(element, MessageKind.DUPLICATE_EXPORT,
- {'name': name});
+ Link<Export> existingExports = exporters[existingElement];
+ reportDuplicateExport(existingElement, existingExports);
+ reportDuplicateExport(element, exports, reportError: false);
+ reportDuplicateExportDecl(existingElement, existingExports);
+ reportDuplicateExportDecl(element, exports);
element = exportScope[name] = new ErroneousElementX(
MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
}
} else {
exportScope[name] = element;
+ exporters[element] = exports;
}
return element;
}
@@ -741,14 +783,16 @@ class LibraryDependencyNode {
* the pending export set was modified. The combinators of [export] are used
* to filter the element.
*/
- bool addElementToPendingExports(Element element) {
+ bool addElementToPendingExports(Element element, Export export) {
+ bool changed = false;
if (!identical(exportScope[element.name], element)) {
- if (!pendingExportSet.contains(element)) {
- pendingExportSet.add(element);
- return true;
- }
+ Link<Export> exports = pendingExportMap.putIfAbsent(element, () {
+ changed = true;
+ return const Link<Export>();
+ });
+ pendingExportMap[element] = exports.prepend(export);
}
- return false;
+ return changed;
}
}
@@ -783,8 +827,8 @@ class LibraryDependencyHandler {
bool changed = true;
while (changed) {
changed = false;
- Map<LibraryDependencyNode, List<Element>> tasks =
- new LinkedHashMap<LibraryDependencyNode, List<Element>>();
+ Map<LibraryDependencyNode, Map<Element, Link<Export>>> tasks =
+ new Map<LibraryDependencyNode, Map<Element, Link<Export>>>();
// Locally defined elements take precedence over exported
// elements. So we must propagate local elements first. We
@@ -792,12 +836,13 @@ class LibraryDependencyHandler {
// propagating. This enforces that we handle exports
// breadth-first, with locally defined elements being level 0.
nodeMap.forEach((_, LibraryDependencyNode node) {
- List<Element> pendingExports = node.pullPendingExports();
+ Map<Element, Link<Export>> pendingExports = node.pullPendingExports();
tasks[node] = pendingExports;
});
- tasks.forEach((LibraryDependencyNode node, List<Element> pendingExports) {
- pendingExports.forEach((Element element) {
- element = node.addElementToExportScope(compiler, element);
+ tasks.forEach((LibraryDependencyNode node,
+ Map<Element, Link<Export>> pendingExports) {
+ pendingExports.forEach((Element element, Link<Export> exports) {
+ element = node.addElementToExportScope(compiler, element, exports);
if (node.propagateElement(element)) {
changed = true;
}
@@ -833,7 +878,8 @@ class LibraryDependencyHandler {
if (loadedLibrary.exportsHandled) {
// Export scope already computed on [loadedLibrary].
var combinatorFilter = new CombinatorFilter.fromTag(tag);
- exportingNode.registerHandledExports(loadedLibrary, combinatorFilter);
+ exportingNode.registerHandledExports(
+ loadedLibrary, tag, combinatorFilter);
return;
}
LibraryDependencyNode exportedNode = nodeMap[loadedLibrary];
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698