| 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 // TODO(ahe): Record the token corresponding to name instead of |
| 142 // returning different values at different points in time. |
| 143 return (cachedNode !== null) |
| 144 ? cachedNode.getBeginToken() : variables.position(); |
| 145 } |
| 135 } | 146 } |
| 136 | 147 |
| 137 // This element represents a list of variable or field declaration. | 148 // This element represents a list of variable or field declaration. |
| 138 // It contains the node, and the type. A [VariableElement] always | 149 // It contains the node, and the type. A [VariableElement] always |
| 139 // references its [VariableListElement]. It forwards its | 150 // references its [VariableListElement]. It forwards its |
| 140 // [computeType] and [parseNode] methods to this element. | 151 // [computeType] and [parseNode] methods to this element. |
| 141 class VariableListElement extends Element { | 152 class VariableListElement extends Element { |
| 142 VariableDefinitions cachedNode; | 153 VariableDefinitions cachedNode; |
| 143 Type type; | 154 Type type; |
| 144 final Modifiers modifiers; | 155 final Modifiers modifiers; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 158 VariableDefinitions parseNode(Canceler canceler, Logger logger) { | 169 VariableDefinitions parseNode(Canceler canceler, Logger logger) { |
| 159 return cachedNode; | 170 return cachedNode; |
| 160 } | 171 } |
| 161 | 172 |
| 162 Type computeType(Compiler compiler) { | 173 Type computeType(Compiler compiler) { |
| 163 if (type != null) return type; | 174 if (type != null) return type; |
| 164 type = getType(parseNode(compiler, compiler).type, compiler, | 175 type = getType(parseNode(compiler, compiler).type, compiler, |
| 165 compiler.types); | 176 compiler.types); |
| 166 return type; | 177 return type; |
| 167 } | 178 } |
| 179 |
| 180 Token position() => cachedNode.getBeginToken(); |
| 168 } | 181 } |
| 169 | 182 |
| 170 class ForeignElement extends Element { | 183 class ForeignElement extends Element { |
| 171 ForeignElement(SourceString name) : super(name, ElementKind.FOREIGN, null); | 184 ForeignElement(SourceString name) : super(name, ElementKind.FOREIGN, null); |
| 172 | 185 |
| 173 Type computeType(Compiler compiler) { | 186 Type computeType(Compiler compiler) { |
| 174 return compiler.types.dynamicType; | 187 return compiler.types.dynamicType; |
| 175 } | 188 } |
| 176 | 189 |
| 177 parseNode(Canceler canceler, Logger logger) { | 190 parseNode(Canceler canceler, Logger logger) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 | 267 |
| 255 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); | 268 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); |
| 256 for (Link<Element> link = parameters; !link.isEmpty(); link = link.tail) { | 269 for (Link<Element> link = parameters; !link.isEmpty(); link = link.tail) { |
| 257 parameterTypes.addLast(link.head.computeType(compiler)); | 270 parameterTypes.addLast(link.head.computeType(compiler)); |
| 258 } | 271 } |
| 259 type = new FunctionType(returnType, parameterTypes.toLink(), this); | 272 type = new FunctionType(returnType, parameterTypes.toLink(), this); |
| 260 return type; | 273 return type; |
| 261 } | 274 } |
| 262 | 275 |
| 263 Node parseNode(Canceler canceler, Logger logger) => cachedNode; | 276 Node parseNode(Canceler canceler, Logger logger) => cachedNode; |
| 277 |
| 278 Token position() => cachedNode.getBeginToken(); |
| 264 } | 279 } |
| 265 | 280 |
| 266 class ConstructorBodyElement extends FunctionElement { | 281 class ConstructorBodyElement extends FunctionElement { |
| 267 FunctionElement constructor; | 282 FunctionElement constructor; |
| 268 | 283 |
| 269 ConstructorBodyElement(FunctionElement constructor) | 284 ConstructorBodyElement(FunctionElement constructor) |
| 270 : this.constructor = constructor, | 285 : this.constructor = constructor, |
| 271 super(constructor.name, | 286 super(constructor.name, |
| 272 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, | 287 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, |
| 273 null, | 288 null, |
| 274 constructor.enclosingElement) { | 289 constructor.enclosingElement) { |
| 275 this.parameters = constructor.parameters; | 290 this.parameters = constructor.parameters; |
| 276 } | 291 } |
| 277 | 292 |
| 278 bool isInstanceMember() => true; | 293 bool isInstanceMember() => true; |
| 279 | 294 |
| 280 FunctionType computeType(Compiler compiler) { unreachable(); } | 295 FunctionType computeType(Compiler compiler) { unreachable(); } |
| 281 | 296 |
| 282 Node parseNode(Canceler canceler, Logger logger) { | 297 Node parseNode(Canceler canceler, Logger logger) { |
| 283 if (cachedNode !== null) return cachedNode; | 298 if (cachedNode !== null) return cachedNode; |
| 284 cachedNode = constructor.parseNode(canceler, logger); | 299 cachedNode = constructor.parseNode(canceler, logger); |
| 285 assert(cachedNode !== null); | 300 assert(cachedNode !== null); |
| 286 return cachedNode; | 301 return cachedNode; |
| 287 } | 302 } |
| 303 |
| 304 Token position() => constructor.position(); |
| 288 } | 305 } |
| 289 | 306 |
| 290 class SynthesizedConstructorElement extends FunctionElement { | 307 class SynthesizedConstructorElement extends FunctionElement { |
| 291 SynthesizedConstructorElement(Element enclosing) | 308 SynthesizedConstructorElement(Element enclosing) |
| 292 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, | 309 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, |
| 293 null, enclosing) { | 310 null, enclosing) { |
| 294 parameters = const EmptyLink<Element>(); | 311 parameters = const EmptyLink<Element>(); |
| 295 } | 312 } |
| 296 | 313 |
| 297 FunctionType computeType(Compiler compiler) { | 314 FunctionType computeType(Compiler compiler) { |
| 298 if (type != null) return type; | 315 if (type != null) return type; |
| 299 Type returnType = compiler.types.voidType; | 316 Type returnType = compiler.types.voidType; |
| 300 type = new FunctionType(returnType, const EmptyLink<Type>(), this); | 317 type = new FunctionType(returnType, const EmptyLink<Type>(), this); |
| 301 return type; | 318 return type; |
| 302 } | 319 } |
| 303 | 320 |
| 304 Node parseNode(Canceler canceler, Logger logger) { | 321 Node parseNode(Canceler canceler, Logger logger) { |
| 305 if (cachedNode != null) return cachedNode; | 322 if (cachedNode != null) return cachedNode; |
| 306 cachedNode = new FunctionExpression( | 323 cachedNode = new FunctionExpression( |
| 307 new Identifier.synthetic(''), | 324 new Identifier.synthetic(''), |
| 308 new NodeList.empty(), | 325 new NodeList.empty(), |
| 309 new Block(new NodeList.empty()), | 326 new Block(new NodeList.empty()), |
| 310 null, null, null); | 327 null, null, null); |
| 311 return cachedNode; | 328 return cachedNode; |
| 312 } | 329 } |
| 330 |
| 331 Token position() => null; |
| 313 } | 332 } |
| 314 | 333 |
| 315 class ClassElement extends Element { | 334 class ClassElement extends Element { |
| 316 Type type; | 335 Type type; |
| 317 Type supertype; | 336 Type supertype; |
| 318 Link<Element> members = const EmptyLink<Element>(); | 337 Link<Element> members = const EmptyLink<Element>(); |
| 319 Map<SourceString, Element> localMembers; | 338 Map<SourceString, Element> localMembers; |
| 320 Map<SourceString, Element> constructors; | 339 Map<SourceString, Element> constructors; |
| 321 Link<Type> interfaces = const EmptyLink<Type>(); | 340 Link<Type> interfaces = const EmptyLink<Type>(); |
| 322 bool isResolved = false; | 341 bool isResolved = false; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 if (send.isPropertyAccess) return false; | 440 if (send.isPropertyAccess) return false; |
| 422 if (send.receiver !== null) return false; | 441 if (send.receiver !== null) return false; |
| 423 Element element = elements[send]; | 442 Element element = elements[send]; |
| 424 // (o)() or foo()(). | 443 // (o)() or foo()(). |
| 425 if (element === null && send.selector.asIdentifier() === null) return true; | 444 if (element === null && send.selector.asIdentifier() === null) return true; |
| 426 if (element === null) return false; | 445 if (element === null) return false; |
| 427 // foo() with foo a local or a parameter. | 446 // foo() with foo a local or a parameter. |
| 428 return element.isVariable() || element.isParameter(); | 447 return element.isVariable() || element.isParameter(); |
| 429 } | 448 } |
| 430 } | 449 } |
| OLD | NEW |