| OLD | NEW |
| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 const ElementKind('field', ElementCategory.VARIABLE); | 58 const ElementKind('field', ElementCategory.VARIABLE); |
| 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', ElementCategory.NONE); |
| 69 ElementCategory.VARIABLE); // TODO(ahe): Sb. NONE. | |
| 70 static final ElementKind SETTER = | 69 static final ElementKind SETTER = |
| 71 const ElementKind('setter', | 70 const ElementKind('setter', ElementCategory.NONE); |
| 72 ElementCategory.VARIABLE); // TODO(ahe): Sb. NONE. | |
| 73 static final ElementKind ABSTRACT_FIELD = | 71 static final ElementKind ABSTRACT_FIELD = |
| 74 const ElementKind('abstract_field', ElementCategory.VARIABLE); | 72 const ElementKind('abstract_field', ElementCategory.VARIABLE); |
| 75 static final ElementKind LIBRARY = | 73 static final ElementKind LIBRARY = |
| 76 const ElementKind('library', ElementCategory.NONE); | 74 const ElementKind('library', ElementCategory.NONE); |
| 77 static final ElementKind PREFIX = | 75 static final ElementKind PREFIX = |
| 78 const ElementKind('prefix', ElementCategory.PREFIX); | 76 const ElementKind('prefix', ElementCategory.PREFIX); |
| 79 static final ElementKind TYPEDEF = | 77 static final ElementKind TYPEDEF = |
| 80 const ElementKind('typedef', ElementCategory.ALIAS); | 78 const ElementKind('typedef', ElementCategory.ALIAS); |
| 81 | 79 |
| 82 static final ElementKind STATEMENT = | 80 static final ElementKind STATEMENT = |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 } | 149 } |
| 152 | 150 |
| 153 toString() => '$kind(${name.slowToString()})'; | 151 toString() => '$kind(${name.slowToString()})'; |
| 154 } | 152 } |
| 155 | 153 |
| 156 class ContainerElement extends Element { | 154 class ContainerElement extends Element { |
| 157 ContainerElement(name, kind, enclosingElement) : | 155 ContainerElement(name, kind, enclosingElement) : |
| 158 super(name, kind, enclosingElement); | 156 super(name, kind, enclosingElement); |
| 159 | 157 |
| 160 abstract void addMember(Element element, DiagnosticListener listener); | 158 abstract void addMember(Element element, DiagnosticListener listener); |
| 159 |
| 160 void addGetterOrSetter(Element element, |
| 161 Element existing, |
| 162 DiagnosticListener listener) { |
| 163 void reportError(Element other) { |
| 164 listener.cancel('duplicate definition of ${element.name.slowToString()}', |
| 165 element: element); |
| 166 listener.cancel('existing definition', element: other); |
| 167 } |
| 168 |
| 169 if (existing != null) { |
| 170 if (existing.kind !== ElementKind.ABSTRACT_FIELD) { |
| 171 reportError(existing); |
| 172 } else { |
| 173 AbstractFieldElement field = existing; |
| 174 if (element.kind == ElementKind.GETTER) { |
| 175 if (field.getter != null && field.getter != element) { |
| 176 reportError(field.getter); |
| 177 } |
| 178 field.getter = element; |
| 179 } else { |
| 180 if (field.setter != null && field.setter != element) { |
| 181 reportError(field.setter); |
| 182 } |
| 183 field.setter = element; |
| 184 } |
| 185 } |
| 186 } else { |
| 187 AbstractFieldElement field = new AbstractFieldElement(element.name, this); |
| 188 addMember(field, listener); |
| 189 if (element.kind == ElementKind.GETTER) { |
| 190 field.getter = element; |
| 191 } else { |
| 192 field.setter = element; |
| 193 } |
| 194 } |
| 195 } |
| 161 } | 196 } |
| 162 | 197 |
| 163 class CompilationUnitElement extends ContainerElement { | 198 class CompilationUnitElement extends ContainerElement { |
| 164 final Script script; | 199 final Script script; |
| 165 Link<Element> topLevelElements = const EmptyLink<Element>(); | 200 Link<Element> topLevelElements = const EmptyLink<Element>(); |
| 166 | 201 |
| 167 CompilationUnitElement(Script script, Element enclosing) | 202 CompilationUnitElement(Script script, Element enclosing) |
| 168 : this.script = script, | 203 : this.script = script, |
| 169 super(new SourceString(script.name), | 204 super(new SourceString(script.name), |
| 170 ElementKind.COMPILATION_UNIT, | 205 ElementKind.COMPILATION_UNIT, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 void addTag(ScriptTag tag, DiagnosticListener listener) { | 247 void addTag(ScriptTag tag, DiagnosticListener listener) { |
| 213 tags = tags.prepend(tag); | 248 tags = tags.prepend(tag); |
| 214 } | 249 } |
| 215 | 250 |
| 216 void addMember(Element element, DiagnosticListener listener) { | 251 void addMember(Element element, DiagnosticListener listener) { |
| 217 topLevelElements = topLevelElements.prepend(element); | 252 topLevelElements = topLevelElements.prepend(element); |
| 218 define(element, listener); | 253 define(element, listener); |
| 219 } | 254 } |
| 220 | 255 |
| 221 void define(Element element, DiagnosticListener listener) { | 256 void define(Element element, DiagnosticListener listener) { |
| 222 Element existing = elements.putIfAbsent(element.name, () => element); | 257 if (element.kind == ElementKind.GETTER |
| 223 if (existing !== element) { | 258 || element.kind == ElementKind.SETTER) { |
| 224 listener.cancel('duplicate definition', token: element.position()); | 259 addGetterOrSetter(element, elements[element.name], listener); |
| 225 listener.cancel('existing definition', token: existing.position()); | 260 } else { |
| 261 Element existing = elements.putIfAbsent(element.name, () => element); |
| 262 if (existing !== element) { |
| 263 listener.cancel('duplicate definition', token: element.position()); |
| 264 listener.cancel('existing definition', token: existing.position()); |
| 265 } |
| 226 } | 266 } |
| 227 } | 267 } |
| 228 | 268 |
| 229 Element find(SourceString name) { | 269 Element find(SourceString name) { |
| 230 return elements[name]; | 270 return elements[name]; |
| 231 } | 271 } |
| 232 | 272 |
| 233 Element lookupLocalMember(SourceString name) { | 273 Element lookupLocalMember(SourceString name) { |
| 234 Element element = find(name); | 274 Element element = find(name); |
| 235 if (element === null) return null; | 275 if (element === null) return null; |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 } | 387 } |
| 348 | 388 |
| 349 parseNode(DiagnosticListener listener) { | 389 parseNode(DiagnosticListener listener) { |
| 350 throw "internal error: ForeignElement has no node"; | 390 throw "internal error: ForeignElement has no node"; |
| 351 } | 391 } |
| 352 } | 392 } |
| 353 | 393 |
| 354 class AbstractFieldElement extends Element { | 394 class AbstractFieldElement extends Element { |
| 355 FunctionElement getter; | 395 FunctionElement getter; |
| 356 FunctionElement setter; | 396 FunctionElement setter; |
| 397 Modifiers modifiers; |
| 398 |
| 357 AbstractFieldElement(SourceString name, Element enclosing) | 399 AbstractFieldElement(SourceString name, Element enclosing) |
| 358 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); | 400 : super(name, ElementKind.ABSTRACT_FIELD, enclosing), |
| 401 modifiers = new Modifiers.empty(); |
| 359 | 402 |
| 360 Type computeType(Compiler compiler) { | 403 Type computeType(Compiler compiler) { |
| 361 throw "internal error: AbstractFieldElement has no type"; | 404 throw "internal error: AbstractFieldElement has no type"; |
| 362 } | 405 } |
| 363 | 406 |
| 364 Node parseNode(DiagnosticListener listener) { | 407 Node parseNode(DiagnosticListener listener) { |
| 365 throw "internal error: AbstractFieldElement has no node"; | 408 throw "internal error: AbstractFieldElement has no node"; |
| 366 } | 409 } |
| 367 } | 410 } |
| 368 | 411 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 constructors = new Map<SourceString, Element>(), | 640 constructors = new Map<SourceString, Element>(), |
| 598 super(name, ElementKind.CLASS, enclosing); | 641 super(name, ElementKind.CLASS, enclosing); |
| 599 | 642 |
| 600 void addMember(Element element, DiagnosticListener listener) { | 643 void addMember(Element element, DiagnosticListener listener) { |
| 601 members = members.prepend(element); | 644 members = members.prepend(element); |
| 602 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || | 645 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| 603 element.modifiers.isFactory()) { | 646 element.modifiers.isFactory()) { |
| 604 constructors[element.name] = element; | 647 constructors[element.name] = element; |
| 605 } else if (element.kind == ElementKind.GETTER | 648 } else if (element.kind == ElementKind.GETTER |
| 606 || element.kind == ElementKind.SETTER) { | 649 || element.kind == ElementKind.SETTER) { |
| 607 Element existing = localMembers[element.name]; | 650 addGetterOrSetter(element, localMembers[element.name], listener); |
| 608 if (existing != null) { | |
| 609 if (existing.kind !== ElementKind.ABSTRACT_FIELD) { | |
| 610 listener.cancel('duplicate definition of ${name.slowToString()}', | |
| 611 element: element); | |
| 612 listener.cancel('existing definition', element: existing); | |
| 613 } else { | |
| 614 AbstractFieldElement field = existing; | |
| 615 if (element.kind == ElementKind.GETTER) { | |
| 616 if (field.getter != null) { | |
| 617 listener.cancel('duplicate definition of getter ${element.name}', | |
| 618 element: element); | |
| 619 listener.cancel('existing definition', element: field.getter); | |
| 620 } else { | |
| 621 field.getter = element; | |
| 622 } | |
| 623 } else { | |
| 624 if (field.setter != null) { | |
| 625 listener.cancel('duplicate definition of setter ${element.name}', | |
| 626 element: element); | |
| 627 listener.cancel('existing definition', element: field.setter); | |
| 628 } else { | |
| 629 field.setter = element; | |
| 630 } | |
| 631 } | |
| 632 } | |
| 633 } else { | |
| 634 AbstractFieldElement field = | |
| 635 new AbstractFieldElement(element.name, this); | |
| 636 localMembers[element.name] = field; | |
| 637 if (element.kind == ElementKind.GETTER) { | |
| 638 field.getter = element; | |
| 639 } else { | |
| 640 field.setter = element; | |
| 641 } | |
| 642 } | |
| 643 } else { | 651 } else { |
| 644 localMembers[element.name] = element; | 652 localMembers[element.name] = element; |
| 645 } | 653 } |
| 646 } | 654 } |
| 647 | 655 |
| 648 Type computeType(compiler) { | 656 Type computeType(compiler) { |
| 649 if (type === null) { | 657 if (type === null) { |
| 650 type = new SimpleType(name, this); | 658 type = new SimpleType(name, this); |
| 651 } | 659 } |
| 652 return type; | 660 return type; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 | 870 |
| 863 LabelElement addLabel(Identifier label, String labelName) { | 871 LabelElement addLabel(Identifier label, String labelName) { |
| 864 LabelElement result = new LabelElement(label, labelName, this, | 872 LabelElement result = new LabelElement(label, labelName, this, |
| 865 enclosingElement); | 873 enclosingElement); |
| 866 labels = labels.prepend(result); | 874 labels = labels.prepend(result); |
| 867 return result; | 875 return result; |
| 868 } | 876 } |
| 869 | 877 |
| 870 Node parseNode(DiagnosticListener l) => statement; | 878 Node parseNode(DiagnosticListener l) => statement; |
| 871 } | 879 } |
| OLD | NEW |