| Index: pkg/compiler/lib/src/library_loader.dart
|
| diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
|
| index 9984f05d18515cffc59c4a27b015548ef63e1a5a..dbdd3a08bdb8d9c222a80c0d1a01d38b34d70116 100644
|
| --- a/pkg/compiler/lib/src/library_loader.dart
|
| +++ b/pkg/compiler/lib/src/library_loader.dart
|
| @@ -874,7 +874,14 @@ class LibraryDependencyNode {
|
| }
|
| }
|
|
|
| - void registerHandledExports(LibraryElement exportedLibraryElement,
|
| + /// Register the already computed export scope of [exportedLibraryElement] to
|
| + /// export from the library of this node through the [export] declaration
|
| + /// with the given combination [filter].
|
| + ///
|
| + /// Additionally, check that all names in the show/hide combinators are in the
|
| + /// export scope of [exportedLibraryElement].
|
| + void registerHandledExports(DiagnosticListener listener,
|
| + LibraryElement exportedLibraryElement,
|
| ExportElementX export,
|
| CombinatorFilter filter) {
|
| assert(invariant(library, exportedLibraryElement.exportsHandled));
|
| @@ -886,6 +893,9 @@ class LibraryDependencyNode {
|
| pendingExportMap[exportedElement] = exports.prepend(export);
|
| }
|
| });
|
| + listener.withCurrentElement(library, () {
|
| + checkLibraryDependency(listener, export.node, exportedLibraryElement);
|
| + });
|
| }
|
|
|
| /**
|
| @@ -1011,6 +1021,45 @@ class LibraryDependencyNode {
|
| }
|
| return changed;
|
| }
|
| +
|
| + /// Check that all names in the show/hide combinators of imports and exports
|
| + /// are in the export scope of the imported/exported libraries.
|
| + void checkCombinators(DiagnosticListener listener) {
|
| + listener.withCurrentElement(library, () {
|
| + for (ImportLink importLink in imports) {
|
| + checkLibraryDependency(
|
| + listener, importLink.import.node, importLink.importedLibrary);
|
| + }
|
| + });
|
| + for (ExportLink exportLink in dependencies) {
|
| + listener.withCurrentElement(exportLink.exportNode.library, () {
|
| + checkLibraryDependency(listener, exportLink.export.node, library);
|
| + });
|
| + }
|
| + }
|
| +
|
| + /// Check that all names in the show/hide combinators of [tag] are in the
|
| + /// export scope of [library].
|
| + void checkLibraryDependency(DiagnosticListener listener,
|
| + LibraryDependency tag,
|
| + LibraryElement library) {
|
| + if (tag == null || tag.combinators == null) return;
|
| + for (Combinator combinator in tag.combinators) {
|
| + for (Identifier identifier in combinator.identifiers) {
|
| + String name = identifier.source;
|
| + Element element = library.findExported(name);
|
| + if (element == null) {
|
| + listener.reportHint(
|
| + identifier,
|
| + combinator.isHide
|
| + ? MessageKind.EMPTY_HIDE : MessageKind.EMPTY_SHOW,
|
| + {'uri': library.canonicalUri,
|
| + 'name': name});
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| }
|
|
|
| /**
|
| @@ -1084,6 +1133,10 @@ class LibraryDependencyHandler implements LibraryLoader {
|
| nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
|
| node.registerImports(compiler);
|
| });
|
| +
|
| + nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
|
| + node.checkCombinators(compiler);
|
| + });
|
| }
|
|
|
| /// Registers that [library] depends on [loadedLibrary] through
|
| @@ -1099,7 +1152,7 @@ class LibraryDependencyHandler implements LibraryLoader {
|
| CombinatorFilter combinatorFilter =
|
| new CombinatorFilter.fromTag(libraryDependency.node);
|
| exportingNode.registerHandledExports(
|
| - loadedLibrary, libraryDependency, combinatorFilter);
|
| + compiler, loadedLibrary, libraryDependency, combinatorFilter);
|
| return;
|
| }
|
| LibraryDependencyNode exportedNode = nodeMap[loadedLibrary];
|
|
|