Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: frog/leg/elements/elements.dart

Issue 9655024: Also create abstract fields for top-level getters and setters. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/language/language-leg.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #library('elements'); 5 #library('elements');
6 6
7 #import('../tree/tree.dart'); 7 #import('../tree/tree.dart');
8 #import('../scanner/scannerlib.dart'); 8 #import('../scanner/scannerlib.dart');
9 #import('../leg.dart'); // TODO(karlklose): we only need type. 9 #import('../leg.dart'); // TODO(karlklose): we only need type.
10 #import('../util/util.dart'); 10 #import('../util/util.dart');
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 static final ElementKind VARIABLE_LIST = 59 static final ElementKind VARIABLE_LIST =
60 const ElementKind('variable_list', ElementCategory.NONE); 60 const ElementKind('variable_list', ElementCategory.NONE);
61 static final ElementKind FIELD_LIST = 61 static final ElementKind FIELD_LIST =
62 const ElementKind('field_list', ElementCategory.NONE); 62 const ElementKind('field_list', ElementCategory.NONE);
63 static final ElementKind GENERATIVE_CONSTRUCTOR_BODY = 63 static final ElementKind GENERATIVE_CONSTRUCTOR_BODY =
64 const ElementKind('generative_constructor_body', ElementCategory.NONE); 64 const ElementKind('generative_constructor_body', ElementCategory.NONE);
65 static final ElementKind COMPILATION_UNIT = 65 static final ElementKind COMPILATION_UNIT =
66 const ElementKind('compilation_unit', ElementCategory.NONE); 66 const ElementKind('compilation_unit', ElementCategory.NONE);
67 static final ElementKind GETTER = 67 static final ElementKind GETTER =
68 const ElementKind('getter', 68 const ElementKind('getter',
69 ElementCategory.VARIABLE); // TODO(ahe): Sb. NONE. 69 ElementCategory.VARIABLE); // TODO(ahe): Sb. NONE.
ahe 2012/03/09 10:22:09 I think this can be NONE now.
ngeoffray 2012/03/09 13:05:56 Done.
70 static final ElementKind SETTER = 70 static final ElementKind SETTER =
71 const ElementKind('setter', 71 const ElementKind('setter',
72 ElementCategory.VARIABLE); // TODO(ahe): Sb. NONE. 72 ElementCategory.VARIABLE); // TODO(ahe): Sb. NONE.
ahe 2012/03/09 10:22:09 Ditto.
ngeoffray 2012/03/09 13:05:56 Done.
73 static final ElementKind ABSTRACT_FIELD = 73 static final ElementKind ABSTRACT_FIELD =
74 const ElementKind('abstract_field', ElementCategory.VARIABLE); 74 const ElementKind('abstract_field', ElementCategory.VARIABLE);
75 static final ElementKind LIBRARY = 75 static final ElementKind LIBRARY =
76 const ElementKind('library', ElementCategory.NONE); 76 const ElementKind('library', ElementCategory.NONE);
77 static final ElementKind PREFIX = 77 static final ElementKind PREFIX =
78 const ElementKind('prefix', ElementCategory.PREFIX); 78 const ElementKind('prefix', ElementCategory.PREFIX);
79 static final ElementKind TYPEDEF = 79 static final ElementKind TYPEDEF =
80 const ElementKind('typedef', ElementCategory.ALIAS); 80 const ElementKind('typedef', ElementCategory.ALIAS);
81 81
82 static final ElementKind STATEMENT = 82 static final ElementKind STATEMENT =
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 } 151 }
152 152
153 toString() => '$kind(${name.slowToString()})'; 153 toString() => '$kind(${name.slowToString()})';
154 } 154 }
155 155
156 class ContainerElement extends Element { 156 class ContainerElement extends Element {
157 ContainerElement(name, kind, enclosingElement) : 157 ContainerElement(name, kind, enclosingElement) :
158 super(name, kind, enclosingElement); 158 super(name, kind, enclosingElement);
159 159
160 abstract void addMember(Element element, DiagnosticListener listener); 160 abstract void addMember(Element element, DiagnosticListener listener);
161
162 void handleGetterOrSetter(Element element,
karlklose 2012/03/09 10:20:54 Call it addGetterOrSetter instead?
ngeoffray 2012/03/09 13:05:56 Done.
163 Element existing,
164 DiagnosticListener listener) {
165 if (existing != null) {
166 if (existing.kind !== ElementKind.ABSTRACT_FIELD) {
167 listener.cancel('duplicate definition of ${name.slowToString()}',
karlklose 2012/03/09 10:20:54 You could extract the error reporting to a local f
ngeoffray 2012/03/09 13:05:56 Done.
168 element: element);
169 listener.cancel('existing definition', element: existing);
170 } else {
171 AbstractFieldElement field = existing;
172 if (element.kind == ElementKind.GETTER) {
173 if (field.getter != null) {
174 listener.cancel('duplicate definition of getter ${element.name}',
175 element: element);
176 listener.cancel('existing definition', element: field.getter);
177 } else {
178 field.getter = element;
179 }
180 } else {
181 if (field.setter != null) {
182 listener.cancel('duplicate definition of setter ${element.name}',
183 element: element);
184 listener.cancel('existing definition', element: field.setter);
185 } else {
186 field.setter = element;
187 }
188 }
189 }
190 } else {
191 AbstractFieldElement field =
192 new AbstractFieldElement(element.name, this);
193 addMember(field, listener);
194 if (element.kind == ElementKind.GETTER) {
195 field.getter = element;
196 } else {
197 field.setter = element;
198 }
199 }
200 }
161 } 201 }
162 202
163 class CompilationUnitElement extends ContainerElement { 203 class CompilationUnitElement extends ContainerElement {
164 final Script script; 204 final Script script;
165 Link<Element> topLevelElements = const EmptyLink<Element>(); 205 Link<Element> topLevelElements = const EmptyLink<Element>();
166 206
167 CompilationUnitElement(Script script, Element enclosing) 207 CompilationUnitElement(Script script, Element enclosing)
168 : this.script = script, 208 : this.script = script,
169 super(new SourceString(script.name), 209 super(new SourceString(script.name),
170 ElementKind.COMPILATION_UNIT, 210 ElementKind.COMPILATION_UNIT,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 void addTag(ScriptTag tag, DiagnosticListener listener) { 252 void addTag(ScriptTag tag, DiagnosticListener listener) {
213 tags = tags.prepend(tag); 253 tags = tags.prepend(tag);
214 } 254 }
215 255
216 void addMember(Element element, DiagnosticListener listener) { 256 void addMember(Element element, DiagnosticListener listener) {
217 topLevelElements = topLevelElements.prepend(element); 257 topLevelElements = topLevelElements.prepend(element);
218 define(element, listener); 258 define(element, listener);
219 } 259 }
220 260
221 void define(Element element, DiagnosticListener listener) { 261 void define(Element element, DiagnosticListener listener) {
222 Element existing = elements.putIfAbsent(element.name, () => element); 262 if (element.kind == ElementKind.GETTER
223 if (existing !== element) { 263 || element.kind == ElementKind.SETTER) {
224 listener.cancel('duplicate definition', token: element.position()); 264 handleGetterOrSetter(element, elements[element.name], listener);
225 listener.cancel('existing definition', token: existing.position()); 265 } else {
266 Element existing = elements.putIfAbsent(element.name, () => element);
267 if (existing !== element) {
268 listener.cancel('duplicate definition', token: element.position());
269 listener.cancel('existing definition', token: existing.position());
270 }
226 } 271 }
227 } 272 }
228 273
229 Element find(SourceString name) { 274 Element find(SourceString name) {
230 return elements[name]; 275 return elements[name];
231 } 276 }
232 277
233 Element lookupLocalMember(SourceString name) { 278 Element lookupLocalMember(SourceString name) {
234 Element element = find(name); 279 Element element = find(name);
235 if (element === null) return null; 280 if (element === null) return null;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 } 392 }
348 393
349 parseNode(DiagnosticListener listener) { 394 parseNode(DiagnosticListener listener) {
350 throw "internal error: ForeignElement has no node"; 395 throw "internal error: ForeignElement has no node";
351 } 396 }
352 } 397 }
353 398
354 class AbstractFieldElement extends Element { 399 class AbstractFieldElement extends Element {
355 FunctionElement getter; 400 FunctionElement getter;
356 FunctionElement setter; 401 FunctionElement setter;
402 Modifiers modifiers;
403
357 AbstractFieldElement(SourceString name, Element enclosing) 404 AbstractFieldElement(SourceString name, Element enclosing)
358 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); 405 : super(name, ElementKind.ABSTRACT_FIELD, enclosing),
406 modifiers = new Modifiers.empty();
359 407
360 Type computeType(Compiler compiler) { 408 Type computeType(Compiler compiler) {
361 throw "internal error: AbstractFieldElement has no type"; 409 throw "internal error: AbstractFieldElement has no type";
362 } 410 }
363 411
364 Node parseNode(DiagnosticListener listener) { 412 Node parseNode(DiagnosticListener listener) {
365 throw "internal error: AbstractFieldElement has no node"; 413 throw "internal error: AbstractFieldElement has no node";
366 } 414 }
367 } 415 }
368 416
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 constructors = new Map<SourceString, Element>(), 644 constructors = new Map<SourceString, Element>(),
597 super(name, ElementKind.CLASS, enclosing); 645 super(name, ElementKind.CLASS, enclosing);
598 646
599 void addMember(Element element, DiagnosticListener listener) { 647 void addMember(Element element, DiagnosticListener listener) {
600 members = members.prepend(element); 648 members = members.prepend(element);
601 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || 649 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
602 element.modifiers.isFactory()) { 650 element.modifiers.isFactory()) {
603 constructors[element.name] = element; 651 constructors[element.name] = element;
604 } else if (element.kind == ElementKind.GETTER 652 } else if (element.kind == ElementKind.GETTER
605 || element.kind == ElementKind.SETTER) { 653 || element.kind == ElementKind.SETTER) {
606 Element existing = localMembers[element.name]; 654 handleGetterOrSetter(element, localMembers[element.name], listener);
607 if (existing != null) {
608 if (existing.kind !== ElementKind.ABSTRACT_FIELD) {
609 listener.cancel('duplicate definition of ${name.slowToString()}',
610 element: element);
611 listener.cancel('existing definition', element: existing);
612 } else {
613 AbstractFieldElement field = existing;
614 if (element.kind == ElementKind.GETTER) {
615 if (field.getter != null) {
616 listener.cancel('duplicate definition of getter ${element.name}',
617 element: element);
618 listener.cancel('existing definition', element: field.getter);
619 } else {
620 field.getter = element;
621 }
622 } else {
623 if (field.setter != null) {
624 listener.cancel('duplicate definition of setter ${element.name}',
625 element: element);
626 listener.cancel('existing definition', element: field.setter);
627 } else {
628 field.setter = element;
629 }
630 }
631 }
632 } else {
633 AbstractFieldElement field =
634 new AbstractFieldElement(element.name, this);
635 localMembers[element.name] = field;
636 if (element.kind == ElementKind.GETTER) {
637 field.getter = element;
638 } else {
639 field.setter = element;
640 }
641 }
642 } else { 655 } else {
643 localMembers[element.name] = element; 656 localMembers[element.name] = element;
644 } 657 }
645 } 658 }
646 659
647 Type computeType(compiler) { 660 Type computeType(compiler) {
648 if (type === null) { 661 if (type === null) {
649 type = new SimpleType(name, this); 662 type = new SimpleType(name, this);
650 } 663 }
651 return type; 664 return type;
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 869
857 LabelElement addLabel(Identifier label, String labelName) { 870 LabelElement addLabel(Identifier label, String labelName) {
858 LabelElement result = new LabelElement(label, labelName, this, 871 LabelElement result = new LabelElement(label, labelName, this,
859 enclosingElement); 872 enclosingElement);
860 labels = labels.prepend(result); 873 labels = labels.prepend(result);
861 return result; 874 return result;
862 } 875 }
863 876
864 Node parseNode(DiagnosticListener l) => statement; 877 Node parseNode(DiagnosticListener l) => statement;
865 } 878 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/language-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698