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, |
(...skipping 28 matching lines...) Expand all Loading... |
39 LiteralDartString; | 39 LiteralDartString; |
40 | 40 |
41 import 'resolution/resolution.dart' show | 41 import 'resolution/resolution.dart' show |
42 TreeElements; | 42 TreeElements; |
43 | 43 |
44 import 'mirrors_used.dart' show | 44 import 'mirrors_used.dart' show |
45 MirrorUsageAnalyzer, | 45 MirrorUsageAnalyzer, |
46 MirrorUsageAnalyzerTask, | 46 MirrorUsageAnalyzerTask, |
47 MirrorUsage; | 47 MirrorUsage; |
48 | 48 |
49 import "dart_types.dart" show | |
50 DartType, | |
51 VoidType, | |
52 InterfaceType, | |
53 FunctionType, | |
54 TypeVariableType, | |
55 MalformedType, | |
56 TypedefType; | |
57 | |
58 /// A "hunk" of the program that will be loaded whenever one of its [imports] | 49 /// A "hunk" of the program that will be loaded whenever one of its [imports] |
59 /// are loaded. | 50 /// are loaded. |
60 /// | 51 /// |
61 /// Elements that are only used in one deferred import, is in an OutputUnit with | 52 /// Elements that are only used in one deferred import, is in an OutputUnit with |
62 /// the deferred import as single element in the [imports] set. | 53 /// the deferred import as single element in the [imports] set. |
63 /// | 54 /// |
64 /// Whenever a deferred Element is shared between several deferred imports it is | 55 /// Whenever a deferred Element is shared between several deferred imports it is |
65 /// in an output unit with those imports in the [imports] Set. | 56 /// in an output unit with those imports in the [imports] Set. |
66 /// | 57 /// |
67 /// OutputUnits are equal if their [imports] are equal. | 58 /// OutputUnits are equal if their [imports] are equal. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 /// [LibraryElement] they import. | 125 /// [LibraryElement] they import. |
135 /// The main library is included in this set for convenience. | 126 /// The main library is included in this set for convenience. |
136 final Map<Import, LibraryElement> _allDeferredImports = | 127 final Map<Import, LibraryElement> _allDeferredImports = |
137 new Map<Import, LibraryElement>(); | 128 new Map<Import, LibraryElement>(); |
138 | 129 |
139 // For each deferred import we want to know exactly what elements have to | 130 // For each deferred import we want to know exactly what elements have to |
140 // be loaded. | 131 // be loaded. |
141 Map<Import, Set<Element>> _importedDeferredBy = null; | 132 Map<Import, Set<Element>> _importedDeferredBy = null; |
142 Map<Import, Set<Constant>> _constantsDeferredBy = null; | 133 Map<Import, Set<Constant>> _constantsDeferredBy = null; |
143 | 134 |
144 // The types we have visited in [addNestedTypes]. | |
145 Set<DartType> _visitedTypes; | |
146 | |
147 Set<Element> _mainElements = new Set<Element>(); | 135 Set<Element> _mainElements = new Set<Element>(); |
148 | 136 |
149 DeferredLoadTask(Compiler compiler) : super(compiler); | 137 DeferredLoadTask(Compiler compiler) : super(compiler); |
150 | 138 |
151 /// Returns the [OutputUnit] where [element] belongs. | 139 /// Returns the [OutputUnit] where [element] belongs. |
152 OutputUnit outputUnitForElement(Element element) { | 140 OutputUnit outputUnitForElement(Element element) { |
153 if (!splitProgram) return mainOutputUnit; | 141 if (!splitProgram) return mainOutputUnit; |
154 | 142 |
155 element = element.implementation; | 143 element = element.implementation; |
156 while (!_elementToOutputUnit.containsKey(element)) { | 144 while (!_elementToOutputUnit.containsKey(element)) { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 if (!e.isInstanceMember()) return; | 281 if (!e.isInstanceMember()) return; |
294 _collectDependencies(e.implementation, elements, constants); | 282 _collectDependencies(e.implementation, elements, constants); |
295 }); | 283 }); |
296 if (cls.implementation != cls) { | 284 if (cls.implementation != cls) { |
297 // TODO(ahe): Why doesn't ClassElement.forEachLocalMember do this? | 285 // TODO(ahe): Why doesn't ClassElement.forEachLocalMember do this? |
298 cls.implementation.forEachLocalMember((Element e) { | 286 cls.implementation.forEachLocalMember((Element e) { |
299 if (!e.isInstanceMember()) return; | 287 if (!e.isInstanceMember()) return; |
300 _collectDependencies(e.implementation, elements, constants); | 288 _collectDependencies(e.implementation, elements, constants); |
301 }); | 289 }); |
302 } | 290 } |
303 // Adds, recursively, to [elements] any types the [type] depends on in its | 291 for (var type in cls.implementation.allSupertypes) { |
304 // type arguments. | |
305 void addNestedTypes(DartType type) { | |
306 if (_visitedTypes.contains(type)) return; | |
307 _visitedTypes.add(type); | |
308 // Gives a FunctionType from a TypedefType. | |
309 type = type.unalias(compiler); | |
310 // Only add concrete types. | |
311 if (type is VoidType) return; | |
312 if (type is TypeVariableType) return; | |
313 if (type is MalformedType) return; | |
314 if (type is FunctionType) { | |
315 FunctionType functionType = type; | |
316 addNestedTypes(functionType.returnType); | |
317 for (DartType parameterType in functionType.parameterTypes) { | |
318 addNestedTypes(parameterType); | |
319 } | |
320 for (DartType parameterType in functionType.optionalParameterTypes) { | |
321 addNestedTypes(parameterType); | |
322 } | |
323 for (DartType parameterType in functionType.namedParameterTypes) { | |
324 addNestedTypes(parameterType); | |
325 } | |
326 return; | |
327 } | |
328 assert(invariant(type.element, type is InterfaceType, | |
329 message: "Unrecognized type: $type")); | |
330 InterfaceType interfaceType = type; | |
331 for (DartType typeArgument in interfaceType.typeArguments) { | |
332 addNestedTypes(typeArgument); | |
333 } | |
334 elements.add(type.element.implementation); | 292 elements.add(type.element.implementation); |
335 } | 293 } |
336 for (DartType supertype in cls.implementation.allSupertypes) { | |
337 addNestedTypes(supertype); | |
338 } | |
339 elements.add(cls.implementation); | 294 elements.add(cls.implementation); |
340 } else if (Elements.isStaticOrTopLevel(element) || | 295 } else if (Elements.isStaticOrTopLevel(element) || |
341 element.isConstructor()) { | 296 element.isConstructor()) { |
342 _collectDependencies(element, elements, constants); | 297 _collectDependencies(element, elements, constants); |
343 } | 298 } |
344 if (element.isGenerativeConstructor()) { | 299 if (element.isGenerativeConstructor()) { |
345 // When instantiating a class, we record a reference to the | 300 // When instantiating a class, we record a reference to the |
346 // constructor, not the class itself. We must add all the | 301 // constructor, not the class itself. We must add all the |
347 // instance members of the constructor's class. | 302 // instance members of the constructor's class. |
348 ClassElement implementation = | 303 ClassElement implementation = |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 void onResolutionComplete(FunctionElement main) { | 550 void onResolutionComplete(FunctionElement main) { |
596 if (!splitProgram) { | 551 if (!splitProgram) { |
597 allOutputUnits.add(mainOutputUnit); | 552 allOutputUnits.add(mainOutputUnit); |
598 return; | 553 return; |
599 } | 554 } |
600 if (main == null) return; | 555 if (main == null) return; |
601 LibraryElement mainLibrary = main.getLibrary(); | 556 LibraryElement mainLibrary = main.getLibrary(); |
602 _importedDeferredBy = new Map<Import, Set<Element>>(); | 557 _importedDeferredBy = new Map<Import, Set<Element>>(); |
603 _constantsDeferredBy = new Map<Import, Set<Constant>>(); | 558 _constantsDeferredBy = new Map<Import, Set<Constant>>(); |
604 _importedDeferredBy[_fakeMainImport] = _mainElements; | 559 _importedDeferredBy[_fakeMainImport] = _mainElements; |
605 _visitedTypes = new Set<DartType>(); | |
606 | 560 |
607 measureElement(mainLibrary, () { | 561 measureElement(mainLibrary, () { |
608 | 562 |
609 // Starting from main, traverse the program and find all dependencies. | 563 // Starting from main, traverse the program and find all dependencies. |
610 _mapDependencies(compiler.mainFunction, _fakeMainImport); | 564 _mapDependencies(compiler.mainFunction, _fakeMainImport); |
611 | 565 |
612 // Also add "global" dependencies to the main OutputUnit. These are | 566 // Also add "global" dependencies to the main OutputUnit. These are |
613 // things that the backend need but cannot associate with a particular | 567 // things that the backend need but cannot associate with a particular |
614 // element, for example, startRootIsolate. This set also contains | 568 // element, for example, startRootIsolate. This set also contains |
615 // elements for which we lack precise information. | 569 // elements for which we lack precise information. |
(...skipping 15 matching lines...) Expand all Loading... |
631 } | 585 } |
632 for (Constant constant in _constantsDeferredBy[import]) { | 586 for (Constant constant in _constantsDeferredBy[import]) { |
633 allConstants.add(constant); | 587 allConstants.add(constant); |
634 _addImportToOutputUnitOfConstant(constant, import); | 588 _addImportToOutputUnitOfConstant(constant, import); |
635 } | 589 } |
636 } | 590 } |
637 | 591 |
638 // Release maps; | 592 // Release maps; |
639 _importedDeferredBy = null; | 593 _importedDeferredBy = null; |
640 _constantsDeferredBy = null; | 594 _constantsDeferredBy = null; |
641 _visitedTypes = null; | |
642 | 595 |
643 _adjustConstantsOutputUnit(allConstants); | 596 _adjustConstantsOutputUnit(allConstants); |
644 | 597 |
645 // Find all the output units we have used. | 598 // Find all the output units we have used. |
646 // Also generate a unique name for each OutputUnit. | 599 // Also generate a unique name for each OutputUnit. |
647 for (OutputUnit outputUnit in _elementToOutputUnit.values) { | 600 for (OutputUnit outputUnit in _elementToOutputUnit.values) { |
648 allOutputUnits.add(outputUnit); | 601 allOutputUnits.add(outputUnit); |
649 } | 602 } |
650 for (OutputUnit outputUnit in _constantToOutputUnit.values) { | 603 for (OutputUnit outputUnit in _constantToOutputUnit.values) { |
651 allOutputUnits.add(outputUnit); | 604 allOutputUnits.add(outputUnit); |
(...skipping 24 matching lines...) Expand all Loading... |
676 } | 629 } |
677 } | 630 } |
678 if (splitProgram && !deferredUsedFromMain) { | 631 if (splitProgram && !deferredUsedFromMain) { |
679 compiler.reportInfo( | 632 compiler.reportInfo( |
680 lastDeferred, | 633 lastDeferred, |
681 MessageKind.DEFERRED_LIBRARY_NOT_FROM_MAIN); | 634 MessageKind.DEFERRED_LIBRARY_NOT_FROM_MAIN); |
682 splitProgram = false; | 635 splitProgram = false; |
683 } | 636 } |
684 } | 637 } |
685 } | 638 } |
OLD | NEW |