| 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 'dart2jslib.dart' show | 7 import 'dart2jslib.dart' show |
| 8 Backend, | |
| 9 Compiler, | 8 Compiler, |
| 10 CompilerTask, | 9 CompilerTask, |
| 11 Constant, | 10 Constant, |
| 12 ConstructedConstant, | 11 ConstructedConstant, |
| 13 MessageKind, | 12 MessageKind, |
| 14 StringConstant, | 13 StringConstant, |
| 15 invariant; | 14 invariant; |
| 16 | 15 |
| 17 import 'dart_backend/dart_backend.dart' show | 16 import 'dart_backend/dart_backend.dart' show |
| 18 DartBackend; | 17 DartBackend; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 | 143 |
| 145 // For each deferred import we want to know exactly what elements have to | 144 // For each deferred import we want to know exactly what elements have to |
| 146 // be loaded. | 145 // be loaded. |
| 147 Map<Import, Set<Element>> _importedDeferredBy = null; | 146 Map<Import, Set<Element>> _importedDeferredBy = null; |
| 148 Map<Import, Set<Constant>> _constantsDeferredBy = null; | 147 Map<Import, Set<Constant>> _constantsDeferredBy = null; |
| 149 | 148 |
| 150 Set<Element> _mainElements = new Set<Element>(); | 149 Set<Element> _mainElements = new Set<Element>(); |
| 151 | 150 |
| 152 DeferredLoadTask(Compiler compiler) : super(compiler); | 151 DeferredLoadTask(Compiler compiler) : super(compiler); |
| 153 | 152 |
| 154 Backend get backend => compiler.backend; | |
| 155 | |
| 156 /// Returns the [OutputUnit] where [element] belongs. | 153 /// Returns the [OutputUnit] where [element] belongs. |
| 157 OutputUnit outputUnitForElement(Element element) { | 154 OutputUnit outputUnitForElement(Element element) { |
| 158 if (!splitProgram) return mainOutputUnit; | 155 if (!splitProgram) return mainOutputUnit; |
| 159 | 156 |
| 160 element = element.implementation; | 157 element = element.implementation; |
| 161 while (!_elementToOutputUnit.containsKey(element)) { | 158 while (!_elementToOutputUnit.containsKey(element)) { |
| 162 element = element.enclosingElement.implementation; | 159 element = element.enclosingElement.implementation; |
| 163 } | 160 } |
| 164 return _elementToOutputUnit[element]; | 161 return _elementToOutputUnit[element]; |
| 165 } | 162 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 Set<Constant> constantDependencies) { | 285 Set<Constant> constantDependencies) { |
| 289 TreeElements elements = | 286 TreeElements elements = |
| 290 compiler.enqueuer.resolution.getCachedElements(element); | 287 compiler.enqueuer.resolution.getCachedElements(element); |
| 291 if (elements == null) return; | 288 if (elements == null) return; |
| 292 for (Element dependency in elements.allElements) { | 289 for (Element dependency in elements.allElements) { |
| 293 if (Elements.isLocal(dependency) && !dependency.isFunction()) continue; | 290 if (Elements.isLocal(dependency) && !dependency.isFunction()) continue; |
| 294 if (Elements.isUnresolved(dependency)) continue; | 291 if (Elements.isUnresolved(dependency)) continue; |
| 295 if (dependency.isStatement()) continue; | 292 if (dependency.isStatement()) continue; |
| 296 elementDependencies.add(dependency); | 293 elementDependencies.add(dependency); |
| 297 } | 294 } |
| 298 elements.forEachConstantNode((Node n, _) { | 295 constantDependencies.addAll(elements.allConstants); |
| 299 // Explicitly depend on the backend constants. | |
| 300 constantDependencies.add( | |
| 301 backend.constants.getConstantForNode(n, elements)); | |
| 302 }); | |
| 303 elementDependencies.addAll(elements.otherDependencies); | 296 elementDependencies.addAll(elements.otherDependencies); |
| 304 } | 297 } |
| 305 | 298 |
| 306 /// Finds all elements and constants that [element] depends directly on. | 299 /// Finds all elements and constants that [element] depends directly on. |
| 307 /// (not the transitive closure.) | 300 /// (not the transitive closure.) |
| 308 /// | 301 /// |
| 309 /// Adds the results to [elements] and [constants]. | 302 /// Adds the results to [elements] and [constants]. |
| 310 void _collectAllElementsAndConstantsResolvedFrom(Element element, | 303 void _collectAllElementsAndConstantsResolvedFrom(Element element, |
| 311 Set<Element> elements, | 304 Set<Element> elements, |
| 312 Set<Constant> constants) { | 305 Set<Constant> constants) { |
| 313 // TODO(sigurdm): How is metadata on a patch-class handled? | 306 // TODO(sigurdm): How is metadata on a patch-class handled? |
| 314 for (MetadataAnnotation metadata in element.metadata) { | 307 for (MetadataAnnotation metadata in element.metadata) { |
| 315 Constant constant = backend.constants.getConstantForMetadata(metadata); | 308 if (metadata.value != null) { |
| 316 if (constant != null) { | 309 constants.add(metadata.value); |
| 317 constants.add(constant); | 310 elements.add(metadata.value.computeType(compiler).element); |
| 318 elements.add(constant.computeType(compiler).element); | |
| 319 } | 311 } |
| 320 } | 312 } |
| 321 if (element.isClass()) { | 313 if (element.isClass()) { |
| 322 // If we see a class, add everything its instance members refer | 314 // If we see a class, add everything its instance members refer |
| 323 // to. Static members are not relevant. | 315 // to. Static members are not relevant. |
| 324 ClassElement cls = element.declaration; | 316 ClassElement cls = element.declaration; |
| 325 cls.forEachLocalMember((Element e) { | 317 cls.forEachLocalMember((Element e) { |
| 326 if (!e.isInstanceMember()) return; | 318 if (!e.isInstanceMember()) return; |
| 327 _collectDependencies(e.implementation, elements, constants); | 319 _collectDependencies(e.implementation, elements, constants); |
| 328 }); | 320 }); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 MirrorUsageAnalyzerTask mirrorTask = compiler.mirrorUsageAnalyzerTask; | 412 MirrorUsageAnalyzerTask mirrorTask = compiler.mirrorUsageAnalyzerTask; |
| 421 // For each import we record all mirrors-used elements from all the | 413 // For each import we record all mirrors-used elements from all the |
| 422 // libraries reached directly from that import. | 414 // libraries reached directly from that import. |
| 423 for (Import deferredImport in _allDeferredImports.keys) { | 415 for (Import deferredImport in _allDeferredImports.keys) { |
| 424 LibraryElement deferredLibrary = _allDeferredImports[deferredImport]; | 416 LibraryElement deferredLibrary = _allDeferredImports[deferredImport]; |
| 425 for (LibraryElement library in | 417 for (LibraryElement library in |
| 426 _nonDeferredReachableLibraries(deferredLibrary)) { | 418 _nonDeferredReachableLibraries(deferredLibrary)) { |
| 427 // TODO(sigurdm): The metadata should go to the right output unit. | 419 // TODO(sigurdm): The metadata should go to the right output unit. |
| 428 // For now they all go to the main output unit. | 420 // For now they all go to the main output unit. |
| 429 for (MetadataAnnotation metadata in library.metadata) { | 421 for (MetadataAnnotation metadata in library.metadata) { |
| 430 Constant constant = | 422 if (metadata.value != null) { |
| 431 backend.constants.getConstantForMetadata(metadata); | 423 _mapDependencies(metadata.value.computeType(compiler).element, |
| 432 if (constant != null) { | |
| 433 _mapDependencies(constant.computeType(compiler).element, | |
| 434 _fakeMainImport); | 424 _fakeMainImport); |
| 435 } | 425 } |
| 436 } | 426 } |
| 437 for (LibraryTag tag in library.tags) { | 427 for (LibraryTag tag in library.tags) { |
| 438 for (MetadataAnnotation metadata in tag.metadata) { | 428 for (MetadataAnnotation metadata in tag.metadata) { |
| 439 Constant constant = | 429 if (metadata.value != null) { |
| 440 backend.constants.getConstantForMetadata(metadata); | 430 _mapDependencies(metadata.value.computeType(compiler).element, |
| 441 if (constant != null) { | |
| 442 _mapDependencies(constant.computeType(compiler).element, | |
| 443 _fakeMainImport); | 431 _fakeMainImport); |
| 444 } | 432 } |
| 445 } | 433 } |
| 446 } | 434 } |
| 447 | 435 |
| 448 if (mirrorTask.librariesWithUsage.contains(library)) { | 436 if (mirrorTask.librariesWithUsage.contains(library)) { |
| 449 | 437 |
| 450 Map<LibraryElement, List<MirrorUsage>> mirrorsResult = | 438 Map<LibraryElement, List<MirrorUsage>> mirrorsResult = |
| 451 mirrorTask.analyzer.collectMirrorsUsedAnnotation(); | 439 mirrorTask.analyzer.collectMirrorsUsedAnnotation(); |
| 452 | 440 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 if (import == _fakeMainImport) { | 589 if (import == _fakeMainImport) { |
| 602 result = "main"; | 590 result = "main"; |
| 603 } else if (import.isDeferred) { | 591 } else if (import.isDeferred) { |
| 604 result = import.prefix.toString(); | 592 result = import.prefix.toString(); |
| 605 } else { | 593 } else { |
| 606 Link<MetadataAnnotation> metadatas = import.metadata; | 594 Link<MetadataAnnotation> metadatas = import.metadata; |
| 607 assert(metadatas != null); | 595 assert(metadatas != null); |
| 608 for (MetadataAnnotation metadata in metadatas) { | 596 for (MetadataAnnotation metadata in metadatas) { |
| 609 metadata.ensureResolved(compiler); | 597 metadata.ensureResolved(compiler); |
| 610 Element element = metadata.value.computeType(compiler).element; | 598 Element element = metadata.value.computeType(compiler).element; |
| 611 if (element == deferredLibraryClass) { | 599 if (metadata.value.computeType(compiler).element == |
| 600 deferredLibraryClass) { |
| 612 ConstructedConstant constant = metadata.value; | 601 ConstructedConstant constant = metadata.value; |
| 613 StringConstant s = constant.fields[0]; | 602 StringConstant s = constant.fields[0]; |
| 614 result = s.value.slowToString(); | 603 result = s.value.slowToString(); |
| 615 break; | 604 break; |
| 616 } | 605 } |
| 617 } | 606 } |
| 618 } | 607 } |
| 619 assert(result != null); | 608 assert(result != null); |
| 620 importDeferName[import] = makeUnique(result, usedImportNames);; | 609 importDeferName[import] = makeUnique(result, usedImportNames);; |
| 621 } | 610 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 ? previousDeferredImport | 759 ? previousDeferredImport |
| 771 : import; | 760 : import; |
| 772 compiler.reportError(failingImport.prefix, | 761 compiler.reportError(failingImport.prefix, |
| 773 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); | 762 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); |
| 774 } | 763 } |
| 775 usedPrefixes.add(prefix); | 764 usedPrefixes.add(prefix); |
| 776 } | 765 } |
| 777 } | 766 } |
| 778 }); | 767 }); |
| 779 } | 768 } |
| 780 if (splitProgram && backend is DartBackend) { | 769 if (splitProgram && compiler.backend is DartBackend) { |
| 781 // TODO(sigurdm): Implement deferred loading for dart2dart. | 770 // TODO(sigurdm): Implement deferred loading for dart2dart. |
| 782 splitProgram = false; | 771 splitProgram = false; |
| 783 compiler.reportInfo( | 772 compiler.reportInfo( |
| 784 lastDeferred, | 773 lastDeferred, |
| 785 MessageKind.DEFERRED_LIBRARY_DART_2_DART); | 774 MessageKind.DEFERRED_LIBRARY_DART_2_DART); |
| 786 } | 775 } |
| 787 } | 776 } |
| 788 } | 777 } |
| OLD | NEW |