| 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; | |
| 27 import 'helpers/helpers.dart'; // Included for debug helpers. | 25 import 'helpers/helpers.dart'; // Included for debug helpers. |
| 28 import 'native_handler.dart' as native; | 26 import 'native_handler.dart' as native; |
| 29 import 'tree/tree.dart'; | 27 import 'tree/tree.dart'; |
| 30 import 'util/util.dart' show Link, LinkBuilder; | 28 import 'util/util.dart' show Link, LinkBuilder; |
| 31 | 29 |
| 32 /** | 30 /** |
| 33 * [CompilerTask] for loading libraries and setting up the import/export scopes. | 31 * [CompilerTask] for loading libraries and setting up the import/export scopes. |
| 34 * | 32 * |
| 35 * The library loader uses four different kinds of URIs in different parts of | 33 * The library loader uses four different kinds of URIs in different parts of |
| 36 * the loading process. | 34 * the loading process. |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 * Copies and clears pending export set for this node. | 801 * Copies and clears pending export set for this node. |
| 804 */ | 802 */ |
| 805 Map<Element, Link<Export>> pullPendingExports() { | 803 Map<Element, Link<Export>> pullPendingExports() { |
| 806 Map<Element, Link<Export>> pendingExports = | 804 Map<Element, Link<Export>> pendingExports = |
| 807 new Map<Element, Link<Export>>.from(pendingExportMap); | 805 new Map<Element, Link<Export>>.from(pendingExportMap); |
| 808 pendingExportMap.clear(); | 806 pendingExportMap.clear(); |
| 809 return pendingExports; | 807 return pendingExports; |
| 810 } | 808 } |
| 811 | 809 |
| 812 /** | 810 /** |
| 813 * Adds [newElement] to the export scope for this node. If the [newElement] | 811 * Adds [element] to the export scope for this node. If the [element] name |
| 814 * name is a duplicate, an error element is inserted into the export scope. | 812 * is a duplicate, an error element is inserted into the export scope. |
| 815 */ | 813 */ |
| 816 Element addElementToExportScope(Compiler compiler, Element newElement, | 814 Element addElementToExportScope(Compiler compiler, Element element, |
| 817 Link<Export> exports) { | 815 Link<Export> exports) { |
| 818 return compiler.withCurrentElement(library, () { | 816 String name = element.name; |
| 819 String name = newElement.name; | |
| 820 exporters[newElement] = exports; | |
| 821 | 817 |
| 822 void reportDuplicateExport(Element duplicate, | 818 void reportDuplicateExport(Element duplicate, |
| 823 Link<Export> duplicateExports, | 819 Link<Export> duplicateExports, |
| 824 {bool reportError: true}) { | 820 {bool reportError: true}) { |
| 825 assert(invariant(library, !duplicateExports.isEmpty, | 821 assert(invariant(library, !duplicateExports.isEmpty, |
| 826 message: "No export for $duplicate from ${duplicate.library} " | 822 message: "No export for $duplicate from ${duplicate.library} " |
| 827 "in $library.")); | 823 "in $library.")); |
| 828 compiler.withCurrentElement(library, () { | 824 compiler.withCurrentElement(library, () { |
| 829 for (Export export in duplicateExports) { | 825 for (Export export in duplicateExports) { |
| 830 if (reportError) { | 826 if (reportError) { |
| 831 compiler.reportError(export, | 827 compiler.reportError(export, |
| 832 MessageKind.DUPLICATE_EXPORT, {'name': name}); | 828 MessageKind.DUPLICATE_EXPORT, {'name': name}); |
| 833 reportError = false; | 829 reportError = false; |
| 834 } else { | 830 } else { |
| 835 compiler.reportInfo(export, | 831 compiler.reportInfo(export, |
| 836 MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}); | 832 MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}); |
| 837 } | |
| 838 } | 833 } |
| 839 }); | 834 } |
| 835 }); |
| 836 } |
| 837 |
| 838 void reportDuplicateExportDecl(Element duplicate, |
| 839 Link<Export> duplicateExports) { |
| 840 assert(invariant(library, !duplicateExports.isEmpty, |
| 841 message: "No export for $duplicate from ${duplicate.library} " |
| 842 "in $library.")); |
| 843 compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL, |
| 844 {'name': name, 'uriString': duplicateExports.head.uri}); |
| 845 } |
| 846 |
| 847 Element existingElement = exportScope[name]; |
| 848 if (existingElement != null && existingElement != element) { |
| 849 if (existingElement.isErroneous) { |
| 850 reportDuplicateExport(element, exports); |
| 851 reportDuplicateExportDecl(element, exports); |
| 852 element = existingElement; |
| 853 } else if (existingElement.library == library) { |
| 854 // Do nothing. [existingElement] hides [element]. |
| 855 } else if (element.library == library) { |
| 856 // [element] hides [existingElement]. |
| 857 exportScope[name] = element; |
| 858 exporters[element] = exports; |
| 859 } else { |
| 860 // Declared elements hide exported elements. |
| 861 Link<Export> existingExports = exporters[existingElement]; |
| 862 reportDuplicateExport(existingElement, existingExports); |
| 863 reportDuplicateExport(element, exports, reportError: false); |
| 864 reportDuplicateExportDecl(existingElement, existingExports); |
| 865 reportDuplicateExportDecl(element, exports); |
| 866 element = exportScope[name] = new ErroneousElementX( |
| 867 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library); |
| 840 } | 868 } |
| 841 | 869 } else { |
| 842 void reportDuplicateExportDecl(Element duplicate, | 870 exportScope[name] = element; |
| 843 Link<Export> duplicateExports) { | 871 exporters[element] = exports; |
| 844 assert(invariant(library, !duplicateExports.isEmpty, | 872 } |
| 845 message: "No export for $duplicate from ${duplicate.library} " | 873 return element; |
| 846 "in $library.")); | |
| 847 compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL, | |
| 848 {'name': name, 'uriString': duplicateExports.head.uri}); | |
| 849 } | |
| 850 | |
| 851 | |
| 852 Element createWarnOnUseElement(MessageKind messageKind, | |
| 853 Element hidingElement, | |
| 854 Element hiddenElement) { | |
| 855 Uri hiddenUri = hiddenElement.library.canonicalUri; | |
| 856 Uri hidingUri = hidingElement.library.canonicalUri; | |
| 857 Element exportedElement = new WarnOnUseElementX( | |
| 858 new WrappedMessage( | |
| 859 null, // Report on reference to [hidingElement]. | |
| 860 messageKind, | |
| 861 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), | |
| 862 new WrappedMessage( | |
| 863 compiler.spanFromSpannable(exporters[hiddenElement].head), | |
| 864 MessageKind.EXPORTED_HERE, | |
| 865 {'name': name, | |
| 866 'uri': hiddenUri}), | |
| 867 hidingElement.enclosingElement, hidingElement); | |
| 868 exporters[exportedElement] = exports; | |
| 869 return exportedElement; | |
| 870 } | |
| 871 | |
| 872 bool fromPlatform(Element e) => e.library.isPlatformLibrary; | |
| 873 | |
| 874 Element computeExportedElement(Element existingElement) { | |
| 875 if (existingElement != null && existingElement != newElement) { | |
| 876 if (existingElement.isErroneous) { | |
| 877 if (!fromPlatform(newElement)) { | |
| 878 reportDuplicateExport(newElement, exports); | |
| 879 reportDuplicateExportDecl(newElement, exports); | |
| 880 } | |
| 881 return existingElement; | |
| 882 } else if (existingElement.library == library) { | |
| 883 // Do nothing. [existingElement] hides [newElement]. | |
| 884 return existingElement; | |
| 885 } else if (newElement.library == library) { | |
| 886 // [newElement] hides [existingElement]. | |
| 887 return newElement; | |
| 888 } else { | |
| 889 if (fromPlatform(existingElement) && | |
| 890 !fromPlatform(newElement)) { | |
| 891 // [existingElement] is implicitly hidden. | |
| 892 return createWarnOnUseElement( | |
| 893 MessageKind.HIDDEN_IMPLICIT_EXPORT, | |
| 894 newElement, | |
| 895 existingElement); | |
| 896 } else if (!fromPlatform(existingElement) && | |
| 897 fromPlatform(newElement)) { | |
| 898 // [element] is implicitly hidden. | |
| 899 return createWarnOnUseElement( | |
| 900 MessageKind.HIDDEN_IMPLICIT_EXPORT, | |
| 901 existingElement, | |
| 902 newElement); | |
| 903 } else { | |
| 904 // Declared elements hide exported elements. | |
| 905 Link<Export> existingExports = exporters[existingElement]; | |
| 906 reportDuplicateExport(existingElement, existingExports); | |
| 907 reportDuplicateExport(newElement, exports, reportError: false); | |
| 908 reportDuplicateExportDecl(existingElement, existingExports); | |
| 909 reportDuplicateExportDecl(newElement, exports); | |
| 910 Element exportedElement = new ErroneousElementX( | |
| 911 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library); | |
| 912 exporters[exportedElement] = existingExports; | |
| 913 return exportedElement; | |
| 914 } | |
| 915 } | |
| 916 } else { | |
| 917 return newElement; | |
| 918 } | |
| 919 } | |
| 920 | |
| 921 Element existingElement = exportScope[name]; | |
| 922 Element exportedElement = computeExportedElement(existingElement); | |
| 923 exportScope[name] = exportedElement; | |
| 924 return exportedElement; | |
| 925 }); | |
| 926 } | 874 } |
| 927 | 875 |
| 928 /** | 876 /** |
| 929 * Propagates the exported [element] to all library nodes that depend upon | 877 * Propagates the exported [element] to all library nodes that depend upon |
| 930 * this node. If the propagation updated any pending exports, [:true:] is | 878 * this node. If the propagation updated any pending exports, [:true:] is |
| 931 * returned. | 879 * returned. |
| 932 */ | 880 */ |
| 933 bool propagateElement(Element element) { | 881 bool propagateElement(Element element) { |
| 934 bool change = false; | 882 bool change = false; |
| 935 for (ExportLink link in dependencies) { | 883 for (ExportLink link in dependencies) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 * fixed-point computation of the import/export scopes. | 1025 * fixed-point computation of the import/export scopes. |
| 1078 */ | 1026 */ |
| 1079 void registerLibraryExports(LibraryElement library) { | 1027 void registerLibraryExports(LibraryElement library) { |
| 1080 nodeMap[library].registerInitialExports(); | 1028 nodeMap[library].registerInitialExports(); |
| 1081 } | 1029 } |
| 1082 | 1030 |
| 1083 Future processLibraryTags(LibraryElement library) { | 1031 Future processLibraryTags(LibraryElement library) { |
| 1084 return task.processLibraryTags(this, library); | 1032 return task.processLibraryTags(this, library); |
| 1085 } | 1033 } |
| 1086 } | 1034 } |
| OLD | NEW |