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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 return element.computeType(compiler); | 202 return element.computeType(compiler); |
| 203 } | 203 } |
| 204 return types.lookup(name); | 204 return types.lookup(name); |
| 205 } | 205 } |
| 206 | 206 |
| 207 class FunctionElement extends Element { | 207 class FunctionElement extends Element { |
| 208 Link<Element> parameters; | 208 Link<Element> parameters; |
| 209 FunctionExpression cachedNode; | 209 FunctionExpression cachedNode; |
| 210 Type type; | 210 Type type; |
| 211 final Modifiers modifiers; | 211 final Modifiers modifiers; |
| 212 int cachedParameterCount; | |
| 212 | 213 |
| 213 FunctionElement(SourceString name, | 214 FunctionElement(SourceString name, |
| 214 ElementKind kind, | 215 ElementKind kind, |
| 215 Modifiers this.modifiers, | 216 Modifiers this.modifiers, |
| 216 Element enclosing, | 217 Element enclosing, |
| 217 [Node node]) | 218 [Node node]) |
| 218 : super(name, kind, enclosing), cachedNode = node; | 219 : super(name, kind, enclosing), cachedNode = node; |
| 219 FunctionElement.node(FunctionExpression node, | 220 FunctionElement.node(SourceString name, |
| 221 FunctionExpression node, | |
| 220 ElementKind kind, | 222 ElementKind kind, |
| 221 Modifiers this.modifiers, | 223 Modifiers this.modifiers, |
| 222 Element enclosing) | 224 Element enclosing) |
| 223 : super(node.name.asIdentifier().source, kind, enclosing), | 225 : super(name, kind, enclosing), |
| 224 this.cachedNode = node; | 226 this.cachedNode = node; |
| 225 | 227 |
| 226 bool isInstanceMember() { | 228 bool isInstanceMember() { |
| 227 return isMember() | 229 return isMember() |
| 228 && kind != ElementKind.GENERATIVE_CONSTRUCTOR | 230 && kind != ElementKind.GENERATIVE_CONSTRUCTOR |
| 229 && !modifiers.isFactory() | 231 && !modifiers.isFactory() |
| 230 && !modifiers.isStatic(); | 232 && !modifiers.isStatic(); |
| 231 } | 233 } |
| 232 | 234 |
| 235 int parameterCount(Compiler compiler) { | |
| 236 if (cachedParameterCount === null) { | |
| 237 cachedParameterCount = 0; | |
| 238 if (parameters == null) compiler.resolveSignature(this); | |
| 239 for (Link l = parameters; !l.isEmpty(); l = l.tail) { | |
| 240 cachedParameterCount++; | |
| 241 } | |
| 242 } | |
| 243 return cachedParameterCount; | |
| 244 } | |
| 245 | |
| 233 FunctionType computeType(Compiler compiler) { | 246 FunctionType computeType(Compiler compiler) { |
| 234 if (type != null) return type; | 247 if (type != null) return type; |
| 235 if (parameters == null) compiler.resolveSignature(this); | 248 if (parameters == null) compiler.resolveSignature(this); |
| 236 Types types = compiler.types; | 249 Types types = compiler.types; |
| 237 FunctionExpression node = | 250 FunctionExpression node = |
| 238 compiler.parser.measure(() => parseNode(compiler, compiler)); | 251 compiler.parser.measure(() => parseNode(compiler, compiler)); |
| 239 Type returnType = getType(node.returnType, compiler, types); | 252 Type returnType = getType(node.returnType, compiler, types); |
| 240 if (returnType === null) returnType = types.dynamicType; | 253 if (returnType === null) returnType = types.dynamicType; |
| 241 | 254 |
| 242 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); | 255 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 new Block(new NodeList.empty()), | 309 new Block(new NodeList.empty()), |
| 297 null, null, null); | 310 null, null, null); |
| 298 return cachedNode; | 311 return cachedNode; |
| 299 } | 312 } |
| 300 } | 313 } |
| 301 | 314 |
| 302 class ClassElement extends Element { | 315 class ClassElement extends Element { |
| 303 Type type; | 316 Type type; |
| 304 Type supertype; | 317 Type supertype; |
| 305 Link<Element> members = const EmptyLink<Element>(); | 318 Link<Element> members = const EmptyLink<Element>(); |
| 319 Map<SourceString, Element> localMembers; | |
| 320 Map<SourceString, Element> constructors; | |
| 306 Link<Type> interfaces = const EmptyLink<Type>(); | 321 Link<Type> interfaces = const EmptyLink<Type>(); |
| 307 bool isResolved = false; | 322 bool isResolved = false; |
| 308 // backendMembers are members that have been added by the backend to simplify | 323 // backendMembers are members that have been added by the backend to simplify |
| 309 // compilation. They don't have any user-side counter-part. | 324 // compilation. They don't have any user-side counter-part. |
| 310 Link<Element> backendMembers = const EmptyLink<Element>(); | 325 Link<Element> backendMembers = const EmptyLink<Element>(); |
| 311 SynthesizedConstructorElement synthesizedConstructor; | 326 SynthesizedConstructorElement synthesizedConstructor; |
| 312 | 327 |
| 313 ClassElement(SourceString name, CompilationUnitElement enclosing) | 328 ClassElement(SourceString name, CompilationUnitElement enclosing) |
| 314 : super(name, ElementKind.CLASS, enclosing); | 329 : localMembers = new Map<SourceString, Element>(), |
| 330 constructors = new Map<SourceString, Element>(), | |
| 331 super(name, ElementKind.CLASS, enclosing); | |
| 315 | 332 |
| 316 void addMember(Element element) { | 333 void addMember(Element element) { |
| 317 members = members.prepend(element); | 334 members = members.prepend(element); |
| 335 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || | |
| 336 element.modifiers.isFactory()) { | |
| 337 constructors[element.name] = element; | |
| 338 } else { | |
| 339 localMembers[element.name] = element; | |
| 340 } | |
| 318 } | 341 } |
| 319 | 342 |
| 320 Type computeType(compiler) { | 343 Type computeType(compiler) { |
| 321 if (type === null) { | 344 if (type === null) { |
| 322 type = new SimpleType(name, this); | 345 type = new SimpleType(name, this); |
| 323 } | 346 } |
| 324 return type; | 347 return type; |
| 325 } | 348 } |
| 326 | 349 |
| 327 ClassElement resolve(Compiler compiler) { | 350 ClassElement resolve(Compiler compiler) { |
| 328 if (!isResolved) { | 351 if (!isResolved) { |
| 329 compiler.resolveType(this); | 352 compiler.resolveType(this); |
| 330 isResolved = true; | 353 isResolved = true; |
| 331 } | 354 } |
| 332 return this; | 355 return this; |
| 333 } | 356 } |
| 334 | 357 |
| 335 Element lookupLocalElement(SourceString name, bool matches(Element)) { | 358 Element lookupLocalMember(SourceString name) { |
| 336 // TODO(karlklose): replace with more efficient solution. | 359 return localMembers[name]; |
| 337 for (Link<Element> link = members; | |
| 338 link !== null && !link.isEmpty(); | |
| 339 link = link.tail) { | |
| 340 Element element = link.head; | |
| 341 if (matches(element)) return element; | |
| 342 } | |
| 343 return null; | |
| 344 } | 360 } |
| 345 | 361 |
| 346 Element lookupLocalMember(SourceString name) { | 362 Element lookupConstructor(SourceString className, |
| 347 bool matches(Element element) { | 363 [SourceString constructor = const SourceString(''), |
|
ngeoffray
2012/01/20 13:54:17
constructor -> constructorName?
karlklose
2012/01/20 14:11:36
Done.
| |
| 348 return element.name == name | 364 Element noMatch(Element)]) { |
| 349 && element.kind != ElementKind.GENERATIVE_CONSTRUCTOR; | 365 // TODO(karlklose): have a map from class names to a map of constructors |
| 366 // instead of creating the name here? | |
| 367 SourceString name; | |
| 368 if (constructor !== const SourceString('')) { | |
| 369 name = new SourceString('$className.$constructor'); | |
| 370 } else { | |
| 371 name = className; | |
| 350 } | 372 } |
| 351 return lookupLocalElement(name, matches); | 373 Element result = constructors[name]; |
| 374 if (result === null && noMatch !== null) { | |
| 375 result = noMatch(lookupLocalMember(name)); | |
|
ngeoffray
2012/01/20 13:54:17
Shouldn't you check for constructorName if it is n
karlklose
2012/01/20 14:11:36
Done.
| |
| 376 } | |
| 377 return result; | |
| 352 } | 378 } |
| 353 | 379 |
| 354 Element lookupConstructor(SourceString name) { | 380 bool canHaveDefaultConstructor() => constructors.length == 0; |
| 355 bool matches(Element element) { | |
| 356 return element.name == name | |
| 357 && (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR | |
| 358 || element.modifiers.isFactory()); | |
| 359 } | |
| 360 return lookupLocalElement(name, matches); | |
| 361 } | |
| 362 | |
| 363 // TODO(ngeoffray): Implement these. | |
| 364 bool canHaveDefaultConstructor() => true; | |
| 365 | 381 |
| 366 SynthesizedConstructorElement getSynthesizedConstructor() { | 382 SynthesizedConstructorElement getSynthesizedConstructor() { |
| 367 if (synthesizedConstructor === null && canHaveDefaultConstructor()) { | 383 if (synthesizedConstructor === null && canHaveDefaultConstructor()) { |
| 368 synthesizedConstructor = new SynthesizedConstructorElement(this); | 384 synthesizedConstructor = new SynthesizedConstructorElement(this); |
| 369 } | 385 } |
| 370 return synthesizedConstructor; | 386 return synthesizedConstructor; |
| 371 } | 387 } |
| 372 | 388 |
| 373 /** | 389 /** |
| 374 * Returns the super class, if any. | 390 * Returns the super class, if any. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 404 if (send.isPropertyAccess) return false; | 420 if (send.isPropertyAccess) return false; |
| 405 if (send.receiver !== null) return false; | 421 if (send.receiver !== null) return false; |
| 406 Element element = elements[send]; | 422 Element element = elements[send]; |
| 407 // (o)() or foo()(). | 423 // (o)() or foo()(). |
| 408 if (element === null && send.selector.asIdentifier() === null) return true; | 424 if (element === null && send.selector.asIdentifier() === null) return true; |
| 409 if (element === null) return false; | 425 if (element === null) return false; |
| 410 // foo() with foo a local or a parameter. | 426 // foo() with foo a local or a parameter. |
| 411 return element.isVariable() || element.isParameter(); | 427 return element.isVariable() || element.isParameter(); |
| 412 } | 428 } |
| 413 } | 429 } |
| OLD | NEW |