| 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 library dart2js.library_loader; | 5 library dart2js.library_loader; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart2jslib.dart' | 8 import 'dart2jslib.dart' |
| 9 show Compiler, | 9 show Compiler, |
| 10 CompilerTask, | 10 CompilerTask, |
| 11 MessageKind, | 11 MessageKind, |
| 12 Script, | 12 Script, |
| 13 invariant; | 13 invariant; |
| 14 import 'elements/elements.dart' | 14 import 'elements/elements.dart' |
| 15 show CompilationUnitElement, | 15 show CompilationUnitElement, |
| 16 Element, | 16 Element, |
| 17 LibraryElement, | 17 LibraryElement, |
| 18 PrefixElement; | 18 PrefixElement; |
| 19 import 'elements/modelx.dart' | 19 import 'elements/modelx.dart' |
| 20 show CompilationUnitElementX, | 20 show CompilationUnitElementX, |
| 21 DeferredLoaderGetterElementX, | 21 DeferredLoaderGetterElementX, |
| 22 ErroneousElementX, | 22 ErroneousElementX, |
| 23 LibraryElementX, | 23 LibraryElementX, |
| 24 PrefixElementX; | 24 PrefixElementX, |
| 25 WarnOnUseElementX, |
| 26 WrappedMessage; |
| 25 import 'helpers/helpers.dart'; // Included for debug helpers. | 27 import 'helpers/helpers.dart'; // Included for debug helpers. |
| 26 import 'native_handler.dart' as native; | 28 import 'native_handler.dart' as native; |
| 27 import 'tree/tree.dart'; | 29 import 'tree/tree.dart'; |
| 28 import 'util/util.dart' show Link, LinkBuilder; | 30 import 'util/util.dart' show Link, LinkBuilder; |
| 29 | 31 |
| 30 /** | 32 /** |
| 31 * [CompilerTask] for loading libraries and setting up the import/export scopes. | 33 * [CompilerTask] for loading libraries and setting up the import/export scopes. |
| 32 * | 34 * |
| 33 * The library loader uses four different kinds of URIs in different parts of | 35 * The library loader uses four different kinds of URIs in different parts of |
| 34 * the loading process. | 36 * the loading process. |
| (...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 * Copies and clears pending export set for this node. | 763 * Copies and clears pending export set for this node. |
| 762 */ | 764 */ |
| 763 Map<Element, Link<Export>> pullPendingExports() { | 765 Map<Element, Link<Export>> pullPendingExports() { |
| 764 Map<Element, Link<Export>> pendingExports = | 766 Map<Element, Link<Export>> pendingExports = |
| 765 new Map<Element, Link<Export>>.from(pendingExportMap); | 767 new Map<Element, Link<Export>>.from(pendingExportMap); |
| 766 pendingExportMap.clear(); | 768 pendingExportMap.clear(); |
| 767 return pendingExports; | 769 return pendingExports; |
| 768 } | 770 } |
| 769 | 771 |
| 770 /** | 772 /** |
| 771 * Adds [element] to the export scope for this node. If the [element] name | 773 * Adds [newElement] to the export scope for this node. If the [newElement] |
| 772 * is a duplicate, an error element is inserted into the export scope. | 774 * name is a duplicate, an error element is inserted into the export scope. |
| 773 */ | 775 */ |
| 774 Element addElementToExportScope(Compiler compiler, Element element, | 776 Element addElementToExportScope(Compiler compiler, Element newElement, |
| 775 Link<Export> exports) { | 777 Link<Export> exports) { |
| 776 String name = element.name; | 778 return compiler.withCurrentElement(library, () { |
| 779 String name = newElement.name; |
| 780 exporters[newElement] = exports; |
| 777 | 781 |
| 778 void reportDuplicateExport(Element duplicate, | 782 void reportDuplicateExport(Element duplicate, |
| 779 Link<Export> duplicateExports, | 783 Link<Export> duplicateExports, |
| 780 {bool reportError: true}) { | 784 {bool reportError: true}) { |
| 781 assert(invariant(library, !duplicateExports.isEmpty, | 785 assert(invariant(library, !duplicateExports.isEmpty, |
| 782 message: "No export for $duplicate from ${duplicate.library} " | 786 message: "No export for $duplicate from ${duplicate.library} " |
| 783 "in $library.")); | 787 "in $library.")); |
| 784 compiler.withCurrentElement(library, () { | 788 compiler.withCurrentElement(library, () { |
| 785 for (Export export in duplicateExports) { | 789 for (Export export in duplicateExports) { |
| 786 if (reportError) { | 790 if (reportError) { |
| 787 compiler.reportError(export, | 791 compiler.reportError(export, |
| 788 MessageKind.DUPLICATE_EXPORT, {'name': name}); | 792 MessageKind.DUPLICATE_EXPORT, {'name': name}); |
| 789 reportError = false; | 793 reportError = false; |
| 794 } else { |
| 795 compiler.reportInfo(export, |
| 796 MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}); |
| 797 } |
| 798 } |
| 799 }); |
| 800 } |
| 801 |
| 802 void reportDuplicateExportDecl(Element duplicate, |
| 803 Link<Export> duplicateExports) { |
| 804 assert(invariant(library, !duplicateExports.isEmpty, |
| 805 message: "No export for $duplicate from ${duplicate.library} " |
| 806 "in $library.")); |
| 807 compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL, |
| 808 {'name': name, 'uriString': duplicateExports.head.uri}); |
| 809 } |
| 810 |
| 811 |
| 812 Element createWarnOnUseElement(MessageKind messageKind, |
| 813 Element hidingElement, |
| 814 Element hiddenElement) { |
| 815 Uri hiddenUri = hiddenElement.library.canonicalUri; |
| 816 Uri hidingUri = hidingElement.library.canonicalUri; |
| 817 Element exportedElement = new WarnOnUseElementX( |
| 818 new WrappedMessage( |
| 819 null, // Report on reference to [hidingElement]. |
| 820 messageKind, |
| 821 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), |
| 822 new WrappedMessage( |
| 823 compiler.spanFromSpannable(exporters[hiddenElement].head), |
| 824 MessageKind.EXPORTED_HERE, |
| 825 {'name': name, |
| 826 'uri': hiddenUri}), |
| 827 hidingElement.enclosingElement, hidingElement); |
| 828 exporters[exportedElement] = exports; |
| 829 return exportedElement; |
| 830 } |
| 831 |
| 832 bool fromPlatform(Element e) => e.library.isPlatformLibrary; |
| 833 |
| 834 Element computeExportedElement(Element existingElement) { |
| 835 if (existingElement != null && existingElement != newElement) { |
| 836 if (existingElement.isErroneous) { |
| 837 if (!fromPlatform(newElement)) { |
| 838 reportDuplicateExport(newElement, exports); |
| 839 reportDuplicateExportDecl(newElement, exports); |
| 840 } |
| 841 return existingElement; |
| 842 } else if (existingElement.library == library) { |
| 843 // Do nothing. [existingElement] hides [newElement]. |
| 844 return existingElement; |
| 845 } else if (newElement.library == library) { |
| 846 // [newElement] hides [existingElement]. |
| 847 return newElement; |
| 790 } else { | 848 } else { |
| 791 compiler.reportInfo(export, | 849 if (fromPlatform(existingElement) && |
| 792 MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}); | 850 !fromPlatform(newElement)) { |
| 851 // [existingElement] is implicitly hidden. |
| 852 return createWarnOnUseElement( |
| 853 MessageKind.HIDDEN_IMPLICIT_EXPORT, |
| 854 newElement, |
| 855 existingElement); |
| 856 } else if (!fromPlatform(existingElement) && |
| 857 fromPlatform(newElement)) { |
| 858 // [element] is implicitly hidden. |
| 859 return createWarnOnUseElement( |
| 860 MessageKind.HIDDEN_IMPLICIT_EXPORT, |
| 861 existingElement, |
| 862 newElement); |
| 863 } else { |
| 864 // Declared elements hide exported elements. |
| 865 Link<Export> existingExports = exporters[existingElement]; |
| 866 reportDuplicateExport(existingElement, existingExports); |
| 867 reportDuplicateExport(newElement, exports, reportError: false); |
| 868 reportDuplicateExportDecl(existingElement, existingExports); |
| 869 reportDuplicateExportDecl(newElement, exports); |
| 870 Element exportedElement = new ErroneousElementX( |
| 871 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library); |
| 872 exporters[exportedElement] = existingExports; |
| 873 return exportedElement; |
| 874 } |
| 793 } | 875 } |
| 876 } else { |
| 877 return newElement; |
| 794 } | 878 } |
| 795 }); | 879 } |
| 796 } | |
| 797 | 880 |
| 798 void reportDuplicateExportDecl(Element duplicate, | 881 Element existingElement = exportScope[name]; |
| 799 Link<Export> duplicateExports) { | 882 Element exportedElement = computeExportedElement(existingElement); |
| 800 assert(invariant(library, !duplicateExports.isEmpty, | 883 exportScope[name] = exportedElement; |
| 801 message: "No export for $duplicate from ${duplicate.library} " | 884 return exportedElement; |
| 802 "in $library.")); | 885 }); |
| 803 compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL, | |
| 804 {'name': name, 'uriString': duplicateExports.head.uri}); | |
| 805 } | |
| 806 | |
| 807 Element existingElement = exportScope[name]; | |
| 808 if (existingElement != null && existingElement != element) { | |
| 809 if (existingElement.isErroneous) { | |
| 810 reportDuplicateExport(element, exports); | |
| 811 reportDuplicateExportDecl(element, exports); | |
| 812 element = existingElement; | |
| 813 } else if (existingElement.library == library) { | |
| 814 // Do nothing. [existingElement] hides [element]. | |
| 815 } else if (element.library == library) { | |
| 816 // [element] hides [existingElement]. | |
| 817 exportScope[name] = element; | |
| 818 exporters[element] = exports; | |
| 819 } else { | |
| 820 // Declared elements hide exported elements. | |
| 821 Link<Export> existingExports = exporters[existingElement]; | |
| 822 reportDuplicateExport(existingElement, existingExports); | |
| 823 reportDuplicateExport(element, exports, reportError: false); | |
| 824 reportDuplicateExportDecl(existingElement, existingExports); | |
| 825 reportDuplicateExportDecl(element, exports); | |
| 826 element = exportScope[name] = new ErroneousElementX( | |
| 827 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library); | |
| 828 } | |
| 829 } else { | |
| 830 exportScope[name] = element; | |
| 831 exporters[element] = exports; | |
| 832 } | |
| 833 return element; | |
| 834 } | 886 } |
| 835 | 887 |
| 836 /** | 888 /** |
| 837 * Propagates the exported [element] to all library nodes that depend upon | 889 * Propagates the exported [element] to all library nodes that depend upon |
| 838 * this node. If the propagation updated any pending exports, [:true:] is | 890 * this node. If the propagation updated any pending exports, [:true:] is |
| 839 * returned. | 891 * returned. |
| 840 */ | 892 */ |
| 841 bool propagateElement(Element element) { | 893 bool propagateElement(Element element) { |
| 842 bool change = false; | 894 bool change = false; |
| 843 for (ExportLink link in dependencies) { | 895 for (ExportLink link in dependencies) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 * fixed-point computation of the import/export scopes. | 1037 * fixed-point computation of the import/export scopes. |
| 986 */ | 1038 */ |
| 987 void registerLibraryExports(LibraryElement library) { | 1039 void registerLibraryExports(LibraryElement library) { |
| 988 nodeMap[library].registerInitialExports(); | 1040 nodeMap[library].registerInitialExports(); |
| 989 } | 1041 } |
| 990 | 1042 |
| 991 Future processLibraryTags(LibraryElement library) { | 1043 Future processLibraryTags(LibraryElement library) { |
| 992 return task.processLibraryTags(this, library); | 1044 return task.processLibraryTags(this, library); |
| 993 } | 1045 } |
| 994 } | 1046 } |
| OLD | NEW |