Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 | 43 |
| 44 toString() => id; | 44 toString() => id; |
| 45 } | 45 } |
| 46 | 46 |
| 47 class Element implements Hashable { | 47 class Element implements Hashable { |
| 48 final SourceString name; | 48 final SourceString name; |
| 49 final ElementKind kind; | 49 final ElementKind kind; |
| 50 final Element enclosingElement; | 50 final Element enclosingElement; |
| 51 Modifiers get modifiers() => null; | 51 Modifiers get modifiers() => null; |
| 52 | 52 |
| 53 | |
| 54 Node parseNode(Canceler canceler, Logger logger) { | 53 Node parseNode(Canceler canceler, Logger logger) { |
| 55 canceler.cancel("Internal Error: Element.parseNode"); | 54 canceler.cancel("Internal Error: Element.parseNode"); |
| 56 } | 55 } |
| 57 | 56 |
| 58 Type computeType(Compiler compiler) { | 57 Type computeType(Compiler compiler) { |
| 59 compiler.internalError("Element.computeType."); | 58 compiler.internalError("Element.computeType."); |
| 60 } | 59 } |
| 61 | 60 |
| 62 bool isFunction() => kind == ElementKind.FUNCTION; | 61 bool isFunction() => kind == ElementKind.FUNCTION; |
| 63 bool isMember() => | 62 bool isMember() => |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 80 const Element(this.name, this.kind, this.enclosingElement); | 79 const Element(this.name, this.kind, this.enclosingElement); |
| 81 | 80 |
| 82 // TODO(kasperl): This is a very bad hash code for the element and | 81 // TODO(kasperl): This is a very bad hash code for the element and |
| 83 // there's no reason why two elements with the same name should have | 82 // there's no reason why two elements with the same name should have |
| 84 // the same hash code. Replace this with a simple id in the element? | 83 // the same hash code. Replace this with a simple id in the element? |
| 85 int hashCode() => name.hashCode(); | 84 int hashCode() => name.hashCode(); |
| 86 | 85 |
| 87 toString() => '$kind($name)'; | 86 toString() => '$kind($name)'; |
| 88 } | 87 } |
| 89 | 88 |
| 90 class CompilationUnitElement extends Element { | 89 class EnclosingElement extends Element { |
|
ngeoffray
2012/01/25 09:04:59
EnclosingElement -> ContainerElement?
Because oth
ahe
2012/01/25 09:18:53
I was planning on making the other elements subcla
ahe
2012/01/25 09:28:53
Done.
| |
| 90 EnclosingElement(name, kind, enclosingElement) : | |
| 91 super(name, kind, enclosingElement); | |
| 92 | |
| 93 abstract void addMember(Element element, Canceler canceler); | |
| 94 } | |
| 95 | |
| 96 class CompilationUnitElement extends EnclosingElement { | |
| 91 final Script script; | 97 final Script script; |
| 98 Link<Element> topLevelElements = const EmptyLink<Element>(); | |
| 99 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); | |
| 100 final Map<SourceString, Element> scope; | |
| 101 | |
| 92 CompilationUnitElement(Script script, Element enclosing) | 102 CompilationUnitElement(Script script, Element enclosing) |
| 93 : super(new SourceString(script.name), | 103 : super(new SourceString(script.name), |
| 94 ElementKind.COMPILATION_UNIT, | 104 ElementKind.COMPILATION_UNIT, |
| 95 enclosing), | 105 enclosing), |
| 96 this.script = script; | 106 this.script = script, |
| 107 this.scope = new Map<SourceString, Element>(); | |
| 108 | |
| 109 void addMember(Element element, Canceler canceler) { | |
| 110 topLevelElements = topLevelElements.prepend(element); | |
| 111 Element existing = scope.putIfAbsent(element.name, ()=>element); | |
|
ngeoffray
2012/01/25 09:04:59
spaces around => ?
| |
| 112 if (existing !== element) { | |
|
ngeoffray
2012/01/25 09:04:59
Is this the right place to do it? Do we want a per
ahe
2012/01/25 09:18:53
You're right, there is not much value in reporting
ahe
2012/01/25 09:28:53
Done.
| |
| 113 canceler.cancel('duplicate definition', token: element.position()); | |
| 114 canceler.cancel('existing definition', token: existing.position()); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 void addTag(ScriptTag tag) { | |
| 119 tags = tags.prepend(tag); | |
| 120 } | |
| 97 } | 121 } |
| 98 | 122 |
| 99 class VariableElement extends Element { | 123 class VariableElement extends Element { |
| 100 final VariableListElement variables; | 124 final VariableListElement variables; |
| 101 Expression cachedNode; // The send or the identifier in the variables list. | 125 Expression cachedNode; // The send or the identifier in the variables list. |
| 102 | 126 |
| 103 Modifiers get modifiers() => variables.modifiers; | 127 Modifiers get modifiers() => variables.modifiers; |
| 104 | 128 |
| 105 VariableElement(SourceString name, | 129 VariableElement(SourceString name, |
| 106 VariableListElement this.variables, | 130 VariableListElement this.variables, |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 new Identifier.synthetic(''), | 346 new Identifier.synthetic(''), |
| 323 new NodeList.empty(), | 347 new NodeList.empty(), |
| 324 new Block(new NodeList.empty()), | 348 new Block(new NodeList.empty()), |
| 325 null, null, null); | 349 null, null, null); |
| 326 return cachedNode; | 350 return cachedNode; |
| 327 } | 351 } |
| 328 | 352 |
| 329 Token position() => null; | 353 Token position() => null; |
| 330 } | 354 } |
| 331 | 355 |
| 332 class ClassElement extends Element { | 356 class ClassElement extends EnclosingElement { |
| 333 Type type; | 357 Type type; |
| 334 Type supertype; | 358 Type supertype; |
| 335 Link<Element> members = const EmptyLink<Element>(); | 359 Link<Element> members = const EmptyLink<Element>(); |
| 336 Map<SourceString, Element> localMembers; | 360 Map<SourceString, Element> localMembers; |
| 337 Map<SourceString, Element> constructors; | 361 Map<SourceString, Element> constructors; |
| 338 Link<Type> interfaces = const EmptyLink<Type>(); | 362 Link<Type> interfaces = const EmptyLink<Type>(); |
| 339 bool isResolved = false; | 363 bool isResolved = false; |
| 340 // backendMembers are members that have been added by the backend to simplify | 364 // backendMembers are members that have been added by the backend to simplify |
| 341 // compilation. They don't have any user-side counter-part. | 365 // compilation. They don't have any user-side counter-part. |
| 342 Link<Element> backendMembers = const EmptyLink<Element>(); | 366 Link<Element> backendMembers = const EmptyLink<Element>(); |
| 343 SynthesizedConstructorElement synthesizedConstructor; | 367 SynthesizedConstructorElement synthesizedConstructor; |
| 344 | 368 |
| 345 ClassElement(SourceString name, CompilationUnitElement enclosing) | 369 ClassElement(SourceString name, CompilationUnitElement enclosing) |
| 346 : localMembers = new Map<SourceString, Element>(), | 370 : localMembers = new Map<SourceString, Element>(), |
| 347 constructors = new Map<SourceString, Element>(), | 371 constructors = new Map<SourceString, Element>(), |
| 348 super(name, ElementKind.CLASS, enclosing); | 372 super(name, ElementKind.CLASS, enclosing); |
| 349 | 373 |
| 350 void addMember(Element element) { | 374 void addMember(Element element, Canceler canceler) { |
| 351 members = members.prepend(element); | 375 members = members.prepend(element); |
| 352 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || | 376 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| 353 element.modifiers.isFactory()) { | 377 element.modifiers.isFactory()) { |
| 354 constructors[element.name] = element; | 378 constructors[element.name] = element; |
| 355 } else { | 379 } else { |
| 356 localMembers[element.name] = element; | 380 localMembers[element.name] = element; |
| 357 } | 381 } |
| 358 } | 382 } |
| 359 | 383 |
| 360 Type computeType(compiler) { | 384 Type computeType(compiler) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 if (send.isPropertyAccess) return false; | 462 if (send.isPropertyAccess) return false; |
| 439 if (send.receiver !== null) return false; | 463 if (send.receiver !== null) return false; |
| 440 Element element = elements[send]; | 464 Element element = elements[send]; |
| 441 // (o)() or foo()(). | 465 // (o)() or foo()(). |
| 442 if (element === null && send.selector.asIdentifier() === null) return true; | 466 if (element === null && send.selector.asIdentifier() === null) return true; |
| 443 if (element === null) return false; | 467 if (element === null) return false; |
| 444 // foo() with foo a local or a parameter. | 468 // foo() with foo a local or a parameter. |
| 445 return element.isVariable() || element.isParameter(); | 469 return element.isVariable() || element.isParameter(); |
| 446 } | 470 } |
| 447 } | 471 } |
| OLD | NEW |