OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.library_loader; | 5 library dart2js.library_loader; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'common/names.dart' show | 9 import 'common/names.dart' show |
10 Uris; | 10 Uris; |
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
867 * Registers all non-private locally declared members of the library of this | 867 * Registers all non-private locally declared members of the library of this |
868 * node to be exported. This forms the basis for the work-list computation of | 868 * node to be exported. This forms the basis for the work-list computation of |
869 * the export scopes performed in [LibraryDependencyHandler.computeExports]. | 869 * the export scopes performed in [LibraryDependencyHandler.computeExports]. |
870 */ | 870 */ |
871 void registerInitialExports() { | 871 void registerInitialExports() { |
872 for (Element element in library.getNonPrivateElementsInScope()) { | 872 for (Element element in library.getNonPrivateElementsInScope()) { |
873 pendingExportMap[element] = const Link<ExportElement>(); | 873 pendingExportMap[element] = const Link<ExportElement>(); |
874 } | 874 } |
875 } | 875 } |
876 | 876 |
877 void registerHandledExports(LibraryElement exportedLibraryElement, | 877 /// Register the already computed export scope of [exportedLibraryElement] to |
| 878 /// export from the library of this node through the [export] declaration |
| 879 /// with the given combination [filter]. |
| 880 /// |
| 881 /// Additionally, check that all names in the show/hide combinators are in the |
| 882 /// export scope of [exportedLibraryElement]. |
| 883 void registerHandledExports(DiagnosticListener listener, |
| 884 LibraryElement exportedLibraryElement, |
878 ExportElementX export, | 885 ExportElementX export, |
879 CombinatorFilter filter) { | 886 CombinatorFilter filter) { |
880 assert(invariant(library, exportedLibraryElement.exportsHandled)); | 887 assert(invariant(library, exportedLibraryElement.exportsHandled)); |
881 exportedLibraryElement.forEachExport((Element exportedElement) { | 888 exportedLibraryElement.forEachExport((Element exportedElement) { |
882 if (!filter.exclude(exportedElement)) { | 889 if (!filter.exclude(exportedElement)) { |
883 Link<ExportElement> exports = | 890 Link<ExportElement> exports = |
884 pendingExportMap.putIfAbsent(exportedElement, | 891 pendingExportMap.putIfAbsent(exportedElement, |
885 () => const Link<ExportElement>()); | 892 () => const Link<ExportElement>()); |
886 pendingExportMap[exportedElement] = exports.prepend(export); | 893 pendingExportMap[exportedElement] = exports.prepend(export); |
887 } | 894 } |
888 }); | 895 }); |
| 896 listener.withCurrentElement(library, () { |
| 897 checkLibraryDependency(listener, export.node, exportedLibraryElement); |
| 898 }); |
889 } | 899 } |
890 | 900 |
891 /** | 901 /** |
892 * Registers the compute export scope with the node library. | 902 * Registers the compute export scope with the node library. |
893 */ | 903 */ |
894 void registerExports() { | 904 void registerExports() { |
895 library.setExports(exportScope.values.toList()); | 905 library.setExports(exportScope.values.toList()); |
896 } | 906 } |
897 | 907 |
898 /** | 908 /** |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 bool changed = false; | 1014 bool changed = false; |
1005 if (!identical(exportScope[element.name], element)) { | 1015 if (!identical(exportScope[element.name], element)) { |
1006 Link<ExportElement> exports = pendingExportMap.putIfAbsent(element, () { | 1016 Link<ExportElement> exports = pendingExportMap.putIfAbsent(element, () { |
1007 changed = true; | 1017 changed = true; |
1008 return const Link<ExportElement>(); | 1018 return const Link<ExportElement>(); |
1009 }); | 1019 }); |
1010 pendingExportMap[element] = exports.prepend(export); | 1020 pendingExportMap[element] = exports.prepend(export); |
1011 } | 1021 } |
1012 return changed; | 1022 return changed; |
1013 } | 1023 } |
| 1024 |
| 1025 /// Check that all names in the show/hide combinators of imports and exports |
| 1026 /// are in the export scope of the imported/exported libraries. |
| 1027 void checkCombinators(DiagnosticListener listener) { |
| 1028 listener.withCurrentElement(library, () { |
| 1029 for (ImportLink importLink in imports) { |
| 1030 checkLibraryDependency( |
| 1031 listener, importLink.import.node, importLink.importedLibrary); |
| 1032 } |
| 1033 }); |
| 1034 for (ExportLink exportLink in dependencies) { |
| 1035 listener.withCurrentElement(exportLink.exportNode.library, () { |
| 1036 checkLibraryDependency(listener, exportLink.export.node, library); |
| 1037 }); |
| 1038 } |
| 1039 } |
| 1040 |
| 1041 /// Check that all names in the show/hide combinators of [tag] are in the |
| 1042 /// export scope of [library]. |
| 1043 void checkLibraryDependency(DiagnosticListener listener, |
| 1044 LibraryDependency tag, |
| 1045 LibraryElement library) { |
| 1046 if (tag == null || tag.combinators == null) return; |
| 1047 for (Combinator combinator in tag.combinators) { |
| 1048 for (Identifier identifier in combinator.identifiers) { |
| 1049 String name = identifier.source; |
| 1050 Element element = library.findExported(name); |
| 1051 if (element == null) { |
| 1052 listener.reportHint( |
| 1053 identifier, |
| 1054 combinator.isHide |
| 1055 ? MessageKind.EMPTY_HIDE : MessageKind.EMPTY_SHOW, |
| 1056 {'uri': library.canonicalUri, |
| 1057 'name': name}); |
| 1058 } |
| 1059 } |
| 1060 } |
| 1061 } |
| 1062 |
1014 } | 1063 } |
1015 | 1064 |
1016 /** | 1065 /** |
1017 * Helper class used for computing the possibly cyclic import/export scopes of | 1066 * Helper class used for computing the possibly cyclic import/export scopes of |
1018 * a set of libraries. | 1067 * a set of libraries. |
1019 * | 1068 * |
1020 * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded | 1069 * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded |
1021 * libraries and to compute their import/export scopes through a fixed-point | 1070 * libraries and to compute their import/export scopes through a fixed-point |
1022 * algorithm. | 1071 * algorithm. |
1023 */ | 1072 */ |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 // scopes to avoid accessing uncomputed export scopes during handling of | 1126 // scopes to avoid accessing uncomputed export scopes during handling of |
1078 // imports. | 1127 // imports. |
1079 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { | 1128 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { |
1080 node.registerExports(); | 1129 node.registerExports(); |
1081 }); | 1130 }); |
1082 | 1131 |
1083 // Setup import scopes. | 1132 // Setup import scopes. |
1084 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { | 1133 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { |
1085 node.registerImports(compiler); | 1134 node.registerImports(compiler); |
1086 }); | 1135 }); |
| 1136 |
| 1137 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { |
| 1138 node.checkCombinators(compiler); |
| 1139 }); |
1087 } | 1140 } |
1088 | 1141 |
1089 /// Registers that [library] depends on [loadedLibrary] through | 1142 /// Registers that [library] depends on [loadedLibrary] through |
1090 /// [libraryDependency]. | 1143 /// [libraryDependency]. |
1091 void registerDependency(LibraryElementX library, | 1144 void registerDependency(LibraryElementX library, |
1092 LibraryDependencyElementX libraryDependency, | 1145 LibraryDependencyElementX libraryDependency, |
1093 LibraryElement loadedLibrary) { | 1146 LibraryElement loadedLibrary) { |
1094 if (libraryDependency.isExport) { | 1147 if (libraryDependency.isExport) { |
1095 // [loadedLibrary] is exported by [library]. | 1148 // [loadedLibrary] is exported by [library]. |
1096 LibraryDependencyNode exportingNode = nodeMap[library]; | 1149 LibraryDependencyNode exportingNode = nodeMap[library]; |
1097 if (loadedLibrary.exportsHandled) { | 1150 if (loadedLibrary.exportsHandled) { |
1098 // Export scope already computed on [loadedLibrary]. | 1151 // Export scope already computed on [loadedLibrary]. |
1099 CombinatorFilter combinatorFilter = | 1152 CombinatorFilter combinatorFilter = |
1100 new CombinatorFilter.fromTag(libraryDependency.node); | 1153 new CombinatorFilter.fromTag(libraryDependency.node); |
1101 exportingNode.registerHandledExports( | 1154 exportingNode.registerHandledExports( |
1102 loadedLibrary, libraryDependency, combinatorFilter); | 1155 compiler, loadedLibrary, libraryDependency, combinatorFilter); |
1103 return; | 1156 return; |
1104 } | 1157 } |
1105 LibraryDependencyNode exportedNode = nodeMap[loadedLibrary]; | 1158 LibraryDependencyNode exportedNode = nodeMap[loadedLibrary]; |
1106 assert(invariant(loadedLibrary, exportedNode != null, | 1159 assert(invariant(loadedLibrary, exportedNode != null, |
1107 message: "$loadedLibrary has not been registered")); | 1160 message: "$loadedLibrary has not been registered")); |
1108 assert(invariant(library, exportingNode != null, | 1161 assert(invariant(library, exportingNode != null, |
1109 message: "$library has not been registered")); | 1162 message: "$library has not been registered")); |
1110 exportedNode.registerExportDependency(libraryDependency, exportingNode); | 1163 exportedNode.registerExportDependency(libraryDependency, exportingNode); |
1111 } else if (libraryDependency == null || libraryDependency.isImport) { | 1164 } else if (libraryDependency == null || libraryDependency.isImport) { |
1112 // [loadedLibrary] is imported by [library]. | 1165 // [loadedLibrary] is imported by [library]. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 } | 1310 } |
1258 suffixes.add(const Link<Uri>().prepend(canonicalUri)); | 1311 suffixes.add(const Link<Uri>().prepend(canonicalUri)); |
1259 } | 1312 } |
1260 suffixChainMap[library] = suffixes; | 1313 suffixChainMap[library] = suffixes; |
1261 return; | 1314 return; |
1262 } | 1315 } |
1263 | 1316 |
1264 computeSuffixes(rootLibrary, const Link<Uri>()); | 1317 computeSuffixes(rootLibrary, const Link<Uri>()); |
1265 } | 1318 } |
1266 } | 1319 } |
OLD | NEW |