Chromium Code Reviews| Index: frog/leg/elements/elements.dart |
| =================================================================== |
| --- frog/leg/elements/elements.dart (revision 3735) |
| +++ frog/leg/elements/elements.dart (working copy) |
| @@ -30,6 +30,7 @@ |
| const ElementKind('compilation_unit'); |
| static final ElementKind GETTER = const ElementKind('getter'); |
| static final ElementKind SETTER = const ElementKind('setter'); |
| + static final ElementKind ABSTRACT_FIELD = const ElementKind('abstract_field'); |
| toString() => id; |
| } |
| @@ -207,6 +208,21 @@ |
| } |
| } |
| +class AbstractFieldElement extends Element { |
| + FunctionElement getter; |
| + FunctionElement setter; |
| + AbstractFieldElement(SourceString name, Element enclosing) |
| + : super(name, ElementKind.ABSTRACT_FIELD, enclosing); |
| + |
| + Type computeType(Compiler compiler) { |
| + throw "internal error: AbstractFieldElement has no type"; |
| + } |
| + |
| + Node parseNode(DiagnosticListener listener) { |
| + throw "internal error: AbstractFieldElement has no node"; |
| + } |
| +} |
| + |
| /** |
| * TODO(ngeoffray): Remove this method in favor of using the universe. |
| * |
| @@ -411,6 +427,43 @@ |
| if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| element.modifiers.isFactory()) { |
| constructors[element.name] = element; |
| + } else if (element.kind == ElementKind.GETTER |
| + || element.kind == ElementKind.SETTER) { |
| + Element existing = localMembers[element.name]; |
| + if (existing != null) { |
| + if (existing.kind !== ElementKind.ABSTRACT_FIELD) { |
| + listener.cancel('duplicate definition of $name', element: element); |
| + listener.cancel('existing definition', element: existing); |
| + } else { |
| + AbstractFieldElement field = existing; |
| + if (element.kind == ElementKind.GETTER) { |
| + if (field.getter != null) { |
| + listener.cancel('duplicate definition of getter ${element.name}', |
| + element: element); |
|
karlklose
2012/02/01 14:17:06
align with first argument?
ngeoffray
2012/02/01 15:57:12
Done.
|
| + listener.cancel('existing definition', element: field.getter); |
| + } else { |
| + field.getter = element; |
| + } |
| + } else { |
| + if (field.setter != null) { |
| + listener.cancel('duplicate definition of setter ${element.name}', |
| + element: element); |
|
karlklose
2012/02/01 14:17:06
ditto.
ngeoffray
2012/02/01 15:57:12
Done.
|
| + listener.cancel('existing definition', element: field.setter); |
| + } else { |
| + field.setter = element; |
| + } |
| + } |
| + } |
| + } else { |
| + AbstractFieldElement field = |
| + new AbstractFieldElement(element.name, this); |
| + localMembers[element.name] = field; |
| + if (element.kind == ElementKind.GETTER) { |
| + field.getter = element; |
| + } else { |
| + field.setter = element; |
| + } |
| + } |
| } else { |
| localMembers[element.name] = element; |
| } |
| @@ -478,13 +531,17 @@ |
| static bool isInstanceField(Element element) { |
| return (element !== null) |
| && element.isInstanceMember() |
| - && (element.kind === ElementKind.FIELD); |
| + && (element.kind === ElementKind.FIELD |
| + || element.kind === ElementKind.GETTER |
| + || element.kind === ElementKind.SETTER); |
| } |
| static bool isStaticOrTopLevelField(Element element) { |
| return (element != null) |
| && !element.isInstanceMember() |
| - && (element.kind === ElementKind.FIELD); |
| + && (element.kind === ElementKind.FIELD |
| + || element.kind === ElementKind.GETTER |
| + || element.kind === ElementKind.SETTER); |
| } |
| static bool isInstanceMethod(Element element) { |