Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/deferred_load.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/sdk/lib/_internal/compiler/implementation/deferred_load.dart |
| index 3e92c1ce93accbd3e1f9fc9bae6af0bb11514d31..0b90d1668fd43906f50c33c8d48825672719fa57 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/deferred_load.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/deferred_load.dart |
| @@ -114,6 +114,7 @@ class DeferredLoadTask extends CompilerTask { |
| /// output units. |
| final Map<String, Set<OutputUnit>> hunksToLoad = |
| new Map<String, Set<OutputUnit>>(); |
| + final Map<Import, String> importDeferName = new Map<Import, String>(); |
| /// A mapping from elements and constants to their output unit. Query this via |
| /// [outputUnitForElement] |
| @@ -197,6 +198,12 @@ class DeferredLoadTask extends CompilerTask { |
| /// the information in [_allDeferredImports] and on the corresponding |
| /// prefixElement. |
| void _markIfDeferred(Import import, LibraryElement library) { |
| + // Check if the import is deferred by a keyword. |
| + if (import.isDeferred) { |
| + _allDeferredImports[import] = library.getLibraryFromTag(import); |
| + return; |
| + } |
| + // Check if the import is deferred by a metadata annotation. |
| Link<MetadataAnnotation> metadataList = import.metadata; |
| if (metadataList == null) return; |
| for (MetadataAnnotation metadata in metadataList) { |
| @@ -211,7 +218,7 @@ class DeferredLoadTask extends CompilerTask { |
| Element maybePrefix = library.find(import.prefix.toString()); |
| if (maybePrefix != null && maybePrefix.isPrefix()) { |
| PrefixElement prefix = maybePrefix; |
| - prefix.markAsDeferred(); |
| + prefix.markAsDeferred(import); |
| } |
| } |
| } |
| @@ -529,50 +536,66 @@ class DeferredLoadTask extends CompilerTask { |
| /// |
| /// Also sets up the [hunksToLoad] mapping. |
| void _assignNamesToOutputUnits(Set<OutputUnit> allOutputUnits) { |
| - Map<Import, String> deferNameCache = new Map<Import, String>(); |
| + Set<String> usedImportNames = new Set<String>(); |
| + |
| + // Returns suggestedName if it is not in usedNames. Otherwise concatenate |
|
floitsch
2014/03/17 14:15:41
concatenates
sigurdm
2014/03/19 12:46:30
Done.
|
| + // the smallest number that makes it not appear in usedNames. |
| + // Adds the result to usedNames. |
| + String makeUnique(String suggestedName, Set<String> usedNames) { |
| + String result = suggestedName; |
| + if (usedNames.contains(suggestedName)) { |
| + int counter = 0; |
| + while (usedNames.contains(result)) { |
| + counter++; |
| + result = "$suggestedName$counter"; |
| + } |
| + } |
| + usedNames.add(result); |
| + return result; |
| + } |
| + |
| // Finds the first argument to the [DeferredLibrary] annotation |
| - String importDeferName(Import import) { |
| - if (deferNameCache.containsKey(import)) return deferNameCache[import]; |
| - if (import == _fakeMainImport) return "main"; |
| - Link<MetadataAnnotation> metadatas = import.metadata; |
| - assert(metadatas != null); |
| + void computeImportDeferName(Import import) { |
| String result; |
| - for (MetadataAnnotation metadata in metadatas) { |
| - metadata.ensureResolved(compiler); |
| - Element element = metadata.value.computeType(compiler).element; |
| - if (metadata.value.computeType(compiler).element == |
| - deferredLibraryClass) { |
| - ConstructedConstant constant = metadata.value; |
| - StringConstant s = constant.fields[0]; |
| - result = s.value.slowToString(); |
| - break; |
| + if (import == _fakeMainImport) { |
| + result = "main"; |
| + } else if (import.isDeferred) { |
| + result = import.prefix.toString(); |
| + } else { |
| + Link<MetadataAnnotation> metadatas = import.metadata; |
| + assert(metadatas != null); |
| + for (MetadataAnnotation metadata in metadatas) { |
| + metadata.ensureResolved(compiler); |
| + Element element = metadata.value.computeType(compiler).element; |
| + if (metadata.value.computeType(compiler).element == |
| + deferredLibraryClass) { |
| + ConstructedConstant constant = metadata.value; |
| + StringConstant s = constant.fields[0]; |
| + result = s.value.slowToString(); |
| + break; |
| + } |
| } |
| } |
| assert(result != null); |
| - deferNameCache[import] = result; |
| - return result; |
| + importDeferName[import] = makeUnique(result, usedImportNames);; |
| } |
| - Set<String> usedNames = new Set<String>(); |
| + Set<String> usedOutputUnitNames = new Set<String>(); |
| Map<OutputUnit, String> generatedNames = new Map<OutputUnit, String>(); |
| void computeOutputUnitName(OutputUnit outputUnit) { |
| if (generatedNames[outputUnit] != null) return; |
| String suggestedName = outputUnit.imports.map((import) { |
| - return importDeferName(import); |
| + return importDeferName[import]; |
| }).join('_'); |
| - if (!usedNames.contains(suggestedName)) { |
| - outputUnit.name = suggestedName; |
| - } else { |
| - int counter = 0; |
| - while (usedNames.contains("$suggestedName$counter")) { |
| - counter++; |
| - } |
| - outputUnit.name = "$suggestedName$counter"; |
| - } |
| + outputUnit.name = makeUnique(suggestedName, usedOutputUnitNames); |
| generatedNames[outputUnit] = outputUnit.name; |
| } |
| + for (Import import in _allDeferredImports.keys) { |
| + computeImportDeferName(import); |
| + } |
| + |
| for (OutputUnit outputUnit in allOutputUnits) { |
| computeOutputUnitName(outputUnit); |
| } |
| @@ -580,11 +603,11 @@ class DeferredLoadTask extends CompilerTask { |
| // For each deferred import we find out which outputUnits to load. |
| for (Import import in _allDeferredImports.keys) { |
| if (import == _fakeMainImport) continue; |
| - hunksToLoad[importDeferName(import)] = new Set<OutputUnit>(); |
| + hunksToLoad[importDeferName[import]] = new Set<OutputUnit>(); |
| for (OutputUnit outputUnit in allOutputUnits) { |
| if (outputUnit == mainOutputUnit) continue; |
| if (outputUnit.imports.contains(import)) { |
| - hunksToLoad[importDeferName(import)].add(outputUnit); |
| + hunksToLoad[importDeferName[import]].add(outputUnit); |
| } |
| } |
| } |
| @@ -657,14 +680,14 @@ class DeferredLoadTask extends CompilerTask { |
| // When detecting duplicate prefixes of deferred libraries there are 4 |
| // cases of duplicate prefixes: |
| // 1. |
| - // @DeferredLibrary("a") import "lib.dart" as a; |
| - // @DeferredLibrary("b") import "lib2.dart" as a; |
| + // import "lib.dart" deferred as a; |
| + // import "lib2.dart" deferred as a; |
| // 2. |
| - // @DeferredLibrary("a") import "lib.dart" as a; |
| + // import "lib.dart" deferred as a; |
| // import "lib2.dart" as a; |
| // 3. |
| // import "lib.dart" as a; |
| - // @DeferredLibrary("a") import "lib2.dart" as a; |
| + // import "lib2.dart" deferred as a; |
| // 4. |
| // import "lib.dart" as a; |
| // import "lib2.dart" as a; |
| @@ -698,7 +721,7 @@ class DeferredLoadTask extends CompilerTask { |
| prefixDeferredImport[prefix] = import; |
| } |
| splitProgram = true; |
| - lastDeferred = import.metadata.first; |
| + lastDeferred = import; |
| } |
| if (prefix != null) { |
| if (previousDeferredImport != null || |