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 432d835a3f4c120c8dc82a4093bea074d2af20cf..ca505589acdd914e0f87037ac8b80d27e5a9c99d 100644 |
| --- a/lib/compiler/implementation/elements/elements.dart |
| +++ b/lib/compiler/implementation/elements/elements.dart |
| @@ -247,14 +247,26 @@ class Element implements Hashable { |
| } |
| class ContainerElement extends Element { |
| - ContainerElement(name, kind, enclosingElement) : |
| - super(name, kind, enclosingElement); |
| + ContainerElement(name, kind, enclosingElement) |
| + : super(name, kind, enclosingElement); |
| abstract void addMember(Element element, DiagnosticListener listener); |
| - void addGetterOrSetter(Element element, |
| - Element existing, |
| - DiagnosticListener listener) { |
| + /** |
| + * Adds a definition for an accessor (getter or setter) to a container. |
|
ahe
2012/08/10 11:21:46
Please use the [] notation to refer to the argumen
Lasse Reichstein Nielsen
2012/08/13 13:37:51
Done.
|
| + * The definition binds to an abstract field that can hold both a getter |
| + * and a setter. |
| + * |
| + * The abstract field is added once, for the first getter or setter, and |
| + * reused if the other one is also added. |
| + * The abstract field should not be treated as a proper member of the |
| + * container, it's simply a way to return two results for one lookup. |
| + * I.e., the getter or setter does not have the abstract field as enclosing |
|
ahe
2012/08/10 11:21:46
Use English, not Latin. That is, use "that is", no
Lasse Reichstein Nielsen
2012/08/13 13:37:51
Done.
|
| + * element, they are enclosed by the class, as is the abstract field. |
| + */ |
| + void defineAccessor(Element element, |
| + Element existing, |
| + DiagnosticListener listener) { |
| void reportError(Element other) { |
| listener.cancel('duplicate definition of ${element.name.slowToString()}', |
| element: element); |
| @@ -272,6 +284,7 @@ class ContainerElement extends Element { |
| } |
| field.getter = element; |
| } else { |
| + assert(element.kind == ElementKind.SETTER); |
|
ahe
2012/08/10 11:21:46
This assertion does not hold if I write:
class Fo
Lasse Reichstein Nielsen
2012/08/13 13:37:51
I don't see how. Either element is a getter or it'
|
| if (field.setter != null && field.setter != element) { |
| reportError(field.setter); |
| } |
| @@ -285,9 +298,11 @@ class ContainerElement extends Element { |
| } else { |
| field.setter = element; |
| } |
| - addMember(field, listener); |
| + define(field, listener); |
| } |
| } |
| + |
| + abstract void define(Element element, DiagnosticListener listener); |
|
Anders Johnsen
2012/08/07 13:02:30
Could you add a short description to this member?
Lasse Reichstein Nielsen
2012/08/13 13:37:51
Done.
|
| } |
| class CompilationUnitElement extends ContainerElement { |
| @@ -352,15 +367,14 @@ class LibraryElement extends CompilationUnitElement { |
| } |
| void define(Element element, DiagnosticListener listener) { |
| - if (element.kind == ElementKind.GETTER |
| - || element.kind == ElementKind.SETTER) { |
| - addGetterOrSetter(element, elements[element.name], listener); |
| - } else { |
| - Element existing = elements.putIfAbsent(element.name, () => element); |
| - if (existing !== element) { |
| - listener.cancel('duplicate definition', token: element.position()); |
| - listener.cancel('existing definition', token: existing.position()); |
| - } |
| + if (element.isAccessor()) { |
| + defineAccessor(element, find(element.name), listener); |
| + return; |
| + } |
| + Element existing = elements.putIfAbsent(element.name, () => element); |
| + if (existing !== element) { |
| + listener.cancel('duplicate definition', token: element.position()); |
| + listener.cancel('existing definition', token: existing.position()); |
| } |
| } |
| @@ -897,12 +911,17 @@ class ClassElement extends ContainerElement |
| void addMember(Element element, DiagnosticListener listener) { |
| members = members.prepend(element); |
| + define(element, listener); |
| + } |
| + |
| + void define(Element element, DiagnosticListener listener) { |
| + if (element.isAccessor()) { |
| + defineAccessor(element, localMembers[element.name], listener); |
| + return; |
| + } |
| if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| element.modifiers.isFactory()) { |
| constructors[element.name] = element; |
| - } else if (element.kind == ElementKind.GETTER |
| - || element.kind == ElementKind.SETTER) { |
| - addGetterOrSetter(element, localMembers[element.name], listener); |
| } else { |
| localMembers[element.name] = element; |
| } |