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 11 matching lines...) Expand all Loading... | |
| 22 class ElementKind { | 22 class ElementKind { |
| 23 final String id; | 23 final String id; |
| 24 | 24 |
| 25 const ElementKind(String this.id); | 25 const ElementKind(String this.id); |
| 26 | 26 |
| 27 static final ElementKind VARIABLE = const ElementKind('variable'); | 27 static final ElementKind VARIABLE = const ElementKind('variable'); |
| 28 static final ElementKind PARAMETER = const ElementKind('parameter'); | 28 static final ElementKind PARAMETER = const ElementKind('parameter'); |
| 29 static final ElementKind FUNCTION = const ElementKind('function'); | 29 static final ElementKind FUNCTION = const ElementKind('function'); |
| 30 static final ElementKind CLASS = const ElementKind('class'); | 30 static final ElementKind CLASS = const ElementKind('class'); |
| 31 static final ElementKind FOREIGN = const ElementKind('foreign'); | 31 static final ElementKind FOREIGN = const ElementKind('foreign'); |
| 32 static final ElementKind CONSTRUCTOR = const ElementKind('constructor'); | 32 static final ElementKind GENERATIVE_CONSTRUCTOR = |
|
ahe
2011/12/22 13:32:39
I like using terminology from the specification.
| |
| 33 const ElementKind('generative_constructor'); | |
| 33 static final ElementKind FIELD = const ElementKind('field'); | 34 static final ElementKind FIELD = const ElementKind('field'); |
| 34 static final ElementKind VARIABLE_LIST = const ElementKind('variable_list'); | 35 static final ElementKind VARIABLE_LIST = const ElementKind('variable_list'); |
| 35 static final ElementKind FIELD_LIST = const ElementKind('field_list'); | 36 static final ElementKind FIELD_LIST = const ElementKind('field_list'); |
| 36 static final ElementKind CONSTRUCTOR_BODY = | 37 static final ElementKind GENERATIVE_CONSTRUCTOR_BODY = |
| 37 const ElementKind('constructor_body'); | 38 const ElementKind('generative_constructor_body'); |
| 38 | 39 |
| 39 toString() => id; | 40 toString() => id; |
| 40 } | 41 } |
| 41 | 42 |
| 42 class Element implements Hashable { | 43 class Element implements Hashable { |
| 43 final SourceString name; | 44 final SourceString name; |
| 44 final ElementKind kind; | 45 final ElementKind kind; |
| 45 final Element enclosingElement; | 46 final Element enclosingElement; |
| 46 abstract Node parseNode(Canceler canceler, Logger logger); | 47 abstract Node parseNode(Canceler canceler, Logger logger); |
| 47 abstract Type computeType(Compiler compiler, Types types); | 48 abstract Type computeType(Compiler compiler, Types types); |
| 48 bool isMember() => | 49 bool isMember() => |
| 49 enclosingElement !== null && enclosingElement.kind == ElementKind.CLASS; | 50 enclosingElement !== null && enclosingElement.kind == ElementKind.CLASS; |
| 50 bool isInstanceMember() => false; | 51 bool isInstanceMember() => false; |
| 52 bool isGenerativeConstructor() => kind == ElementKind.GENERATIVE_CONSTRUCTOR; | |
| 51 | 53 |
| 52 const Element(this.name, this.kind, this.enclosingElement); | 54 const Element(this.name, this.kind, this.enclosingElement); |
| 53 | 55 |
| 54 // TODO(kasperl): This is a very bad hash code for the element and | 56 // TODO(kasperl): This is a very bad hash code for the element and |
| 55 // there's no reason why two elements with the same name should have | 57 // there's no reason why two elements with the same name should have |
| 56 // the same hash code. Replace this with a simple id in the element? | 58 // the same hash code. Replace this with a simple id in the element? |
| 57 int hashCode() => name.hashCode(); | 59 int hashCode() => name.hashCode(); |
| 58 | 60 |
| 59 toString() => '$kind($name)'; | 61 toString() => '$kind($name)'; |
| 60 } | 62 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 : super(name, kind, enclosing); | 163 : super(name, kind, enclosing); |
| 162 FunctionElement.node(FunctionExpression node, | 164 FunctionElement.node(FunctionExpression node, |
| 163 ElementKind kind, | 165 ElementKind kind, |
| 164 Modifiers this.modifiers, | 166 Modifiers this.modifiers, |
| 165 Element enclosing) | 167 Element enclosing) |
| 166 : super(node.name.asIdentifier().source, kind, enclosing), | 168 : super(node.name.asIdentifier().source, kind, enclosing), |
| 167 this.node = node; | 169 this.node = node; |
| 168 | 170 |
| 169 bool isInstanceMember() { | 171 bool isInstanceMember() { |
| 170 return isMember() | 172 return isMember() |
| 171 && kind != ElementKind.CONSTRUCTOR | 173 && kind != ElementKind.GENERATIVE_CONSTRUCTOR |
| 174 && !modifiers.isFactory() | |
| 172 && !modifiers.isStatic(); | 175 && !modifiers.isStatic(); |
| 173 } | 176 } |
| 174 | 177 |
| 175 FunctionType computeType(Compiler compiler, types) { | 178 FunctionType computeType(Compiler compiler, types) { |
| 176 if (type != null) return type; | 179 if (type != null) return type; |
| 177 if (parameters == null) compiler.resolveSignature(this); | 180 if (parameters == null) compiler.resolveSignature(this); |
| 178 FunctionExpression node = | 181 FunctionExpression node = |
| 179 compiler.parser.measure(() => parseNode(compiler, compiler)); | 182 compiler.parser.measure(() => parseNode(compiler, compiler)); |
| 180 Type returnType = getType(node.returnType, compiler, types); | 183 Type returnType = getType(node.returnType, compiler, types); |
| 181 if (returnType === null) compiler.cancel('unknown type ${node.returnType}'); | 184 if (returnType === null) returnType = types.dynamicType; |
| 182 | 185 |
| 183 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); | 186 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); |
| 184 for (Link<Element> link = parameters; !link.isEmpty(); link = link.tail) { | 187 for (Link<Element> link = parameters; !link.isEmpty(); link = link.tail) { |
| 185 parameterTypes.addLast(link.head.computeType(compiler, types)); | 188 parameterTypes.addLast(link.head.computeType(compiler, types)); |
| 186 } | 189 } |
| 187 type = new FunctionType(returnType, parameterTypes.toLink(), this); | 190 type = new FunctionType(returnType, parameterTypes.toLink(), this); |
| 188 return type; | 191 return type; |
| 189 } | 192 } |
| 190 | 193 |
| 191 Node parseNode(Canceler canceler, Logger logger) => node; | 194 Node parseNode(Canceler canceler, Logger logger) => node; |
| 192 } | 195 } |
| 193 | 196 |
| 194 class ConstructorBodyElement extends FunctionElement { | 197 class ConstructorBodyElement extends FunctionElement { |
| 195 FunctionElement constructor; | 198 FunctionElement constructor; |
| 196 | 199 |
| 197 ConstructorBodyElement(FunctionElement constructor) | 200 ConstructorBodyElement(FunctionElement constructor) |
| 198 : this.constructor = constructor, | 201 : this.constructor = constructor, |
| 199 super(constructor.name, | 202 super(constructor.name, |
| 200 ElementKind.CONSTRUCTOR_BODY, | 203 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, |
| 201 null, | 204 null, |
| 202 constructor.enclosingElement) { | 205 constructor.enclosingElement) { |
| 203 assert(constructor.node !== null); | 206 assert(constructor.node !== null); |
| 204 this.parameters = constructor.parameters; | 207 this.parameters = constructor.parameters; |
| 205 this.node = constructor.node; | 208 this.node = constructor.node; |
| 206 this.type = constructor.type; | 209 this.type = constructor.type; |
| 207 } | 210 } |
| 208 | 211 |
| 209 bool isInstanceMember() => true; | 212 bool isInstanceMember() => true; |
| 210 | 213 |
| 211 FunctionType computeType(Compiler compiler, types) { unreachable(); } | 214 FunctionType computeType(Compiler compiler, types) { unreachable(); } |
| 212 Node parseNode(Canceler canceler, Logger logger) { unreachable(); } | 215 Node parseNode(Canceler canceler, Logger logger) { unreachable(); } |
| 213 } | 216 } |
| 214 | 217 |
| 215 class SynthesizedConstructorElement extends FunctionElement { | 218 class SynthesizedConstructorElement extends FunctionElement { |
| 216 SynthesizedConstructorElement(Element enclosing) | 219 SynthesizedConstructorElement(Element enclosing) |
| 217 : super(enclosing.name, ElementKind.CONSTRUCTOR, null, enclosing) { | 220 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, |
| 221 null, enclosing) { | |
| 218 parameters = const EmptyLink<Element>(); | 222 parameters = const EmptyLink<Element>(); |
| 219 } | 223 } |
| 220 | 224 |
| 221 FunctionType computeType(Compiler compiler, types) { | 225 FunctionType computeType(Compiler compiler, types) { |
| 222 if (type != null) return type; | 226 if (type != null) return type; |
| 223 type = new FunctionType(types.voidType, const EmptyLink<Type>(), this); | 227 type = new FunctionType(types.voidType, const EmptyLink<Type>(), this); |
| 224 return type; | 228 return type; |
| 225 } | 229 } |
| 226 | 230 |
| 227 Node parseNode(Canceler canceler, Logger logger) { | 231 Node parseNode(Canceler canceler, Logger logger) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 link = link.tail) { | 279 link = link.tail) { |
| 276 Element element = link.head; | 280 Element element = link.head; |
| 277 if (matches(element)) return element; | 281 if (matches(element)) return element; |
| 278 } | 282 } |
| 279 return null; | 283 return null; |
| 280 } | 284 } |
| 281 | 285 |
| 282 Element lookupLocalMember(SourceString name) { | 286 Element lookupLocalMember(SourceString name) { |
| 283 bool matches(Element element) { | 287 bool matches(Element element) { |
| 284 return element.name == name | 288 return element.name == name |
| 285 && element.kind != ElementKind.CONSTRUCTOR; | 289 && element.kind != ElementKind.GENERATIVE_CONSTRUCTOR; |
| 286 } | 290 } |
| 287 return lookupLocalElement(name, matches); | 291 return lookupLocalElement(name, matches); |
| 288 } | 292 } |
| 289 | 293 |
| 290 Element lookupConstructor(SourceString name) { | 294 Element lookupConstructor(SourceString name) { |
| 291 bool matches(Element element) { | 295 bool matches(FunctionElement element) { |
| 292 return element.name == name | 296 return element.name == name |
| 293 && element.kind == ElementKind.CONSTRUCTOR; | 297 && (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR |
| 298 || element.modifiers.isFactory()); | |
| 294 } | 299 } |
| 295 return lookupLocalElement(name, matches); | 300 return lookupLocalElement(name, matches); |
| 296 } | 301 } |
| 297 | 302 |
| 298 // TODO(ngeoffray): Implement these. | 303 // TODO(ngeoffray): Implement these. |
| 299 bool canHaveDefaultConstructor() => true; | 304 bool canHaveDefaultConstructor() => true; |
| 300 | 305 |
| 301 SynthesizedConstructorElement getSynthesizedConstructor() { | 306 SynthesizedConstructorElement getSynthesizedConstructor() { |
| 302 if (synthesizedConstructor === null && canHaveDefaultConstructor()) { | 307 if (synthesizedConstructor === null && canHaveDefaultConstructor()) { |
| 303 synthesizedConstructor = new SynthesizedConstructorElement(this); | 308 synthesizedConstructor = new SynthesizedConstructorElement(this); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 330 && !element.isInstanceMember() | 335 && !element.isInstanceMember() |
| 331 && (element.kind === ElementKind.FIELD); | 336 && (element.kind === ElementKind.FIELD); |
| 332 } | 337 } |
| 333 | 338 |
| 334 static bool isInstanceMethod(Element element) { | 339 static bool isInstanceMethod(Element element) { |
| 335 return (element != null) | 340 return (element != null) |
| 336 && element.isInstanceMember() | 341 && element.isInstanceMember() |
| 337 && (element.kind === ElementKind.FUNCTION); | 342 && (element.kind === ElementKind.FUNCTION); |
| 338 } | 343 } |
| 339 } | 344 } |
| OLD | NEW |