Chromium Code Reviews| Index: dart/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| diff --git a/dart/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/dart/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| index 27b8fa649a90b7de11a2e4596e7cb5e292eb980e..10aad9db071581c939fe2a2921299b6636760284 100644 |
| --- a/dart/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| +++ b/dart/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| @@ -377,6 +377,36 @@ class AmbiguousElementX extends ElementX implements AmbiguousElement { |
| super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement); |
| bool isAmbiguous() => true; |
| + |
| + Set flatten() { |
| + Element element = this; |
| + var set = new Set(); |
| + while (element.isAmbiguous()) { |
| + AmbiguousElement ambiguous = element; |
| + set.add(ambiguous.newElement); |
| + element = ambiguous.existingElement; |
| + } |
| + set.add(element); |
| + return set; |
| + } |
| + |
| + void diagnose(Element context, DiagnosticListener listener) { |
| + Set ambiguousElements = flatten(); |
| + MessageKind code = (ambiguousElements.length == 1) |
| + ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; |
| + LibraryElementX importer = context.getLibrary(); |
| + for (Element element in ambiguousElements) { |
| + var arguments = {'element': element}; |
| + listener.reportInfo(element, code, arguments); |
| + var importers = importer.importers[element]; |
|
Johnni Winther
2013/06/06 12:28:31
Type this variable.
ahe
2013/06/06 13:56:16
Done.
|
| + listener.withCurrentElement(importer, () { |
| + for (; !importers.isEmpty; importers = importers.tail) { |
| + listener.reportInfo( |
| + importers.head, MessageKind.IMPORTED_HERE, arguments); |
| + } |
| + }); |
| + } |
| + } |
| } |
| class ScopeX { |
| @@ -566,6 +596,9 @@ class LibraryElementX extends ElementX implements LibraryElement { |
| */ |
| final Map<SourceString, Element> importScope; |
| + /// A mapping from an imported element to the "import" tag. |
| + final Map<Element, Link<Import>> importers; |
| + |
| /** |
| * Link for elements exported either through export declarations or through |
| * declaration. This field should not be accessed directly but instead through |
| @@ -582,6 +615,7 @@ 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<SourceString, Element>(), |
| super(new SourceString(script.name), ElementKind.LIBRARY, null) { |
| entryCompilationUnit = new CompilationUnitElementX(script, this); |
| if (isPatch) { |
| @@ -628,7 +662,10 @@ class LibraryElementX extends ElementX implements LibraryElement { |
| * [ErroneousElement] will be put in the imported scope, allowing for the |
| * detection of ambiguous uses of imported names. |
| */ |
| - void addImport(Element element, DiagnosticListener listener) { |
| + void addImport(Element element, Import import, DiagnosticListener listener) { |
| + importers[element] = |
| + importers.putIfAbsent(element, () => const Link<Import>()) |
| + .prepend(import); |
| Element existing = importScope[element.name]; |
| if (existing != null) { |
| // TODO(johnniwinther): Provide access to the import tags from which |