| 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 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1444 visit(node.condition); | 1444 visit(node.condition); |
| 1445 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 1445 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 1446 } | 1446 } |
| 1447 | 1447 |
| 1448 visitParenthesizedExpression(ParenthesizedExpression node) { | 1448 visitParenthesizedExpression(ParenthesizedExpression node) { |
| 1449 visit(node.expression); | 1449 visit(node.expression); |
| 1450 } | 1450 } |
| 1451 | 1451 |
| 1452 visitNewExpression(NewExpression node) { | 1452 visitNewExpression(NewExpression node) { |
| 1453 Node selector = node.send.selector; | 1453 Node selector = node.send.selector; |
| 1454 | |
| 1455 FunctionElement constructor = resolveConstructor(node); | 1454 FunctionElement constructor = resolveConstructor(node); |
| 1456 resolveSelector(node.send); | 1455 resolveSelector(node.send); |
| 1457 resolveArguments(node.send.argumentsNode); | 1456 resolveArguments(node.send.argumentsNode); |
| 1458 if (constructor === null) return null; | 1457 useElement(node.send, constructor); |
| 1458 if (Element.isInvalid(constructor)) return constructor; |
| 1459 // TODO(karlklose): handle optional arguments. | 1459 // TODO(karlklose): handle optional arguments. |
| 1460 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { | 1460 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { |
| 1461 // TODO(ngeoffray): resolution error with wrong number of | 1461 // TODO(ngeoffray): resolution error with wrong number of |
| 1462 // parameters. We cannot do this rigth now because of the | 1462 // parameters. We cannot do this rigth now because of the |
| 1463 // List constructor. | 1463 // List constructor. |
| 1464 } | 1464 } |
| 1465 useElement(node.send, constructor); | |
| 1466 world.registerStaticUse(constructor); | 1465 world.registerStaticUse(constructor); |
| 1467 compiler.withCurrentElement(constructor, () { | 1466 compiler.withCurrentElement(constructor, () { |
| 1468 FunctionExpression tree = constructor.parseNode(compiler); | 1467 FunctionExpression tree = constructor.parseNode(compiler); |
| 1469 compiler.resolver.resolveConstructorImplementation(constructor, tree); | 1468 compiler.resolver.resolveConstructorImplementation(constructor, tree); |
| 1470 }); | 1469 }); |
| 1471 world.registerStaticUse(constructor.defaultImplementation); | 1470 world.registerStaticUse(constructor.defaultImplementation); |
| 1472 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); | 1471 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); |
| 1473 world.registerInstantiatedClass(cls); | 1472 world.registerInstantiatedClass(cls); |
| 1474 cls.forEachInstanceField( | 1473 cls.forEachInstanceField( |
| 1475 includeBackendMembers: false, | 1474 includeBackendMembers: false, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1486 } else if (send.selector.asSend() !== null) { | 1485 } else if (send.selector.asSend() !== null) { |
| 1487 Send selector = send.selector; | 1486 Send selector = send.selector; |
| 1488 if (selector.receiver.asTypeAnnotation() !== null) { | 1487 if (selector.receiver.asTypeAnnotation() !== null) { |
| 1489 return selector.receiver; | 1488 return selector.receiver; |
| 1490 } | 1489 } |
| 1491 } else { | 1490 } else { |
| 1492 compiler.internalError("malformed send in new expression"); | 1491 compiler.internalError("malformed send in new expression"); |
| 1493 } | 1492 } |
| 1494 } | 1493 } |
| 1495 | 1494 |
| 1495 /** |
| 1496 * Try to resolve the constructor that is referred to by [node]. |
| 1497 * Note: this function may return an ErroneousFunctionElement instead of |
| 1498 * [null], if there is no corresponding constructor, class or library. |
| 1499 */ |
| 1496 FunctionElement resolveConstructor(NewExpression node) { | 1500 FunctionElement resolveConstructor(NewExpression node) { |
| 1497 FunctionElement constructor = | 1501 FunctionElement constructor = |
| 1498 node.accept(new ConstructorResolver(compiler, this)); | 1502 node.accept(new ConstructorResolver(compiler, this)); |
| 1499 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send); | 1503 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send); |
| 1500 Type type = resolveTypeRequired(annotation); | 1504 // TODO(karlklose): clean up: the type should be resolved in the |
| 1501 if (constructor === null) { | 1505 // constructor resolver visitor to avoid visiting the node twice. |
| 1502 Element resolved = (type != null) ? type.element : null; | 1506 resolveTypeRequired(annotation); |
| 1503 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) { | |
| 1504 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR); | |
| 1505 return null; | |
| 1506 } else { | |
| 1507 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | |
| 1508 return null; | |
| 1509 } | |
| 1510 } | |
| 1511 return constructor; | 1507 return constructor; |
| 1512 } | 1508 } |
| 1513 | 1509 |
| 1514 Type resolveTypeRequired(TypeAnnotation node) { | 1510 Type resolveTypeRequired(TypeAnnotation node) { |
| 1515 bool old = typeRequired; | 1511 bool old = typeRequired; |
| 1516 typeRequired = true; | 1512 typeRequired = true; |
| 1517 Type result = resolveTypeAnnotation(node); | 1513 Type result = resolveTypeAnnotation(node); |
| 1518 typeRequired = old; | 1514 typeRequired = old; |
| 1519 return result; | 1515 return result; |
| 1520 } | 1516 } |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2317 | 2313 |
| 2318 // TODO(ahe): This is temporary. | 2314 // TODO(ahe): This is temporary. |
| 2319 ClassElement get currentClass() { | 2315 ClassElement get currentClass() { |
| 2320 return enclosingElement.isMember() | 2316 return enclosingElement.isMember() |
| 2321 ? enclosingElement.getEnclosingClass() : null; | 2317 ? enclosingElement.getEnclosingClass() : null; |
| 2322 } | 2318 } |
| 2323 } | 2319 } |
| 2324 | 2320 |
| 2325 class ConstructorResolver extends CommonResolverVisitor<Element> { | 2321 class ConstructorResolver extends CommonResolverVisitor<Element> { |
| 2326 final ResolverVisitor resolver; | 2322 final ResolverVisitor resolver; |
| 2323 |
| 2327 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); | 2324 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); |
| 2328 | 2325 |
| 2329 visitNode(Node node) { | 2326 visitNode(Node node) { |
| 2330 throw 'not supported'; | 2327 throw 'not supported'; |
| 2331 } | 2328 } |
| 2332 | 2329 |
| 2330 FunctionElement lookupConstructor(ClassElement cls, |
| 2331 Node diagnosticNode, |
| 2332 SourceString constructorName) { |
| 2333 cls.ensureResolved(compiler); |
| 2334 Element result = cls.lookupConstructor(cls.name, constructorName); |
| 2335 if (result === null) { |
| 2336 String fullConstructorName = cls.name.slowToString(); |
| 2337 if (constructorName !== const SourceString('')) { |
| 2338 fullConstructorName = '$fullConstructorName' |
| 2339 '.${constructorName.slowToString()}'; |
| 2340 } |
| 2341 ResolutionWarning message = |
| 2342 new ResolutionWarning(MessageKind.CANNOT_FIND_CONSTRUCTOR, |
| 2343 [fullConstructorName]); |
| 2344 compiler.reportWarning(diagnosticNode, message); |
| 2345 return new ErroneousFunctionElement(message, cls); |
| 2346 } |
| 2347 return result; |
| 2348 } |
| 2349 |
| 2333 visitNewExpression(NewExpression node) { | 2350 visitNewExpression(NewExpression node) { |
| 2334 Node selector = node.send.selector; | 2351 Node selector = node.send.selector; |
| 2335 Element e = visit(selector); | 2352 Element e = visit(selector); |
| 2336 if (e !== null && e.kind === ElementKind.CLASS) { | 2353 if (!Element.isInvalid(e) && e.kind === ElementKind.CLASS) { |
| 2337 ClassElement cls = e; | 2354 ClassElement cls = e; |
| 2338 cls.ensureResolved(compiler); | 2355 cls.ensureResolved(compiler); |
| 2339 if (cls.isInterface() && (cls.defaultClass === null)) { | 2356 if (cls.isInterface() && (cls.defaultClass === null)) { |
| 2340 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | 2357 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); |
| 2341 } | 2358 } |
| 2342 e = cls.lookupConstructor(cls.name); | 2359 e = lookupConstructor(cls, selector, const SourceString('')); |
| 2343 } | 2360 } |
| 2344 return e; | 2361 return e; |
| 2345 } | 2362 } |
| 2346 | 2363 |
| 2347 visitTypeAnnotation(TypeAnnotation node) { | 2364 visitTypeAnnotation(TypeAnnotation node) { |
| 2348 // TODO(ahe): Do not ignore type arguments. | 2365 // TODO(ahe): Do not ignore type arguments. |
| 2349 return visit(node.typeName); | 2366 return visit(node.typeName); |
| 2350 } | 2367 } |
| 2351 | 2368 |
| 2352 visitSend(Send node) { | 2369 visitSend(Send node) { |
| 2353 Element e = visit(node.receiver); | 2370 Element e = visit(node.receiver); |
| 2354 if (e === null) return null; // TODO(ahe): Return erroneous element. | 2371 if (e === null) return null; // TODO(ahe): Return erroneous element. |
| 2355 | 2372 |
| 2356 Identifier name = node.selector.asIdentifier(); | 2373 Identifier name = node.selector.asIdentifier(); |
| 2357 if (name === null) internalError(node.selector, 'unexpected node'); | 2374 if (name === null) internalError(node.selector, 'unexpected node'); |
| 2358 | 2375 |
| 2359 if (e.kind === ElementKind.CLASS) { | 2376 if (e.kind === ElementKind.CLASS) { |
| 2360 ClassElement cls = e; | 2377 ClassElement cls = e; |
| 2361 cls.ensureResolved(compiler); | 2378 cls.ensureResolved(compiler); |
| 2362 if (cls.isInterface() && (cls.defaultClass === null)) { | 2379 if (cls.isInterface() && (cls.defaultClass === null)) { |
| 2363 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, | 2380 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 2364 [cls.name]); | 2381 [cls.name]); |
| 2365 } | 2382 } |
| 2366 SourceString constructorName = | 2383 return lookupConstructor(cls, name, name.source); |
| 2367 Elements.constructConstructorName(cls.name, name.source); | |
| 2368 FunctionElement constructor = cls.lookupConstructor(constructorName); | |
| 2369 if (constructor === null) { | |
| 2370 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]); | |
| 2371 } | |
| 2372 e = constructor; | |
| 2373 } else if (e.kind === ElementKind.PREFIX) { | 2384 } else if (e.kind === ElementKind.PREFIX) { |
| 2374 PrefixElement prefix = e; | 2385 PrefixElement prefix = e; |
| 2375 e = prefix.lookupLocalMember(name.source); | 2386 e = prefix.lookupLocalMember(name.source); |
| 2376 if (e === null) { | 2387 if (e === null) { |
| 2377 error(name, MessageKind.CANNOT_RESOLVE, [name]); | 2388 error(name, MessageKind.CANNOT_RESOLVE, [name]); |
| 2378 // TODO(ahe): Return erroneous element. | 2389 // TODO(ahe): Return erroneous element. |
| 2379 } else if (e.kind !== ElementKind.CLASS) { | 2390 } else if (e.kind !== ElementKind.CLASS) { |
| 2380 error(node, MessageKind.NOT_A_TYPE, [name]); | 2391 error(node, MessageKind.NOT_A_TYPE, [name]); |
| 2381 } | 2392 } |
| 2382 } else { | 2393 } else { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2515 TopScope(LibraryElement library) : super(null, library); | 2526 TopScope(LibraryElement library) : super(null, library); |
| 2516 Element lookup(SourceString name) { | 2527 Element lookup(SourceString name) { |
| 2517 return library.find(name); | 2528 return library.find(name); |
| 2518 } | 2529 } |
| 2519 | 2530 |
| 2520 Element add(Element newElement) { | 2531 Element add(Element newElement) { |
| 2521 throw "Cannot add an element in the top scope"; | 2532 throw "Cannot add an element in the top scope"; |
| 2522 } | 2533 } |
| 2523 String toString() => '$element'; | 2534 String toString() => '$element'; |
| 2524 } | 2535 } |
| OLD | NEW |