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