| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** | 5 /** |
| 6 * [CompilerTask] for loading libraries and setting up the import/export scopes. | 6 * [CompilerTask] for loading libraries and setting up the import/export scopes. |
| 7 */ | 7 */ |
| 8 abstract class LibraryLoader extends CompilerTask { | 8 abstract class LibraryLoader extends CompilerTask { |
| 9 LibraryLoader(Compiler compiler) : super(compiler); | 9 LibraryLoader(Compiler compiler) : super(compiler); |
| 10 | 10 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 /** | 120 /** |
| 121 * Implementation class for [LibraryLoader]. The distinction between | 121 * Implementation class for [LibraryLoader]. The distinction between |
| 122 * [LibraryLoader] and [LibraryLoaderTask] is made to hide internal members from | 122 * [LibraryLoader] and [LibraryLoaderTask] is made to hide internal members from |
| 123 * the [LibraryLoader] interface. | 123 * the [LibraryLoader] interface. |
| 124 */ | 124 */ |
| 125 class LibraryLoaderTask extends LibraryLoader { | 125 class LibraryLoaderTask extends LibraryLoader { |
| 126 LibraryLoaderTask(Compiler compiler) : super(compiler); | 126 LibraryLoaderTask(Compiler compiler) : super(compiler); |
| 127 String get name => 'LibraryLoader'; | 127 String get name => 'LibraryLoader'; |
| 128 | 128 |
| 129 final Map<String, LibraryElement> libraryNames = | 129 final Map<String, LibraryElement> libraryNames = |
| 130 new Map<String, LibraryElement>(); | 130 new LinkedHashMap<String, LibraryElement>(); |
| 131 | 131 |
| 132 LibraryDependencyHandler currentHandler; | 132 LibraryDependencyHandler currentHandler; |
| 133 | 133 |
| 134 LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri) { | 134 LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri) { |
| 135 return measure(() { | 135 return measure(() { |
| 136 assert(currentHandler == null); | 136 assert(currentHandler == null); |
| 137 currentHandler = new LibraryDependencyHandler(compiler); | 137 currentHandler = new LibraryDependencyHandler(compiler); |
| 138 LibraryElement library = | 138 LibraryElement library = |
| 139 createLibrary(currentHandler, uri, node, canonicalUri); | 139 createLibrary(currentHandler, uri, node, canonicalUri); |
| 140 currentHandler.computeExports(); | 140 currentHandler.computeExports(); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 /** | 456 /** |
| 457 * A linked list of the export tags the dependent upon this node library. | 457 * A linked list of the export tags the dependent upon this node library. |
| 458 * This is used to propagate exports during the computation of export scopes. | 458 * This is used to propagate exports during the computation of export scopes. |
| 459 */ | 459 */ |
| 460 Link<ExportLink> dependencies = const Link<ExportLink>(); | 460 Link<ExportLink> dependencies = const Link<ExportLink>(); |
| 461 | 461 |
| 462 /** | 462 /** |
| 463 * The export scope for [library] which is gradually computed by the work-list | 463 * The export scope for [library] which is gradually computed by the work-list |
| 464 * computation in [LibraryDependencyHandler.computeExports]. | 464 * computation in [LibraryDependencyHandler.computeExports]. |
| 465 */ | 465 */ |
| 466 Map<SourceString, Element> exportScope = new Map<SourceString, Element>(); | 466 Map<SourceString, Element> exportScope = |
| 467 new LinkedHashMap<SourceString, Element>(); |
| 467 | 468 |
| 468 /** | 469 /** |
| 469 * The set of exported elements that need to be propageted to dependent | 470 * The set of exported elements that need to be propageted to dependent |
| 470 * libraries as part of the work-list computation performed in | 471 * libraries as part of the work-list computation performed in |
| 471 * [LibraryDependencyHandler.computeExports]. | 472 * [LibraryDependencyHandler.computeExports]. |
| 472 */ | 473 */ |
| 473 Set<Element> pendingExportSet = new Set<Element>(); | 474 Set<Element> pendingExportSet = new Set<Element>(); |
| 474 | 475 |
| 475 LibraryDependencyNode(LibraryElement this.library); | 476 LibraryDependencyNode(LibraryElement this.library); |
| 476 | 477 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 class LibraryDependencyHandler { | 594 class LibraryDependencyHandler { |
| 594 final Compiler compiler; | 595 final Compiler compiler; |
| 595 | 596 |
| 596 /** | 597 /** |
| 597 * Newly loaded libraries and their corresponding node in the library | 598 * Newly loaded libraries and their corresponding node in the library |
| 598 * dependency graph. Libraries that have already been fully loaded are not | 599 * dependency graph. Libraries that have already been fully loaded are not |
| 599 * part of the dependency graph of this handler since their export scopes have | 600 * part of the dependency graph of this handler since their export scopes have |
| 600 * already been computed. | 601 * already been computed. |
| 601 */ | 602 */ |
| 602 Map<LibraryElement,LibraryDependencyNode> nodeMap = | 603 Map<LibraryElement,LibraryDependencyNode> nodeMap = |
| 603 new Map<LibraryElement,LibraryDependencyNode>(); | 604 new LinkedHashMap<LibraryElement,LibraryDependencyNode>(); |
| 604 | 605 |
| 605 LibraryDependencyHandler(Compiler this.compiler); | 606 LibraryDependencyHandler(Compiler this.compiler); |
| 606 | 607 |
| 607 /** | 608 /** |
| 608 * Performs a fixed-point computation on the export scopes of all registered | 609 * Performs a fixed-point computation on the export scopes of all registered |
| 609 * libraries and creates the import/export of the libraries based on the | 610 * libraries and creates the import/export of the libraries based on the |
| 610 * fixed-point. | 611 * fixed-point. |
| 611 */ | 612 */ |
| 612 void computeExports() { | 613 void computeExports() { |
| 613 bool changed = true; | 614 bool changed = true; |
| 614 while (changed) { | 615 while (changed) { |
| 615 changed = false; | 616 changed = false; |
| 617 Map<LibraryDependencyNode, List<Element>> tasks = |
| 618 new LinkedHashMap<LibraryDependencyNode, List<Element>>(); |
| 619 |
| 620 // Locally defined elements take precedence over exported |
| 621 // elements. So we must propagate local elements first. We |
| 622 // ensure this by pulling the pending exports before |
| 623 // propagating. This enforces that we handle exports |
| 624 // breadth-first, with locally defined elements being level 0. |
| 616 nodeMap.forEach((_, LibraryDependencyNode node) { | 625 nodeMap.forEach((_, LibraryDependencyNode node) { |
| 617 var pendingExports = node.pullPendingExports(); | 626 List<Element> pendingExports = node.pullPendingExports(); |
| 627 tasks[node] = pendingExports; |
| 628 }); |
| 629 tasks.forEach((LibraryDependencyNode node, List<Element> pendingExports) { |
| 618 pendingExports.forEach((Element element) { | 630 pendingExports.forEach((Element element) { |
| 619 element = node.addElementToExportScope(compiler, element); | 631 element = node.addElementToExportScope(compiler, element); |
| 620 if (node.propagateElement(element)) { | 632 if (node.propagateElement(element)) { |
| 621 changed = true; | 633 changed = true; |
| 622 } | 634 } |
| 623 }); | 635 }); |
| 624 }); | 636 }); |
| 625 } | 637 } |
| 626 | 638 |
| 627 // Setup export scopes. These have to be set before computing the import | 639 // Setup export scopes. These have to be set before computing the import |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 } | 685 } |
| 674 | 686 |
| 675 /** | 687 /** |
| 676 * Registers all top-level entities of [library] as starting point for the | 688 * Registers all top-level entities of [library] as starting point for the |
| 677 * fixed-point computation of the import/export scopes. | 689 * fixed-point computation of the import/export scopes. |
| 678 */ | 690 */ |
| 679 void registerLibraryExports(LibraryElement library) { | 691 void registerLibraryExports(LibraryElement library) { |
| 680 nodeMap[library].registerInitialExports(); | 692 nodeMap[library].registerInitialExports(); |
| 681 } | 693 } |
| 682 } | 694 } |
| OLD | NEW |