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 |