Chromium Code Reviews| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |