Index: sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
index e74bd0d389ea59cdd19fae32f579cf3c135b7768..b19debaebf1397226bf66d25c385cbffaef8cae7 100644 |
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
@@ -634,6 +634,82 @@ class CompilationUnitElementX extends ElementX |
} |
} |
+class ImportScope { |
+ /** |
+ * Map for elements imported through import declarations. |
+ * |
+ * Addition to the map is performed by [addImport]. Lookup is done trough |
+ * [find]. |
+ */ |
+ final Map<SourceString, Element> importScope = |
+ new Map<SourceString, Element>(); |
+ |
+ /** |
+ * Adds [element] to the import scope of this library. |
+ * |
+ * If an element by the same name is already in the imported scope, an |
+ * [ErroneousElement] will be put in the imported scope, allowing for |
+ * detection of ambiguous uses of imported names. |
+ */ |
+ void addImport(Element enclosingElement, |
+ Element element, |
+ Import import, |
+ DiagnosticListener listener) { |
+ LibraryElementX library = enclosingElement.getLibrary(); |
+ Map<Element, Link<Import>> importers = library.importers; |
+ importers[element] = |
+ importers.putIfAbsent(element, () => const Link<Import>()) |
+ .prepend(import); |
+ SourceString name = element.name; |
+ Element existing = importScope.putIfAbsent(name, () => element); |
+ |
+ Element createWarnOnUseElement(Spannable spannable, |
+ MessageKind messageKind, |
+ Element hidingElement, |
+ Element hiddenElement) { |
+ Uri hiddenUri = hiddenElement.getLibrary().canonicalUri; |
+ Uri hidingUri = hidingElement.getLibrary().canonicalUri; |
+ return new WarnOnUseElementX( |
+ new WrappedMessage( |
+ null, // Report on reference to [hidingElement]. |
+ messageKind, |
+ {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), |
+ new WrappedMessage( |
+ listener.spanFromSpannable(spannable), |
+ MessageKind.IMPORTED_HERE, |
+ {'name': name}), |
+ enclosingElement, hidingElement); |
+ } |
+ |
+ if (existing != element) { |
+ if (existing.getLibrary().isPlatformLibrary && |
+ !element.getLibrary().isPlatformLibrary) { |
+ // [existing] is implicitly hidden. |
+ importScope[name] = createWarnOnUseElement( |
+ import, MessageKind.HIDDEN_IMPORT, element, existing); |
+ } else if (!existing.getLibrary().isPlatformLibrary && |
+ element.getLibrary().isPlatformLibrary) { |
+ // [element] is implicitly hidden. |
+ if (import == null) { |
+ // [element] is imported implicitly (probably through dart:core). |
+ importScope[name] = createWarnOnUseElement( |
+ importers[existing].head, MessageKind.HIDDEN_IMPLICIT_IMPORT, |
+ existing, element); |
+ } else { |
+ importScope[name] = createWarnOnUseElement( |
+ import, MessageKind.HIDDEN_IMPORT, existing, element); |
+ } |
+ } else { |
+ importScope[name] = new AmbiguousElementX( |
+ MessageKind.DUPLICATE_IMPORT, {'name': name}, |
+ enclosingElement, existing, element); |
+ } |
+ } |
+ } |
+ |
+ Element operator [](SourceString name) => importScope[name]; |
+} |
+ |
class LibraryElementX extends ElementX implements LibraryElement { |
final Uri canonicalUri; |
CompilationUnitElement entryCompilationUnit; |
@@ -644,6 +720,7 @@ class LibraryElementX extends ElementX implements LibraryElement { |
bool canUseNative = false; |
Link<Element> localMembers = const Link<Element>(); |
final ScopeX localScope = new ScopeX(); |
+ final ImportScope importScope = new ImportScope(); |
/** |
* If this library is patched, [patch] points to the patch library. |
@@ -659,14 +736,6 @@ class LibraryElementX extends ElementX implements LibraryElement { |
*/ |
final LibraryElementX origin; |
- /** |
- * Map for elements imported through import declarations. |
- * |
- * Addition to the map is performed by [addImport]. Lookup is done trough |
- * [find]. |
- */ |
- final Map<SourceString, Element> importScope; |
- |
/// A mapping from an imported element to the "import" tag. |
final Map<Element, Link<Import>> importers; |
@@ -685,7 +754,6 @@ class LibraryElementX extends ElementX implements LibraryElement { |
LibraryElementX(Script script, [Uri canonicalUri, LibraryElement this.origin]) |
: this.canonicalUri = ((canonicalUri == null) ? script.uri : canonicalUri), |
- importScope = new Map<SourceString, Element>(), |
importers = new Map<Element, Link<Import>>(), |
super(new SourceString(script.name), ElementKind.LIBRARY, null) { |
entryCompilationUnit = new CompilationUnitElementX(script, this); |
@@ -733,56 +801,7 @@ class LibraryElementX extends ElementX implements LibraryElement { |
* [ErroneousElement] will be put in the imported scope, allowing for detection of ambiguous uses of imported names. |
*/ |
void addImport(Element element, Import import, DiagnosticListener listener) { |
- importers[element] = |
- importers.putIfAbsent(element, () => const Link<Import>()) |
- .prepend(import); |
- SourceString name = element.name; |
- Element existing = importScope.putIfAbsent(name, () => element); |
- |
- Element createWarnOnUseElement(Spannable spannable, |
- MessageKind messageKind, |
- Element hidingElement, |
- Element hiddenElement) { |
- Uri hiddenUri = hiddenElement.getLibrary().canonicalUri; |
- Uri hidingUri = hidingElement.getLibrary().canonicalUri; |
- return new WarnOnUseElementX( |
- new WrappedMessage( |
- null, // Report on reference to [hidingElement]. |
- messageKind, |
- {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), |
- new WrappedMessage( |
- listener.spanFromSpannable(spannable), |
- MessageKind.IMPORTED_HERE, |
- {'name': name}), |
- this, hidingElement); |
- } |
- |
- if (existing != element) { |
- if (existing.getLibrary().isPlatformLibrary && |
- !element.getLibrary().isPlatformLibrary) { |
- // [existing] is implicitly hidden. |
- importScope[name] = createWarnOnUseElement( |
- import, MessageKind.HIDDEN_IMPORT, element, existing); |
- } else if (!existing.getLibrary().isPlatformLibrary && |
- element.getLibrary().isPlatformLibrary) { |
- // [element] is implicitly hidden. |
- if (import == null) { |
- // [element] is imported implicitly (probably through dart:core). |
- importScope[name] = createWarnOnUseElement( |
- importers[existing].head, MessageKind.HIDDEN_IMPLICIT_IMPORT, |
- existing, element); |
- } else { |
- importScope[name] = createWarnOnUseElement( |
- import, MessageKind.HIDDEN_IMPORT, existing, element); |
- } |
- } else { |
- // TODO(johnniwinther): Provide access to the import tags from which |
- // the elements came. |
- importScope[name] = new AmbiguousElementX( |
- MessageKind.DUPLICATE_IMPORT, {'name': name}, |
- this, existing, element); |
- } |
- } |
+ importScope.addImport(this, element, import, listener); |
} |
void addMember(Element element, DiagnosticListener listener) { |
@@ -932,18 +951,22 @@ class LibraryElementX extends ElementX implements LibraryElement { |
} |
class PrefixElementX extends ElementX implements PrefixElement { |
- Map<SourceString, Element> imported; |
Token firstPosition; |
+ final ImportScope importScope = new ImportScope(); |
+ |
PrefixElementX(SourceString prefix, Element enclosing, this.firstPosition) |
- : imported = new Map<SourceString, Element>(), |
- super(prefix, ElementKind.PREFIX, enclosing); |
+ : super(prefix, ElementKind.PREFIX, enclosing); |
- Element lookupLocalMember(SourceString memberName) => imported[memberName]; |
+ Element lookupLocalMember(SourceString memberName) => importScope[memberName]; |
DartType computeType(Compiler compiler) => compiler.types.dynamicType; |
Token position() => firstPosition; |
+ |
+ void addImport(Element element, Import import, DiagnosticListener listener) { |
+ importScope.addImport(this, element, import, listener); |
+ } |
} |
class TypedefElementX extends ElementX implements TypedefElement { |