| 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 } | 8 } |
| 9 | 9 |
| 10 class TreeElementMapping implements TreeElements { | 10 class TreeElementMapping implements TreeElements { |
| (...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 visitParenthesizedExpression(ParenthesizedExpression node) { | 951 visitParenthesizedExpression(ParenthesizedExpression node) { |
| 952 visit(node.expression); | 952 visit(node.expression); |
| 953 } | 953 } |
| 954 | 954 |
| 955 visitNewExpression(NewExpression node) { | 955 visitNewExpression(NewExpression node) { |
| 956 if (node.isConst()) { | 956 if (node.isConst()) { |
| 957 warning(node, MessageKind.GENERIC, | 957 warning(node, MessageKind.GENERIC, |
| 958 ['const expressions are not implemented']); | 958 ['const expressions are not implemented']); |
| 959 } | 959 } |
| 960 Node selector = node.send.selector; | 960 Node selector = node.send.selector; |
| 961 if (selector.asTypeAnnotation() === null) { | |
| 962 cancel( | |
| 963 node, 'named constructors with type arguments are not implemented'); | |
| 964 } | |
| 965 | 961 |
| 966 FunctionElement constructor = resolveConstructor(node); | 962 FunctionElement constructor = resolveConstructor(node); |
| 967 handleArguments(node.send); | 963 handleArguments(node.send); |
| 968 if (constructor === null) return null; | 964 if (constructor === null) return null; |
| 969 // TODO(karlklose): handle optional arguments. | 965 // TODO(karlklose): handle optional arguments. |
| 970 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { | 966 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { |
| 971 // TODO(ngeoffray): resolution error with wrong number of | 967 // TODO(ngeoffray): resolution error with wrong number of |
| 972 // parameters. We cannot do this rigth now because of the | 968 // parameters. We cannot do this rigth now because of the |
| 973 // List constructor. | 969 // List constructor. |
| 974 } | 970 } |
| 975 useElement(node.send, constructor); | 971 useElement(node.send, constructor); |
| 976 return null; | 972 return null; |
| 977 } | 973 } |
| 978 | 974 |
| 979 FunctionElement resolveConstructor(NewExpression node) { | 975 FunctionElement resolveConstructor(NewExpression node) { |
| 980 SourceString constructorName; | 976 FunctionElement constructor = |
| 981 Node selector = node.send.selector; | 977 node.accept(new ConstructorResolver(compiler, this)); |
| 982 Node typeName = selector.asTypeAnnotation().typeName; | 978 if (constructor === null) { |
| 983 if (typeName.asSend() !== null) { | 979 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); |
| 984 SourceString className = typeName.asSend().receiver.asIdentifier().source; | |
| 985 SourceString name = typeName.asSend().selector.asIdentifier().source; | |
| 986 constructorName = Elements.constructConstructorName(className, name); | |
| 987 } else { | |
| 988 constructorName = typeName.asIdentifier().source; | |
| 989 } | 980 } |
| 990 Element elt = resolveTypeRequired(selector); | 981 return constructor; |
| 991 if (elt === null) { | |
| 992 error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]); | |
| 993 return null; | |
| 994 } | |
| 995 if (elt.isTypedef()) { | |
| 996 error(selector, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [cls.name]); | |
| 997 return null; | |
| 998 } | |
| 999 if (!elt.isClass()) { | |
| 1000 error(selector, MessageKind.NOT_A_TYPE, [cls.name]); | |
| 1001 return null; | |
| 1002 } | |
| 1003 ClassElement cls = elt; | |
| 1004 cls.resolve(compiler); | |
| 1005 if (cls.isInterface() && (cls.defaultClass === null)) { | |
| 1006 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | |
| 1007 } | |
| 1008 FunctionElement constructor = cls.lookupConstructor(constructorName); | |
| 1009 if (constructor !== null) return constructor; | |
| 1010 if (constructorName == cls.name && node.send.argumentsNode.isEmpty()) { | |
| 1011 return cls.getSynthesizedConstructor(); | |
| 1012 } | |
| 1013 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | |
| 1014 return null; | |
| 1015 } | 982 } |
| 1016 | 983 |
| 1017 Element resolveTypeRequired(Node node) { | 984 Element resolveTypeRequired(Node node) { |
| 1018 bool old = typeRequired; | 985 bool old = typeRequired; |
| 1019 typeRequired = true; | 986 typeRequired = true; |
| 1020 Element element = visit(node); | 987 Element element = visit(node); |
| 1021 typeRequired = old; | 988 typeRequired = old; |
| 1022 return element; | 989 return element; |
| 1023 } | 990 } |
| 1024 | 991 |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 node.accept(new ResolverVisitor(compiler, enclosingElement)); | 1398 node.accept(new ResolverVisitor(compiler, enclosingElement)); |
| 1432 } | 1399 } |
| 1433 | 1400 |
| 1434 // TODO(ahe): This is temporary. | 1401 // TODO(ahe): This is temporary. |
| 1435 ClassElement get currentClass() { | 1402 ClassElement get currentClass() { |
| 1436 return enclosingElement.isMember() | 1403 return enclosingElement.isMember() |
| 1437 ? enclosingElement.enclosingElement : null; | 1404 ? enclosingElement.enclosingElement : null; |
| 1438 } | 1405 } |
| 1439 } | 1406 } |
| 1440 | 1407 |
| 1408 class ConstructorResolver extends CommonResolverVisitor<Element> { |
| 1409 final ResolverVisitor resolver; |
| 1410 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); |
| 1411 |
| 1412 visitNode(Node node) { |
| 1413 throw 'not supported'; |
| 1414 } |
| 1415 |
| 1416 visitNewExpression(NewExpression node) { |
| 1417 Node selector = node.send.selector; |
| 1418 Element e = visit(selector); |
| 1419 if (e !== null && e.kind === ElementKind.CLASS) { |
| 1420 ClassElement cls = e; |
| 1421 cls.resolve(compiler); |
| 1422 compiler.resolver.toResolve.add(cls); |
| 1423 if (cls.isInterface() && (cls.defaultClass === null)) { |
| 1424 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); |
| 1425 } |
| 1426 FunctionElement constructor = cls.lookupConstructor(cls.name); |
| 1427 if (constructor === null && node.send.argumentsNode.isEmpty()) { |
| 1428 e = cls.getSynthesizedConstructor(); |
| 1429 } else { |
| 1430 e = constructor; |
| 1431 } |
| 1432 } |
| 1433 return e; |
| 1434 } |
| 1435 |
| 1436 visitTypeAnnotation(TypeAnnotation node) { |
| 1437 // TODO(ahe): Do not ignore type arguments. |
| 1438 return visit(node.typeName); |
| 1439 } |
| 1440 |
| 1441 visitSend(Send node) { |
| 1442 Element e = visit(node.receiver); |
| 1443 if (e === null) return null; // TODO(ahe): Return erroneous element. |
| 1444 |
| 1445 if (e.kind === ElementKind.CLASS) { |
| 1446 ClassElement cls = e; |
| 1447 cls.resolve(compiler); |
| 1448 compiler.resolver.toResolve.add(cls); |
| 1449 if (cls.isInterface() && (cls.defaultClass === null)) { |
| 1450 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 1451 [cls.name]); |
| 1452 } |
| 1453 Identifier name = node.selector.asIdentifier(); |
| 1454 if (name === null) { |
| 1455 internalError(node.selector, 'unexpected node'); |
| 1456 } |
| 1457 SourceString constructorName = |
| 1458 Elements.constructConstructorName(cls.name, name.source); |
| 1459 FunctionElement constructor = cls.lookupConstructor(constructorName); |
| 1460 if (constructor === null) { |
| 1461 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]); |
| 1462 } |
| 1463 e = constructor; |
| 1464 } else { |
| 1465 internalError(node.resolve, 'unexpected element $e'); |
| 1466 } |
| 1467 return e; |
| 1468 } |
| 1469 |
| 1470 Element visitIdentifier(Identifier node) { |
| 1471 SourceString name = node.source; |
| 1472 Element e = resolver.lookup(node, name); |
| 1473 if (e === null) { |
| 1474 error(node, MessageKind.CANNOT_RESOLVE, [name]); |
| 1475 // TODO(ahe): Return erroneous element. |
| 1476 } else if (e.kind === ElementKind.TYPEDEF) { |
| 1477 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]); |
| 1478 } else if (e.kind !== ElementKind.CLASS) { |
| 1479 error(node, MessageKind.NOT_A_TYPE, [name]); |
| 1480 } |
| 1481 return e; |
| 1482 } |
| 1483 } |
| 1484 |
| 1441 class Scope { | 1485 class Scope { |
| 1442 final Element element; | 1486 final Element element; |
| 1443 final Scope parent; | 1487 final Scope parent; |
| 1444 | 1488 |
| 1445 Scope(this.parent, this.element); | 1489 Scope(this.parent, this.element); |
| 1446 abstract Element add(Element element); | 1490 abstract Element add(Element element); |
| 1447 abstract Element lookup(SourceString name); | 1491 abstract Element lookup(SourceString name); |
| 1448 } | 1492 } |
| 1449 | 1493 |
| 1450 class MethodScope extends Scope { | 1494 class MethodScope extends Scope { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 class TopScope extends Scope { | 1536 class TopScope extends Scope { |
| 1493 LibraryElement get library() => element; | 1537 LibraryElement get library() => element; |
| 1494 | 1538 |
| 1495 TopScope(LibraryElement library) : super(null, library); | 1539 TopScope(LibraryElement library) : super(null, library); |
| 1496 Element lookup(SourceString name) => library.find(name); | 1540 Element lookup(SourceString name) => library.find(name); |
| 1497 | 1541 |
| 1498 Element add(Element element) { | 1542 Element add(Element element) { |
| 1499 throw "Cannot add an element in the top scope"; | 1543 throw "Cannot add an element in the top scope"; |
| 1500 } | 1544 } |
| 1501 } | 1545 } |
| OLD | NEW |