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 Backend, | 8 Backend, |
| 9 Compiler, | 9 Compiler, |
| 10 CompilerTask, | 10 CompilerTask, |
| 11 Constant, | 11 Constant, |
| 12 ConstructedConstant, | 12 ConstructedConstant, |
| 13 MessageKind, | 13 MessageKind, |
| 14 StringConstant, | 14 StringConstant, |
| 15 invariant; | 15 invariant, |
| 16 Backend; | |
| 16 | 17 |
| 17 import 'dart_backend/dart_backend.dart' show | 18 import 'dart_backend/dart_backend.dart' show |
| 18 DartBackend; | 19 DartBackend; |
| 19 | 20 |
| 21 import 'js_backend/js_backend.dart' show | |
| 22 JavaScriptBackend; | |
| 23 | |
| 20 import 'elements/elements.dart' show | 24 import 'elements/elements.dart' show |
| 21 Element, | 25 Element, |
| 22 ClassElement, | 26 ClassElement, |
| 23 ElementKind, | 27 ElementKind, |
| 24 Elements, | 28 Elements, |
| 25 FunctionElement, | 29 FunctionElement, |
| 26 LibraryElement, | 30 LibraryElement, |
| 27 MetadataAnnotation, | 31 MetadataAnnotation, |
| 28 ScopeContainerElement, | 32 ScopeContainerElement, |
| 29 PrefixElement, | 33 PrefixElement, |
| 30 ClosureContainer; | 34 ClosureContainer; |
| 31 | 35 |
| 32 import 'util/util.dart' show | 36 import 'util/util.dart' show |
| 33 Link; | 37 Link; |
| 34 | 38 |
| 35 import 'util/setlet.dart' show | 39 import 'util/setlet.dart' show |
| 36 Setlet; | 40 Setlet; |
| 37 | 41 |
| 38 import 'tree/tree.dart' show | 42 import 'tree/tree.dart' show |
| 39 LibraryTag, | 43 LibraryTag, |
| 40 Node, | 44 Node, |
| 41 NewExpression, | 45 NewExpression, |
| 42 Import, | 46 Import, |
| 43 LiteralString, | 47 LiteralString, |
| 44 LiteralDartString; | 48 LiteralDartString; |
| 45 | 49 |
| 50 import 'tree/tree.dart' as ast; | |
| 51 | |
| 46 import 'resolution/resolution.dart' show | 52 import 'resolution/resolution.dart' show |
| 47 TreeElements; | 53 TreeElements; |
| 48 | 54 |
| 49 import 'mirrors_used.dart' show | 55 import 'mirrors_used.dart' show |
| 50 MirrorUsageAnalyzer, | 56 MirrorUsageAnalyzer, |
| 51 MirrorUsageAnalyzerTask, | 57 MirrorUsageAnalyzerTask, |
| 52 MirrorUsage; | 58 MirrorUsage; |
| 53 | 59 |
| 54 /// A "hunk" of the program that will be loaded whenever one of its [imports] | 60 /// A "hunk" of the program that will be loaded whenever one of its [imports] |
| 55 /// are loaded. | 61 /// are loaded. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 OutputUnit outputUnitForConstant(Constant constant) { | 174 OutputUnit outputUnitForConstant(Constant constant) { |
| 169 if (!splitProgram) return mainOutputUnit; | 175 if (!splitProgram) return mainOutputUnit; |
| 170 | 176 |
| 171 return _constantToOutputUnit[constant]; | 177 return _constantToOutputUnit[constant]; |
| 172 } | 178 } |
| 173 | 179 |
| 174 bool isDeferred(Element element) { | 180 bool isDeferred(Element element) { |
| 175 return outputUnitForElement(element) != mainOutputUnit; | 181 return outputUnitForElement(element) != mainOutputUnit; |
| 176 } | 182 } |
| 177 | 183 |
| 184 /// Returns true if e1 and e2 are in the same output unit. | |
| 185 bool inSameOutputUnit(Element e1, Element e2) { | |
| 186 return outputUnitForElement(e1) == outputUnitForElement(e2); | |
| 187 } | |
| 188 | |
| 178 /// Mark that [import] is part of the [OutputputUnit] for [element]. | 189 /// Mark that [import] is part of the [OutputputUnit] for [element]. |
| 179 /// | 190 /// |
| 180 /// [element] can be either a [Constant] or an [Element]. | 191 /// [element] can be either a [Constant] or an [Element]. |
| 181 void _addImportToOutputUnitOfElement(Element element, Import import) { | 192 void _addImportToOutputUnitOfElement(Element element, Import import) { |
| 182 // Only one file should be loaded when the program starts, so make | 193 // Only one file should be loaded when the program starts, so make |
| 183 // sure that only one OutputUnit is created for [fakeMainImport]. | 194 // sure that only one OutputUnit is created for [fakeMainImport]. |
| 184 if (import == _fakeMainImport) { | 195 if (import == _fakeMainImport) { |
| 185 _elementToOutputUnit[element] = mainOutputUnit; | 196 _elementToOutputUnit[element] = mainOutputUnit; |
| 186 } | 197 } |
| 187 _elementToOutputUnit.putIfAbsent(element, () => new OutputUnit()) | 198 _elementToOutputUnit.putIfAbsent(element, () => new OutputUnit()) |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 if (imports.isEmpty) return false; | 256 if (imports.isEmpty) return false; |
| 246 // An element could potentially be loaded by several imports. If all of them | 257 // An element could potentially be loaded by several imports. If all of them |
| 247 // is explicitly deferred, we say the element is explicitly deferred. | 258 // is explicitly deferred, we say the element is explicitly deferred. |
| 248 // TODO(sigurdm): We might want to give a warning if the imports do not | 259 // TODO(sigurdm): We might want to give a warning if the imports do not |
| 249 // agree. | 260 // agree. |
| 250 return imports.every(_isImportDeferred); | 261 return imports.every(_isImportDeferred); |
| 251 } | 262 } |
| 252 | 263 |
| 253 /// Returns a [Link] of every [Import] that imports [element] into [library]. | 264 /// Returns a [Link] of every [Import] that imports [element] into [library]. |
| 254 Link<Import> _getImports(Element element, LibraryElement library) { | 265 Link<Import> _getImports(Element element, LibraryElement library) { |
| 255 if (!element.isTopLevel()) { | 266 if (element.isMember()) { |
| 256 element = element.getEnclosingClass(); | 267 element = element.getEnclosingClass(); |
| 257 } | 268 } |
| 258 | 269 if (element.isAccessor()) { |
| 270 element = (element as FunctionElement).abstractField; | |
| 271 } | |
| 259 return library.getImportsFor(element); | 272 return library.getImportsFor(element); |
| 260 } | 273 } |
| 261 | 274 |
| 262 /// Replaces the imports of [outputUnit] with those in | 275 /// Replaces the imports of [outputUnit] with those in |
| 263 /// [replacementImports]. Because mainOutputUnit has a special handling we | 276 /// [replacementImports]. Because mainOutputUnit has a special handling we |
| 264 /// create a new outputUnit instead, and update the mapping from the | 277 /// create a new outputUnit instead, and update the mapping from the |
| 265 /// dependency to its outputUnit. | 278 /// dependency to its outputUnit. |
| 266 void _replaceOutputUnitImports(dynamic dependency, | 279 void _replaceOutputUnitImports(dynamic dependency, |
| 267 OutputUnit outputUnit, | 280 OutputUnit outputUnit, |
| 268 Iterable<Import> replacementImports) { | 281 Iterable<Import> replacementImports) { |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 770 ? previousDeferredImport | 783 ? previousDeferredImport |
| 771 : import; | 784 : import; |
| 772 compiler.reportError(failingImport.prefix, | 785 compiler.reportError(failingImport.prefix, |
| 773 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); | 786 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); |
| 774 } | 787 } |
| 775 usedPrefixes.add(prefix); | 788 usedPrefixes.add(prefix); |
| 776 } | 789 } |
| 777 } | 790 } |
| 778 }); | 791 }); |
| 779 } | 792 } |
| 793 Backend backend = compiler.backend; | |
| 794 if (splitProgram && backend is JavaScriptBackend) { | |
| 795 backend.registerCheckDeferredIsLoaded(compiler.globalDependencies); | |
| 796 } | |
| 780 if (splitProgram && backend is DartBackend) { | 797 if (splitProgram && backend is DartBackend) { |
| 781 // TODO(sigurdm): Implement deferred loading for dart2dart. | 798 // TODO(sigurdm): Implement deferred loading for dart2dart. |
| 782 splitProgram = false; | 799 splitProgram = false; |
| 783 compiler.reportInfo( | 800 compiler.reportInfo( |
| 784 lastDeferred, | 801 lastDeferred, |
| 785 MessageKind.DEFERRED_LIBRARY_DART_2_DART); | 802 MessageKind.DEFERRED_LIBRARY_DART_2_DART); |
| 786 } | 803 } |
| 787 } | 804 } |
| 805 | |
| 806 /// Returns the prefixElement associated with the first prefix of [send] in | |
| 807 /// the context of [elements] if the prefix of the send resolves to a deferred | |
| 808 /// import. Otherwise returns null. | |
| 809 PrefixElement deferredPrefixElement(ast.Send send, TreeElements elements) { | |
| 810 Element element = elements[send]; | |
| 811 if (element != null && element.isDeferredLoaderGetter()) return null; | |
| 812 ast.Node firstNode(ast.Node node) { | |
| 813 if (node is! ast.Send) { | |
| 814 return node; | |
| 815 } else { | |
| 816 ast.Send send = node; | |
| 817 ast.Node receiver = send.receiver; | |
| 818 ast.Node receiverFirst = firstNode(receiver); | |
| 819 if (receiverFirst != null) { | |
| 820 return receiverFirst; | |
| 821 } else { | |
| 822 return firstNode(send.selector); | |
| 823 } | |
| 824 } | |
| 825 } | |
| 826 ast.Node first = firstNode(send); | |
| 827 if (first is! ast.Identifier) return null; | |
|
Johnni Winther
2014/04/11 07:34:54
Change to:
astNode identifier = first.asIdentifier
sigurdm
2014/04/11 09:11:38
Done.
| |
| 828 Element maybePrefix = elements[first.asIdentifier()]; | |
| 829 if (maybePrefix != null && maybePrefix.isPrefix() && (maybePrefix as | |
|
Johnni Winther
2014/04/11 07:34:54
Change to:
if (maybePrefix != null && maybePrefix.
sigurdm
2014/04/11 09:11:38
Done.
| |
| 830 PrefixElement).isDeferred) { | |
| 831 return maybePrefix; | |
| 832 } | |
| 833 return null; | |
| 834 } | |
| 788 } | 835 } |
| OLD | NEW |