| 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 |