Chromium Code Reviews| 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 Compiler, | 8 Compiler, |
| 9 CompilerTask, | 9 CompilerTask, |
| 10 Constant, | 10 Constant, |
| 11 ConstructedConstant, | 11 ConstructedConstant, |
| 12 MessageKind, | 12 MessageKind, |
| 13 StringConstant, | 13 StringConstant, |
| 14 invariant; | 14 invariant; |
| 15 | 15 |
| 16 import 'dart_backend/dart_backend.dart' show | |
| 17 DartBackend; | |
| 18 | |
| 16 import 'elements/elements.dart' show | 19 import 'elements/elements.dart' show |
| 17 Element, | 20 Element, |
| 18 ClassElement, | 21 ClassElement, |
| 19 ElementKind, | 22 ElementKind, |
| 20 Elements, | 23 Elements, |
| 21 FunctionElement, | 24 FunctionElement, |
| 22 LibraryElement, | 25 LibraryElement, |
| 23 MetadataAnnotation, | 26 MetadataAnnotation, |
| 24 ScopeContainerElement, | 27 ScopeContainerElement, |
| 28 PrefixElement, | |
| 25 ClosureContainer; | 29 ClosureContainer; |
| 26 | 30 |
| 27 import 'util/util.dart' show | 31 import 'util/util.dart' show |
| 28 Link; | 32 Link; |
| 29 | 33 |
| 30 import 'util/setlet.dart' show | 34 import 'util/setlet.dart' show |
| 31 Setlet; | 35 Setlet; |
| 32 | 36 |
| 33 import 'tree/tree.dart' show | 37 import 'tree/tree.dart' show |
| 34 LibraryTag, | 38 LibraryTag, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 // sure that only one OutputUnit is created for [fakeMainImport]. | 183 // sure that only one OutputUnit is created for [fakeMainImport]. |
| 180 if (import == _fakeMainImport) { | 184 if (import == _fakeMainImport) { |
| 181 _constantToOutputUnit[constant] = mainOutputUnit; | 185 _constantToOutputUnit[constant] = mainOutputUnit; |
| 182 } | 186 } |
| 183 _constantToOutputUnit.putIfAbsent(constant, () => new OutputUnit()) | 187 _constantToOutputUnit.putIfAbsent(constant, () => new OutputUnit()) |
| 184 .imports.add(import); | 188 .imports.add(import); |
| 185 } | 189 } |
| 186 | 190 |
| 187 /// Answers whether the [import] has a [DeferredLibrary] annotation. | 191 /// Answers whether the [import] has a [DeferredLibrary] annotation. |
| 188 bool _isImportDeferred(Import import) { | 192 bool _isImportDeferred(Import import) { |
| 193 return _allDeferredImports.containsKey(import); | |
| 194 } | |
| 195 | |
| 196 /// Checks whether the [import] has a [DeferredLibrary] annotation and stores | |
| 197 /// the information in [_allDeferredImports] and on the corresponding | |
| 198 /// prefixElement. | |
| 199 void _markIfDeferred(Import import, LibraryElement library) { | |
| 189 Link<MetadataAnnotation> metadatalist = import.metadata; | 200 Link<MetadataAnnotation> metadatalist = import.metadata; |
|
floitsch
2014/03/03 14:18:06
metadataList ?
sigurdm
2014/03/04 12:36:19
Done.
| |
| 190 if (metadatalist == null) return false; | 201 if (metadatalist == null) return; |
| 191 for (MetadataAnnotation metadata in metadatalist) { | 202 for (MetadataAnnotation metadata in metadatalist) { |
| 192 metadata.ensureResolved(compiler); | 203 metadata.ensureResolved(compiler); |
| 193 Element element = metadata.value.computeType(compiler).element; | 204 Element element = metadata.value.computeType(compiler).element; |
| 194 if (metadata.value.computeType(compiler).element | 205 if (metadata.value.computeType(compiler).element == |
|
floitsch
2014/03/03 14:18:06
you element just one line above.
if (element == d
sigurdm
2014/03/04 12:36:19
Done.
| |
| 195 == deferredLibraryClass) { | 206 deferredLibraryClass) { |
| 196 return true; | 207 _allDeferredImports[import] = library.getLibraryFromTag(import); |
| 208 Element maybePrefix = library.find(import.prefix.toString()); | |
| 209 if (maybePrefix != null && maybePrefix.isPrefix()) { | |
| 210 PrefixElement prefix = maybePrefix; | |
| 211 prefix.markAsDeferred(); | |
| 212 } | |
| 197 } | 213 } |
| 198 } | 214 } |
| 199 return false; | |
| 200 } | 215 } |
| 201 | 216 |
| 202 /// Answers whether [element] is explicitly deferred when referred to from | 217 /// Answers whether [element] is explicitly deferred when referred to from |
| 203 /// [library]. | 218 /// [library]. |
| 204 bool _isExplicitlyDeferred(Element element, LibraryElement library) { | 219 bool _isExplicitlyDeferred(Element element, LibraryElement library) { |
| 205 Link<Import> imports = _getImports(element, library); | 220 Link<Import> imports = _getImports(element, library); |
| 206 // If the element is not imported explicitly, it is implicitly imported | 221 // If the element is not imported explicitly, it is implicitly imported |
| 207 // not deferred. | 222 // not deferred. |
| 208 if (imports.isEmpty) return false; | 223 if (imports.isEmpty) return false; |
| 209 // An element could potentially be loaded by several imports. If all of them | 224 // An element could potentially be loaded by several imports. If all of them |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 // 2. | 640 // 2. |
| 626 // @DeferredLibrary("a") import "lib.dart" as a; | 641 // @DeferredLibrary("a") import "lib.dart" as a; |
| 627 // import "lib2.dart" as a; | 642 // import "lib2.dart" as a; |
| 628 // 3. | 643 // 3. |
| 629 // import "lib.dart" as a; | 644 // import "lib.dart" as a; |
| 630 // @DeferredLibrary("a") import "lib2.dart" as a; | 645 // @DeferredLibrary("a") import "lib2.dart" as a; |
| 631 // 4. | 646 // 4. |
| 632 // import "lib.dart" as a; | 647 // import "lib.dart" as a; |
| 633 // import "lib2.dart" as a; | 648 // import "lib2.dart" as a; |
| 634 // We must be able to signal error for case 1, 2, 3, but accept case 4. | 649 // We must be able to signal error for case 1, 2, 3, but accept case 4. |
| 635 | 650 |
| 636 // The prefixes that have been used by any imports in this library. | 651 // The prefixes that have been used by any imports in this library. |
| 637 Setlet<String> usedPrefixes = new Setlet<String>(); | 652 Setlet<String> usedPrefixes = new Setlet<String>(); |
| 638 // The last deferred import we saw with a given prefix (if any). | 653 // The last deferred import we saw with a given prefix (if any). |
| 639 Map<String, Import> prefixDeferredImport = new Map<String, Import>(); | 654 Map<String, Import> prefixDeferredImport = new Map<String, Import>(); |
| 640 for (LibraryElement library in compiler.libraries.values) { | 655 for (LibraryElement library in compiler.libraries.values) { |
| 641 compiler.withCurrentElement(library, () { | 656 compiler.withCurrentElement(library, () { |
| 642 prefixDeferredImport.clear(); | 657 prefixDeferredImport.clear(); |
| 643 usedPrefixes.clear(); | 658 usedPrefixes.clear(); |
| 644 // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List | 659 // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List |
| 645 // instead of a Link. | 660 // instead of a Link. |
| 646 for (LibraryTag tag in library.tags) { | 661 for (LibraryTag tag in library.tags) { |
| 647 if (tag is! Import) continue; | 662 if (tag is! Import) continue; |
| 648 Import import = tag; | 663 Import import = tag; |
| 664 _markIfDeferred(import, library); | |
| 649 String prefix = (import.prefix != null) | 665 String prefix = (import.prefix != null) |
| 650 ? import.prefix.toString() | 666 ? import.prefix.toString() |
| 651 : null; | 667 : null; |
| 652 // The last import we saw with the same prefix. | 668 // The last import we saw with the same prefix. |
| 653 Import previousDeferredImport = prefixDeferredImport[prefix]; | 669 Import previousDeferredImport = prefixDeferredImport[prefix]; |
| 654 bool isDeferred = _isImportDeferred(import); | 670 bool isDeferred = _isImportDeferred(import); |
| 655 if (isDeferred) { | 671 if (isDeferred) { |
| 656 if (prefix == null) { | 672 if (prefix == null) { |
| 657 compiler.reportError(import, | 673 compiler.reportError(import, |
| 658 MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX); | 674 MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX); |
| 659 } else { | 675 } else { |
| 660 prefixDeferredImport[prefix] = import; | 676 prefixDeferredImport[prefix] = import; |
| 661 } | 677 } |
| 662 splitProgram = true; | 678 splitProgram = true; |
| 663 _allDeferredImports[tag] = library.getLibraryFromTag(tag); | |
| 664 lastDeferred = import.metadata.first; | 679 lastDeferred = import.metadata.first; |
| 665 if (library == compiler.mainApp) { | 680 if (library == compiler.mainApp) { |
| 666 deferredUsedFromMain = true; | 681 deferredUsedFromMain = true; |
| 667 } | 682 } |
| 668 } | 683 } |
| 669 if (prefix != null) { | 684 if (prefix != null) { |
| 670 if (previousDeferredImport != null || | 685 if (previousDeferredImport != null || |
| 671 (isDeferred && usedPrefixes.contains(prefix))) { | 686 (isDeferred && usedPrefixes.contains(prefix))) { |
| 672 Import failingImport = (previousDeferredImport != null) | 687 Import failingImport = (previousDeferredImport != null) |
| 673 ? previousDeferredImport | 688 ? previousDeferredImport |
| 674 : import; | 689 : import; |
| 675 compiler.reportError(failingImport.prefix, | 690 compiler.reportError(failingImport.prefix, |
| 676 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); | 691 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); |
| 677 } | 692 } |
| 678 usedPrefixes.add(prefix); | 693 usedPrefixes.add(prefix); |
| 679 } | 694 } |
| 680 } | 695 } |
| 681 }); | 696 }); |
| 682 } | 697 } |
| 698 if (splitProgram && compiler.backend is DartBackend) { | |
| 699 // TODO(sigurdm): Implement deferred loading for dart2dart. | |
| 700 splitProgram = false; | |
| 701 compiler.reportInfo( | |
| 702 lastDeferred, | |
| 703 MessageKind.DEFERRED_LIBRARY_DART_2_DART); | |
| 704 } | |
| 683 if (splitProgram && !deferredUsedFromMain) { | 705 if (splitProgram && !deferredUsedFromMain) { |
| 684 compiler.reportInfo( | 706 compiler.reportInfo( |
| 685 lastDeferred, | 707 lastDeferred, |
| 686 MessageKind.DEFERRED_LIBRARY_NOT_FROM_MAIN); | 708 MessageKind.DEFERRED_LIBRARY_NOT_FROM_MAIN); |
| 687 splitProgram = false; | 709 splitProgram = false; |
| 688 } | 710 } |
| 689 } | 711 } |
| 690 } | 712 } |
| OLD | NEW |