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 20 matching lines...) Expand all Loading... | |
| 31 static final ElementKind FOREIGN = const ElementKind('foreign'); | 31 static final ElementKind FOREIGN = const ElementKind('foreign'); |
| 32 static final ElementKind GENERATIVE_CONSTRUCTOR = | 32 static final ElementKind GENERATIVE_CONSTRUCTOR = |
| 33 const ElementKind('generative_constructor'); | 33 const ElementKind('generative_constructor'); |
| 34 static final ElementKind FIELD = const ElementKind('field'); | 34 static final ElementKind FIELD = const ElementKind('field'); |
| 35 static final ElementKind VARIABLE_LIST = const ElementKind('variable_list'); | 35 static final ElementKind VARIABLE_LIST = const ElementKind('variable_list'); |
| 36 static final ElementKind FIELD_LIST = const ElementKind('field_list'); | 36 static final ElementKind FIELD_LIST = const ElementKind('field_list'); |
| 37 static final ElementKind GENERATIVE_CONSTRUCTOR_BODY = | 37 static final ElementKind GENERATIVE_CONSTRUCTOR_BODY = |
| 38 const ElementKind('generative_constructor_body'); | 38 const ElementKind('generative_constructor_body'); |
| 39 static final ElementKind COMPILATION_UNIT = | 39 static final ElementKind COMPILATION_UNIT = |
| 40 const ElementKind('compilation_unit'); | 40 const ElementKind('compilation_unit'); |
| 41 static final ElementKind GETTER = const ElementKind('getter'); | |
| 42 static final ElementKind SETTER = const ElementKind('setter'); | |
| 41 | 43 |
| 42 toString() => id; | 44 toString() => id; |
| 43 } | 45 } |
| 44 | 46 |
| 45 class Element implements Hashable { | 47 class Element implements Hashable { |
| 46 final SourceString name; | 48 final SourceString name; |
| 47 final ElementKind kind; | 49 final ElementKind kind; |
| 48 final Element enclosingElement; | 50 final Element enclosingElement; |
| 49 Modifiers get modifiers() => null; | 51 Modifiers get modifiers() => null; |
| 50 | 52 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 66 bool isCompilationUnit() => kind == ElementKind.COMPILATION_UNIT; | 68 bool isCompilationUnit() => kind == ElementKind.COMPILATION_UNIT; |
| 67 bool isVariable() => kind == ElementKind.VARIABLE; | 69 bool isVariable() => kind == ElementKind.VARIABLE; |
| 68 bool isParameter() => kind == ElementKind.PARAMETER; | 70 bool isParameter() => kind == ElementKind.PARAMETER; |
| 69 | 71 |
| 70 bool isAssignable() { | 72 bool isAssignable() { |
| 71 if (modifiers != null && modifiers.isFinal()) return false; | 73 if (modifiers != null && modifiers.isFinal()) return false; |
| 72 if (isFunction() || isGenerativeConstructor()) return false; | 74 if (isFunction() || isGenerativeConstructor()) return false; |
| 73 return true; | 75 return true; |
| 74 } | 76 } |
| 75 | 77 |
| 78 Token position() => null; | |
| 79 | |
| 76 const Element(this.name, this.kind, this.enclosingElement); | 80 const Element(this.name, this.kind, this.enclosingElement); |
| 77 | 81 |
| 78 // TODO(kasperl): This is a very bad hash code for the element and | 82 // TODO(kasperl): This is a very bad hash code for the element and |
| 79 // there's no reason why two elements with the same name should have | 83 // there's no reason why two elements with the same name should have |
| 80 // the same hash code. Replace this with a simple id in the element? | 84 // the same hash code. Replace this with a simple id in the element? |
| 81 int hashCode() => name.hashCode(); | 85 int hashCode() => name.hashCode(); |
| 82 | 86 |
| 83 toString() => '$kind($name)'; | 87 toString() => '$kind($name)'; |
| 84 } | 88 } |
| 85 | 89 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 | 129 |
| 126 Type computeType(Compiler compiler) { | 130 Type computeType(Compiler compiler) { |
| 127 return variables.computeType(compiler); | 131 return variables.computeType(compiler); |
| 128 } | 132 } |
| 129 | 133 |
| 130 Type get type() => variables.type; | 134 Type get type() => variables.type; |
| 131 | 135 |
| 132 bool isInstanceMember() { | 136 bool isInstanceMember() { |
| 133 return isMember() && !modifiers.isStatic(); | 137 return isMember() && !modifiers.isStatic(); |
| 134 } | 138 } |
| 139 | |
| 140 Token position() { | |
| 141 return (cachedNode !== null) | |
| 142 ? cachedNode.getBeginToken() : variables.position(); | |
|
ngeoffray
2012/01/25 08:36:05
This will return different values in time. Is that
ahe
2012/01/25 08:56:24
You're right.
I'll add a todo to record the Token
| |
| 143 } | |
| 135 } | 144 } |
| 136 | 145 |
| 137 // This element represents a list of variable or field declaration. | 146 // This element represents a list of variable or field declaration. |
| 138 // It contains the node, and the type. A [VariableElement] always | 147 // It contains the node, and the type. A [VariableElement] always |
| 139 // references its [VariableListElement]. It forwards its | 148 // references its [VariableListElement]. It forwards its |
| 140 // [computeType] and [parseNode] methods to this element. | 149 // [computeType] and [parseNode] methods to this element. |
| 141 class VariableListElement extends Element { | 150 class VariableListElement extends Element { |
| 142 VariableDefinitions cachedNode; | 151 VariableDefinitions cachedNode; |
| 143 Type type; | 152 Type type; |
| 144 final Modifiers modifiers; | 153 final Modifiers modifiers; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 158 VariableDefinitions parseNode(Canceler canceler, Logger logger) { | 167 VariableDefinitions parseNode(Canceler canceler, Logger logger) { |
| 159 return cachedNode; | 168 return cachedNode; |
| 160 } | 169 } |
| 161 | 170 |
| 162 Type computeType(Compiler compiler) { | 171 Type computeType(Compiler compiler) { |
| 163 if (type != null) return type; | 172 if (type != null) return type; |
| 164 type = getType(parseNode(compiler, compiler).type, compiler, | 173 type = getType(parseNode(compiler, compiler).type, compiler, |
| 165 compiler.types); | 174 compiler.types); |
| 166 return type; | 175 return type; |
| 167 } | 176 } |
| 177 | |
| 178 Token position() => cachedNode.getBeginToken(); | |
| 168 } | 179 } |
| 169 | 180 |
| 170 class ForeignElement extends Element { | 181 class ForeignElement extends Element { |
| 171 ForeignElement(SourceString name) : super(name, ElementKind.FOREIGN, null); | 182 ForeignElement(SourceString name) : super(name, ElementKind.FOREIGN, null); |
| 172 | 183 |
| 173 Type computeType(Compiler compiler) { | 184 Type computeType(Compiler compiler) { |
| 174 return compiler.types.dynamicType; | 185 return compiler.types.dynamicType; |
| 175 } | 186 } |
| 176 | 187 |
| 177 parseNode(Canceler canceler, Logger logger) { | 188 parseNode(Canceler canceler, Logger logger) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 | 265 |
| 255 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); | 266 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); |
| 256 for (Link<Element> link = parameters; !link.isEmpty(); link = link.tail) { | 267 for (Link<Element> link = parameters; !link.isEmpty(); link = link.tail) { |
| 257 parameterTypes.addLast(link.head.computeType(compiler)); | 268 parameterTypes.addLast(link.head.computeType(compiler)); |
| 258 } | 269 } |
| 259 type = new FunctionType(returnType, parameterTypes.toLink(), this); | 270 type = new FunctionType(returnType, parameterTypes.toLink(), this); |
| 260 return type; | 271 return type; |
| 261 } | 272 } |
| 262 | 273 |
| 263 Node parseNode(Canceler canceler, Logger logger) => cachedNode; | 274 Node parseNode(Canceler canceler, Logger logger) => cachedNode; |
| 275 | |
| 276 Token position() => cachedNode.getBeginToken(); | |
| 264 } | 277 } |
| 265 | 278 |
| 266 class ConstructorBodyElement extends FunctionElement { | 279 class ConstructorBodyElement extends FunctionElement { |
| 267 FunctionElement constructor; | 280 FunctionElement constructor; |
| 268 | 281 |
| 269 ConstructorBodyElement(FunctionElement constructor) | 282 ConstructorBodyElement(FunctionElement constructor) |
| 270 : this.constructor = constructor, | 283 : this.constructor = constructor, |
| 271 super(constructor.name, | 284 super(constructor.name, |
| 272 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, | 285 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, |
| 273 null, | 286 null, |
| 274 constructor.enclosingElement) { | 287 constructor.enclosingElement) { |
| 275 this.parameters = constructor.parameters; | 288 this.parameters = constructor.parameters; |
| 276 } | 289 } |
| 277 | 290 |
| 278 bool isInstanceMember() => true; | 291 bool isInstanceMember() => true; |
| 279 | 292 |
| 280 FunctionType computeType(Compiler compiler) { unreachable(); } | 293 FunctionType computeType(Compiler compiler) { unreachable(); } |
| 281 | 294 |
| 282 Node parseNode(Canceler canceler, Logger logger) { | 295 Node parseNode(Canceler canceler, Logger logger) { |
| 283 if (cachedNode !== null) return cachedNode; | 296 if (cachedNode !== null) return cachedNode; |
| 284 cachedNode = constructor.parseNode(canceler, logger); | 297 cachedNode = constructor.parseNode(canceler, logger); |
| 285 assert(cachedNode !== null); | 298 assert(cachedNode !== null); |
| 286 return cachedNode; | 299 return cachedNode; |
| 287 } | 300 } |
| 301 | |
| 302 Token position() => constructor.position(); | |
| 288 } | 303 } |
| 289 | 304 |
| 290 class SynthesizedConstructorElement extends FunctionElement { | 305 class SynthesizedConstructorElement extends FunctionElement { |
| 291 SynthesizedConstructorElement(Element enclosing) | 306 SynthesizedConstructorElement(Element enclosing) |
| 292 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, | 307 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, |
| 293 null, enclosing) { | 308 null, enclosing) { |
| 294 parameters = const EmptyLink<Element>(); | 309 parameters = const EmptyLink<Element>(); |
| 295 } | 310 } |
| 296 | 311 |
| 297 FunctionType computeType(Compiler compiler) { | 312 FunctionType computeType(Compiler compiler) { |
| 298 if (type != null) return type; | 313 if (type != null) return type; |
| 299 Type returnType = compiler.types.voidType; | 314 Type returnType = compiler.types.voidType; |
| 300 type = new FunctionType(returnType, const EmptyLink<Type>(), this); | 315 type = new FunctionType(returnType, const EmptyLink<Type>(), this); |
| 301 return type; | 316 return type; |
| 302 } | 317 } |
| 303 | 318 |
| 304 Node parseNode(Canceler canceler, Logger logger) { | 319 Node parseNode(Canceler canceler, Logger logger) { |
| 305 if (cachedNode != null) return cachedNode; | 320 if (cachedNode != null) return cachedNode; |
| 306 cachedNode = new FunctionExpression( | 321 cachedNode = new FunctionExpression( |
| 307 new Identifier.synthetic(''), | 322 new Identifier.synthetic(''), |
| 308 new NodeList.empty(), | 323 new NodeList.empty(), |
| 309 new Block(new NodeList.empty()), | 324 new Block(new NodeList.empty()), |
| 310 null, null, null); | 325 null, null, null); |
| 311 return cachedNode; | 326 return cachedNode; |
| 312 } | 327 } |
| 328 | |
| 329 Token position() => null; | |
| 313 } | 330 } |
| 314 | 331 |
| 315 class ClassElement extends Element { | 332 class ClassElement extends Element { |
| 316 Type type; | 333 Type type; |
| 317 Type supertype; | 334 Type supertype; |
| 318 Link<Element> members = const EmptyLink<Element>(); | 335 Link<Element> members = const EmptyLink<Element>(); |
| 319 Map<SourceString, Element> localMembers; | 336 Map<SourceString, Element> localMembers; |
| 320 Map<SourceString, Element> constructors; | 337 Map<SourceString, Element> constructors; |
| 321 Link<Type> interfaces = const EmptyLink<Type>(); | 338 Link<Type> interfaces = const EmptyLink<Type>(); |
| 322 bool isResolved = false; | 339 bool isResolved = false; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 if (send.isPropertyAccess) return false; | 438 if (send.isPropertyAccess) return false; |
| 422 if (send.receiver !== null) return false; | 439 if (send.receiver !== null) return false; |
| 423 Element element = elements[send]; | 440 Element element = elements[send]; |
| 424 // (o)() or foo()(). | 441 // (o)() or foo()(). |
| 425 if (element === null && send.selector.asIdentifier() === null) return true; | 442 if (element === null && send.selector.asIdentifier() === null) return true; |
| 426 if (element === null) return false; | 443 if (element === null) return false; |
| 427 // foo() with foo a local or a parameter. | 444 // foo() with foo a local or a parameter. |
| 428 return element.isVariable() || element.isParameter(); | 445 return element.isVariable() || element.isParameter(); |
| 429 } | 446 } |
| 430 } | 447 } |
| OLD | NEW |