Chromium Code Reviews| Index: lib/compiler/implementation/elements/elements.dart |
| diff --git a/lib/compiler/implementation/elements/elements.dart b/lib/compiler/implementation/elements/elements.dart |
| index 71a7d0007dc859acdfd21e5800441658cf7d6755..7b7440f7c579c359497a0da1f31d76158911b29b 100644 |
| --- a/lib/compiler/implementation/elements/elements.dart |
| +++ b/lib/compiler/implementation/elements/elements.dart |
| @@ -104,6 +104,9 @@ class ElementKind { |
| static const ElementKind VOID = |
| const ElementKind('void', ElementCategory.NONE); |
| + static const ElementKind ERROR = |
| + const ElementKind('error', ElementCategory.NONE); |
| + |
| toString() => id; |
| } |
| @@ -358,7 +361,8 @@ class ErroneousElement extends Element { |
| ErroneousElement(this.messageKind, this.messageArguments, |
| this.targetName, Element enclosing) |
| - : super(const SourceString('erroneous element'), null, enclosing); |
| + : super(const SourceString('erroneous element'), |
| + ElementKind.ERROR, enclosing); |
| isErroneous() => true; |
| @@ -367,7 +371,6 @@ class ErroneousElement extends Element { |
| } |
| SourceString get name => unsupported(); |
| - ElementKind get kind => unsupported(); |
| Link<MetadataAnnotation> get metadata => unsupported(); |
| getLibrary() => enclosingElement.getLibrary(); |
| @@ -585,6 +588,14 @@ class LibraryElement extends ScopeContainerElement { |
| */ |
| final Map<SourceString, Element> importScope; |
| + /** |
| + * Link for elements exported either through export declarations or through |
| + * declaration. |
| + * |
| + * [LibraryDependencyHandler] sets this map when the library is loaded. |
|
Lasse Reichstein Nielsen
2012/10/10 08:07:33
It's the classic set-once pattern.
I would prefer
Johnni Winther
2012/10/10 09:20:59
Done.
|
| + */ |
| + Link<Element> _exports; |
| + |
| LibraryElement(Script script, [Uri uri, LibraryElement this.origin]) |
| : this.uri = ((uri === null) ? script.uri : uri), |
| importScope = new Map<SourceString, Element>(), |
| @@ -617,8 +628,8 @@ class LibraryElement extends ScopeContainerElement { |
| * detection of ambiguous uses of imported names. |
| */ |
| void addImport(Element element, DiagnosticListener listener) { |
| - Element existing = importScope.putIfAbsent(element.name, () => element); |
| - if (existing !== element && existing !== null) { |
| + Element existing = importScope[element.name]; |
| + if (existing !== null) { |
| if (!existing.isErroneous()) { |
| // TODO(johnniwinther): Provide access to both the new and existing |
| // elements. |
| @@ -626,7 +637,35 @@ class LibraryElement extends ScopeContainerElement { |
| MessageKind.DUPLICATE_IMPORT, |
| [element.name], element.name, this); |
| } |
| + } else { |
| + importScope[element.name] = element; |
| + } |
| + } |
| + |
| + /** |
| + * Returns [:true:] if the export scope has already been computed for this |
| + * library. |
| + */ |
| + bool get exportsHandled => _exports !== null; |
| + |
| + Link<Element> get exports { |
| + assert(invariant(this, exportsHandled, |
| + message: 'Exports not handled on $this')); |
| + return _exports; |
| + } |
| + |
| + /** |
| + * Sets the export scope of this library. This method can only be called once. |
| + */ |
| + void setExports(Iterable<Element> iterable) { |
|
Lasse Reichstein Nielsen
2012/10/10 08:07:33
'iterable' -> 'exportedElements'.
Name for the mea
Johnni Winther
2012/10/10 09:20:59
Done.
|
| + assert(invariant(this, !exportsHandled, |
| + message: 'Exports already set to $_exports on $this')); |
| + assert(invariant(this, iterable !== null)); |
| + var builder = new LinkBuilder<Element>(); |
| + for (Element export in iterable) { |
| + builder.addLast(export); |
| } |
| + _exports = builder.toLink(); |
| } |
| LibraryElement getLibrary() => isPatch ? origin : this; |
| @@ -656,14 +695,7 @@ class LibraryElement extends ScopeContainerElement { |
| } |
| void forEachExport(f(Element element)) { |
| - localScope.forEach((_, Element e) { |
| - if (this === e.getLibrary() |
| - && e.kind !== ElementKind.PREFIX |
| - && e.kind !== ElementKind.FOREIGN |
| - && !e.name.isPrivate()) { |
| - f(e); |
| - } |
| - }); |
| + exports.forEach((Element e) => f(e)); |
| } |
| void forEachLocalMember(f(Element element)) { |