Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 interface TreeElements { | 5 interface TreeElements { |
| 6 Element operator[](Node node); | 6 Element operator[](Node node); |
| 7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
| 8 Type getType(TypeAnnotation annotation); | 8 Type getType(TypeAnnotation annotation); |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1411 visit(node.condition); | 1411 visit(node.condition); |
| 1412 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 1412 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 1413 } | 1413 } |
| 1414 | 1414 |
| 1415 visitParenthesizedExpression(ParenthesizedExpression node) { | 1415 visitParenthesizedExpression(ParenthesizedExpression node) { |
| 1416 visit(node.expression); | 1416 visit(node.expression); |
| 1417 } | 1417 } |
| 1418 | 1418 |
| 1419 visitNewExpression(NewExpression node) { | 1419 visitNewExpression(NewExpression node) { |
| 1420 Node selector = node.send.selector; | 1420 Node selector = node.send.selector; |
| 1421 | |
| 1422 FunctionElement constructor = resolveConstructor(node); | 1421 FunctionElement constructor = resolveConstructor(node); |
| 1423 resolveSelector(node.send); | 1422 resolveSelector(node.send); |
| 1424 resolveArguments(node.send.argumentsNode); | 1423 resolveArguments(node.send.argumentsNode); |
| 1425 if (constructor === null) return null; | 1424 useElement(node.send, constructor); |
| 1425 if (Element.isInvalid(constructor)) return constructor; | |
| 1426 // TODO(karlklose): handle optional arguments. | 1426 // TODO(karlklose): handle optional arguments. |
| 1427 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { | 1427 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { |
| 1428 // TODO(ngeoffray): resolution error with wrong number of | 1428 // TODO(ngeoffray): resolution error with wrong number of |
| 1429 // parameters. We cannot do this rigth now because of the | 1429 // parameters. We cannot do this rigth now because of the |
| 1430 // List constructor. | 1430 // List constructor. |
| 1431 } | 1431 } |
| 1432 useElement(node.send, constructor); | |
| 1433 world.registerStaticUse(constructor); | 1432 world.registerStaticUse(constructor); |
| 1434 compiler.withCurrentElement(constructor, () { | 1433 compiler.withCurrentElement(constructor, () { |
| 1435 FunctionExpression tree = constructor.parseNode(compiler); | 1434 FunctionExpression tree = constructor.parseNode(compiler); |
| 1436 compiler.resolver.resolveConstructorImplementation(constructor, tree); | 1435 compiler.resolver.resolveConstructorImplementation(constructor, tree); |
| 1437 }); | 1436 }); |
| 1438 world.registerStaticUse(constructor.defaultImplementation); | 1437 world.registerStaticUse(constructor.defaultImplementation); |
| 1439 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); | 1438 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); |
| 1440 world.registerInstantiatedClass(cls); | 1439 world.registerInstantiatedClass(cls); |
| 1441 cls.forEachInstanceField( | 1440 cls.forEachInstanceField( |
| 1442 includeBackendMembers: false, | 1441 includeBackendMembers: false, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1453 } else if (send.selector.asSend() !== null) { | 1452 } else if (send.selector.asSend() !== null) { |
| 1454 Send selector = send.selector; | 1453 Send selector = send.selector; |
| 1455 if (selector.receiver.asTypeAnnotation() !== null) { | 1454 if (selector.receiver.asTypeAnnotation() !== null) { |
| 1456 return selector.receiver; | 1455 return selector.receiver; |
| 1457 } | 1456 } |
| 1458 } else { | 1457 } else { |
| 1459 compiler.internalError("malformed send in new expression"); | 1458 compiler.internalError("malformed send in new expression"); |
| 1460 } | 1459 } |
| 1461 } | 1460 } |
| 1462 | 1461 |
| 1462 /** | |
| 1463 * Try to resolve the constructor that is referred to by this | |
|
ahe
2012/08/20 15:06:47
"this" is not NewExpression, [node] is. So:
Try t
karlklose
2012/08/21 11:44:10
Done.
| |
| 1464 * [NewExpression]. | |
| 1465 * Note: this function may return an ErroneousFunctionElement instead of | |
| 1466 * [null], if there is no corresponding constructor, class or library. | |
| 1467 */ | |
| 1463 FunctionElement resolveConstructor(NewExpression node) { | 1468 FunctionElement resolveConstructor(NewExpression node) { |
| 1464 FunctionElement constructor = | 1469 FunctionElement constructor = |
| 1465 node.accept(new ConstructorResolver(compiler, this)); | 1470 node.accept(new ConstructorResolver(compiler, this)); |
| 1466 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send); | 1471 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send); |
| 1467 Type type = resolveTypeRequired(annotation); | 1472 Type type = resolveTypeRequired(annotation); |
|
ahe
2012/08/20 15:06:47
This looks bogus to me.
karlklose
2012/08/21 11:44:10
I added a TODO to clean this up.
| |
| 1468 if (constructor === null) { | 1473 if (constructor === null) { |
| 1469 Element resolved = (type != null) ? type.element : null; | 1474 Element resolved = (type != null) ? type.element : null; |
| 1470 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) { | 1475 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) { |
| 1471 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR); | 1476 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR); |
| 1472 return null; | 1477 return null; |
| 1473 } else { | |
| 1474 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | |
| 1475 return null; | |
| 1476 } | 1478 } |
| 1477 } | 1479 } |
| 1478 return constructor; | 1480 return constructor; |
| 1479 } | 1481 } |
| 1480 | 1482 |
| 1481 Type resolveTypeRequired(TypeAnnotation node) { | 1483 Type resolveTypeRequired(TypeAnnotation node) { |
| 1482 bool old = typeRequired; | 1484 bool old = typeRequired; |
| 1483 typeRequired = true; | 1485 typeRequired = true; |
| 1484 Type result = resolveTypeAnnotation(node); | 1486 Type result = resolveTypeAnnotation(node); |
| 1485 typeRequired = old; | 1487 typeRequired = old; |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2241 | 2243 |
| 2242 // TODO(ahe): This is temporary. | 2244 // TODO(ahe): This is temporary. |
| 2243 ClassElement get currentClass() { | 2245 ClassElement get currentClass() { |
| 2244 return enclosingElement.isMember() | 2246 return enclosingElement.isMember() |
| 2245 ? enclosingElement.getEnclosingClass() : null; | 2247 ? enclosingElement.getEnclosingClass() : null; |
| 2246 } | 2248 } |
| 2247 } | 2249 } |
| 2248 | 2250 |
| 2249 class ConstructorResolver extends CommonResolverVisitor<Element> { | 2251 class ConstructorResolver extends CommonResolverVisitor<Element> { |
| 2250 final ResolverVisitor resolver; | 2252 final ResolverVisitor resolver; |
| 2253 | |
| 2251 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); | 2254 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); |
| 2252 | 2255 |
| 2253 visitNode(Node node) { | 2256 visitNode(Node node) { |
| 2254 throw 'not supported'; | 2257 throw 'not supported'; |
| 2255 } | 2258 } |
| 2256 | 2259 |
| 2260 FunctionElement lookupConstructor(ClassElement cls, | |
| 2261 Node diagnosticNode, | |
| 2262 SourceString constructorName) { | |
| 2263 cls.ensureResolved(compiler); | |
| 2264 Element result = cls.lookupConstructor(cls.name, constructorName); | |
| 2265 if (result === null) { | |
| 2266 String fullConstructorName = cls.name.slowToString(); | |
| 2267 if (constructorName !== const SourceString('')) { | |
| 2268 fullConstructorName = '$fullConstructorName' | |
| 2269 '.${constructorName.slowToString()}'; | |
| 2270 } | |
| 2271 ResolutionWarning message = | |
| 2272 new ResolutionWarning(MessageKind.CANNOT_FIND_CONSTRUCTOR, | |
| 2273 [fullConstructorName]); | |
| 2274 compiler.reportWarning(diagnosticNode, message); | |
| 2275 return new ErroneousFunctionElement(message, cls); | |
| 2276 } | |
| 2277 return result; | |
| 2278 } | |
| 2279 | |
| 2257 visitNewExpression(NewExpression node) { | 2280 visitNewExpression(NewExpression node) { |
| 2258 Node selector = node.send.selector; | 2281 Node selector = node.send.selector; |
| 2259 Element e = visit(selector); | 2282 Element e = visit(selector); |
| 2260 if (e !== null && e.kind === ElementKind.CLASS) { | 2283 if (e !== null && e.isValid() && e.kind === ElementKind.CLASS) { |
|
ahe
2012/08/20 15:06:47
I don't like having to check for null and valid.
karlklose
2012/08/21 11:44:10
Done, forgot to change that after introducing the
| |
| 2261 ClassElement cls = e; | 2284 ClassElement cls = e; |
| 2262 cls.ensureResolved(compiler); | 2285 cls.ensureResolved(compiler); |
| 2263 if (cls.isInterface() && (cls.defaultClass === null)) { | 2286 if (cls.isInterface() && (cls.defaultClass === null)) { |
| 2264 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | 2287 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); |
| 2265 } | 2288 } |
| 2266 e = cls.lookupConstructor(cls.name); | 2289 e = lookupConstructor(cls, selector, const SourceString('')); |
| 2267 } | 2290 } |
| 2268 return e; | 2291 return e; |
| 2269 } | 2292 } |
| 2270 | 2293 |
| 2271 visitTypeAnnotation(TypeAnnotation node) { | 2294 visitTypeAnnotation(TypeAnnotation node) { |
| 2272 // TODO(ahe): Do not ignore type arguments. | 2295 // TODO(ahe): Do not ignore type arguments. |
| 2273 return visit(node.typeName); | 2296 return visit(node.typeName); |
| 2274 } | 2297 } |
| 2275 | 2298 |
| 2276 visitSend(Send node) { | 2299 visitSend(Send node) { |
| 2277 Element e = visit(node.receiver); | 2300 Element e = visit(node.receiver); |
| 2278 if (e === null) return null; // TODO(ahe): Return erroneous element. | 2301 if (e === null) return null; // TODO(ahe): Return erroneous element. |
| 2279 | 2302 |
| 2280 Identifier name = node.selector.asIdentifier(); | 2303 Identifier name = node.selector.asIdentifier(); |
| 2281 if (name === null) internalError(node.selector, 'unexpected node'); | 2304 if (name === null) internalError(node.selector, 'unexpected node'); |
| 2282 | 2305 |
| 2283 if (e.kind === ElementKind.CLASS) { | 2306 if (e.kind === ElementKind.CLASS) { |
| 2284 ClassElement cls = e; | 2307 ClassElement cls = e; |
| 2285 cls.ensureResolved(compiler); | 2308 cls.ensureResolved(compiler); |
| 2286 if (cls.isInterface() && (cls.defaultClass === null)) { | 2309 if (cls.isInterface() && (cls.defaultClass === null)) { |
| 2287 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, | 2310 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 2288 [cls.name]); | 2311 [cls.name]); |
| 2289 } | 2312 } |
| 2290 SourceString constructorName = | 2313 return lookupConstructor(cls, name, name.source); |
| 2291 Elements.constructConstructorName(cls.name, name.source); | |
| 2292 FunctionElement constructor = cls.lookupConstructor(constructorName); | |
| 2293 if (constructor === null) { | |
| 2294 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]); | |
| 2295 } | |
| 2296 e = constructor; | |
| 2297 } else if (e.kind === ElementKind.PREFIX) { | 2314 } else if (e.kind === ElementKind.PREFIX) { |
| 2298 PrefixElement prefix = e; | 2315 PrefixElement prefix = e; |
| 2299 e = prefix.lookupLocalMember(name.source); | 2316 e = prefix.lookupLocalMember(name.source); |
| 2300 if (e === null) { | 2317 if (e === null) { |
| 2301 error(name, MessageKind.CANNOT_RESOLVE, [name]); | 2318 error(name, MessageKind.CANNOT_RESOLVE, [name]); |
| 2302 // TODO(ahe): Return erroneous element. | 2319 // TODO(ahe): Return erroneous element. |
| 2303 } else if (e.kind !== ElementKind.CLASS) { | 2320 } else if (e.kind !== ElementKind.CLASS) { |
| 2304 error(node, MessageKind.NOT_A_TYPE, [name]); | 2321 error(node, MessageKind.NOT_A_TYPE, [name]); |
| 2305 } | 2322 } |
| 2306 } else { | 2323 } else { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2439 TopScope(LibraryElement library) : super(null, library); | 2456 TopScope(LibraryElement library) : super(null, library); |
| 2440 Element lookup(SourceString name) { | 2457 Element lookup(SourceString name) { |
| 2441 return library.find(name); | 2458 return library.find(name); |
| 2442 } | 2459 } |
| 2443 | 2460 |
| 2444 Element add(Element newElement) { | 2461 Element add(Element newElement) { |
| 2445 throw "Cannot add an element in the top scope"; | 2462 throw "Cannot add an element in the top scope"; |
| 2446 } | 2463 } |
| 2447 String toString() => '$element'; | 2464 String toString() => '$element'; |
| 2448 } | 2465 } |
| OLD | NEW |