Chromium Code Reviews| 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..c01dcc58d57afca75eebabdbd6f18babca2d1486 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| @@ -634,6 +634,80 @@ 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) { |
|
kasperl
2013/10/11 11:51:49
Use separate lines for the arguments?
Johnni Winther
2013/10/11 12:30:30
Done.
|
| + LibraryElementX library = enclosingElement.getLibrary(); |
| + Map<Element, Link<Import>> importers = library.importers; |
| + importers[element] = |
| + importers.putIfAbsent(element, () => const Link<Import>()) |
| + .prepend(import); |
|
kasperl
2013/10/11 11:51:49
Don't we usually indent this more?
Johnni Winther
2013/10/11 12:30:30
Yes. Done.
|
| + 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 +718,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 +734,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 +752,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 +799,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 +949,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 { |