| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 deferred_load; | 5 library deferred_load; |
| 6 | 6 |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import 'common/tasks.dart' show CompilerTask; | 9 import 'common/tasks.dart' show CompilerTask; |
| 10 import 'common.dart'; | 10 import 'common.dart'; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3 | 126 /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3 |
| 127 /// can be loaded in parallel. And finally lib1 can be loaded. | 127 /// can be loaded in parallel. And finally lib1 can be loaded. |
| 128 final Map<String, List<OutputUnit>> hunksToLoad = | 128 final Map<String, List<OutputUnit>> hunksToLoad = |
| 129 new Map<String, List<OutputUnit>>(); | 129 new Map<String, List<OutputUnit>>(); |
| 130 | 130 |
| 131 /// A cache of the result of calling `computeImportDeferName` on the keys of | 131 /// A cache of the result of calling `computeImportDeferName` on the keys of |
| 132 /// this map. | 132 /// this map. |
| 133 final Map<ImportElement, String> _importDeferName = <ImportElement, String>{}; | 133 final Map<ImportElement, String> _importDeferName = <ImportElement, String>{}; |
| 134 | 134 |
| 135 /// A mapping from elements and constants to their output unit. Query this via | 135 /// A mapping from elements and constants to their output unit. Query this via |
| 136 /// [outputUnitForElement] | 136 /// [outputUnitForEntity] |
| 137 final Map<Entity, ImportSet> _elementToSet = new Map<Entity, ImportSet>(); | 137 final Map<Entity, ImportSet> _elementToSet = new Map<Entity, ImportSet>(); |
| 138 | 138 |
| 139 /// A mapping from constants to their output unit. Query this via | 139 /// A mapping from constants to their output unit. Query this via |
| 140 /// [outputUnitForConstant] | 140 /// [outputUnitForConstant] |
| 141 final Map<ConstantValue, ImportSet> _constantToSet = | 141 final Map<ConstantValue, ImportSet> _constantToSet = |
| 142 new Map<ConstantValue, ImportSet>(); | 142 new Map<ConstantValue, ImportSet>(); |
| 143 | 143 |
| 144 Iterable<ImportElement> get _allDeferredImports => | 144 Iterable<ImportElement> get _allDeferredImports => |
| 145 _deferredImportDescriptions.keys; | 145 _deferredImportDescriptions.keys; |
| 146 | 146 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 158 super(compiler.measurer) { | 158 super(compiler.measurer) { |
| 159 mainOutputUnit = new OutputUnit(true, 'main', new Set<ImportElement>()); | 159 mainOutputUnit = new OutputUnit(true, 'main', new Set<ImportElement>()); |
| 160 importSets.mainSet.unit = mainOutputUnit; | 160 importSets.mainSet.unit = mainOutputUnit; |
| 161 allOutputUnits.add(mainOutputUnit); | 161 allOutputUnits.add(mainOutputUnit); |
| 162 } | 162 } |
| 163 | 163 |
| 164 JavaScriptBackend get backend => compiler.backend; | 164 JavaScriptBackend get backend => compiler.backend; |
| 165 DiagnosticReporter get reporter => compiler.reporter; | 165 DiagnosticReporter get reporter => compiler.reporter; |
| 166 | 166 |
| 167 /// Returns the [OutputUnit] where [element] belongs. | 167 /// Returns the [OutputUnit] where [element] belongs. |
| 168 OutputUnit outputUnitForElement(Entity entity) { | 168 OutputUnit outputUnitForEntity(Entity entity) { |
| 169 // TODO(johnniwinther): Support use of entities by splitting maps by | 169 // TODO(johnniwinther): Support use of entities by splitting maps by |
| 170 // entity kind. | 170 // entity kind. |
| 171 if (!isProgramSplit) return mainOutputUnit; | 171 if (!isProgramSplit) return mainOutputUnit; |
| 172 Element element = entity; | 172 Element element = entity; |
| 173 element = element.implementation; | 173 element = element.implementation; |
| 174 while (!_elementToSet.containsKey(element)) { | 174 while (!_elementToSet.containsKey(element)) { |
| 175 // TODO(21051): workaround: it looks like we output annotation constants | 175 // TODO(21051): workaround: it looks like we output annotation constants |
| 176 // for classes that we don't include in the output. This seems to happen | 176 // for classes that we don't include in the output. This seems to happen |
| 177 // when we have reflection but can see that some classes are not needed. | 177 // when we have reflection but can see that some classes are not needed. |
| 178 // We still add the annotation but don't run through it below (where we | 178 // We still add the annotation but don't run through it below (where we |
| 179 // assign every element to its output unit). | 179 // assign every element to its output unit). |
| 180 if (element.enclosingElement == null) { | 180 if (element.enclosingElement == null) { |
| 181 _elementToSet[element] = importSets.mainSet; | 181 _elementToSet[element] = importSets.mainSet; |
| 182 break; | 182 break; |
| 183 } | 183 } |
| 184 element = element.enclosingElement.implementation; | 184 element = element.enclosingElement.implementation; |
| 185 } | 185 } |
| 186 return _elementToSet[element].unit; | 186 return _elementToSet[element].unit; |
| 187 } | 187 } |
| 188 | 188 |
| 189 /// Returns the [OutputUnit] where [element] belongs. | 189 /// Returns the [OutputUnit] where [element] belongs. |
| 190 OutputUnit outputUnitForClass(ClassEntity element) { | 190 OutputUnit outputUnitForClass(ClassEntity element) { |
| 191 return outputUnitForElement(element); | 191 return outputUnitForEntity(element); |
| 192 } | 192 } |
| 193 | 193 |
| 194 /// Returns the [OutputUnit] where [element] belongs. | 194 /// Returns the [OutputUnit] where [element] belongs. |
| 195 OutputUnit outputUnitForMember(MemberEntity element) { | 195 OutputUnit outputUnitForMember(MemberEntity element) { |
| 196 return outputUnitForElement(element); | 196 return outputUnitForEntity(element); |
| 197 } | 197 } |
| 198 | 198 |
| 199 /// Direct access to the output-unit to element relation used for testing. | 199 /// Direct access to the output-unit to element relation used for testing. |
| 200 OutputUnit getOutputUnitForElementForTesting(Entity element) { | 200 OutputUnit getOutputUnitForElementForTesting(Entity element) { |
| 201 return _elementToSet[element]?.unit; | 201 return _elementToSet[element]?.unit; |
| 202 } | 202 } |
| 203 | 203 |
| 204 /// Returns the [OutputUnit] where [constant] belongs. | 204 /// Returns the [OutputUnit] where [constant] belongs. |
| 205 OutputUnit outputUnitForConstant(ConstantValue constant) { | 205 OutputUnit outputUnitForConstant(ConstantValue constant) { |
| 206 if (!isProgramSplit) return mainOutputUnit; | 206 if (!isProgramSplit) return mainOutputUnit; |
| 207 return _constantToSet[constant]?.unit; | 207 return _constantToSet[constant]?.unit; |
| 208 } | 208 } |
| 209 | 209 |
| 210 /// Direct access to the output-unit to constants map used for testing. | 210 /// Direct access to the output-unit to constants map used for testing. |
| 211 Iterable<ConstantValue> get constantsForTesting => _constantToSet.keys; | 211 Iterable<ConstantValue> get constantsForTesting => _constantToSet.keys; |
| 212 | 212 |
| 213 bool isDeferred(Entity element) { | 213 bool isDeferred(Entity element) { |
| 214 return outputUnitForElement(element) != mainOutputUnit; | 214 return outputUnitForEntity(element) != mainOutputUnit; |
| 215 } | 215 } |
| 216 | 216 |
| 217 bool isDeferredClass(ClassEntity element) { | 217 bool isDeferredClass(ClassEntity element) { |
| 218 return outputUnitForElement(element) != mainOutputUnit; | 218 return outputUnitForEntity(element) != mainOutputUnit; |
| 219 } | 219 } |
| 220 | 220 |
| 221 /// Returns the unique name for the deferred import of [prefix]. | 221 /// Returns the unique name for the deferred import of [prefix]. |
| 222 String getImportDeferName(Spannable node, PrefixElement prefix) { | 222 String getImportDeferName(Spannable node, PrefixElement prefix) { |
| 223 String name = _importDeferName[prefix.deferredImport]; | 223 String name = _importDeferName[prefix.deferredImport]; |
| 224 if (name == null) { | 224 if (name == null) { |
| 225 reporter.internalError(node, "No deferred name for $prefix."); | 225 reporter.internalError(node, "No deferred name for $prefix."); |
| 226 } | 226 } |
| 227 return name; | 227 return name; |
| 228 } | 228 } |
| 229 | 229 |
| 230 /// Returns the names associated with each deferred import in [unit]. | 230 /// Returns the names associated with each deferred import in [unit]. |
| 231 Iterable<String> getImportNames(OutputUnit unit) { | 231 Iterable<String> getImportNames(OutputUnit unit) { |
| 232 return unit._imports.map((i) => _importDeferName[i]); | 232 return unit._imports.map((i) => _importDeferName[i]); |
| 233 } | 233 } |
| 234 | 234 |
| 235 /// Returns `true` if element [to] is reachable from element [from] without | 235 /// Returns `true` if element [to] is reachable from element [from] without |
| 236 /// crossing a deferred import. | 236 /// crossing a deferred import. |
| 237 /// | 237 /// |
| 238 /// For example, if we have two deferred libraries `A` and `B` that both | 238 /// For example, if we have two deferred libraries `A` and `B` that both |
| 239 /// import a library `C`, then even though elements from `A` and `C` end up in | 239 /// import a library `C`, then even though elements from `A` and `C` end up in |
| 240 /// different output units, there is a non-deferred path between `A` and `C`. | 240 /// different output units, there is a non-deferred path between `A` and `C`. |
| 241 bool hasOnlyNonDeferredImportPaths(Entity from, Entity to) { | 241 bool hasOnlyNonDeferredImportPaths(Entity from, Entity to) { |
| 242 OutputUnit outputUnitFrom = outputUnitForElement(from); | 242 OutputUnit outputUnitFrom = outputUnitForEntity(from); |
| 243 OutputUnit outputUnitTo = outputUnitForElement(to); | 243 OutputUnit outputUnitTo = outputUnitForEntity(to); |
| 244 if (outputUnitTo == mainOutputUnit) return true; | 244 if (outputUnitTo == mainOutputUnit) return true; |
| 245 if (outputUnitFrom == mainOutputUnit) return false; | 245 if (outputUnitFrom == mainOutputUnit) return false; |
| 246 return outputUnitTo._imports.containsAll(outputUnitFrom._imports); | 246 return outputUnitTo._imports.containsAll(outputUnitFrom._imports); |
| 247 } | 247 } |
| 248 | 248 |
| 249 void registerConstantDeferredUse( | 249 void registerConstantDeferredUse( |
| 250 DeferredConstantValue constant, PrefixElement prefix) { | 250 DeferredConstantValue constant, PrefixElement prefix) { |
| 251 var newSet = importSets.singleton(prefix.deferredImport); | 251 var newSet = importSets.singleton(prefix.deferredImport); |
| 252 assert( | 252 assert( |
| 253 _constantToSet[constant] == null || _constantToSet[constant] == newSet); | 253 _constantToSet[constant] == null || _constantToSet[constant] == newSet); |
| (...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1385 ConstructedConstantValue constant = value; | 1385 ConstructedConstantValue constant = value; |
| 1386 StringConstantValue s = constant.fields.values.single; | 1386 StringConstantValue s = constant.fields.values.single; |
| 1387 result = s.primitiveValue; | 1387 result = s.primitiveValue; |
| 1388 break; | 1388 break; |
| 1389 } | 1389 } |
| 1390 } | 1390 } |
| 1391 } | 1391 } |
| 1392 assert(result != null); | 1392 assert(result != null); |
| 1393 return result; | 1393 return result; |
| 1394 } | 1394 } |
| OLD | NEW |