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 } | 9 } |
9 | 10 |
10 class TreeElementMapping implements TreeElements { | 11 class TreeElementMapping implements TreeElements { |
11 Map<Node, Element> map; | 12 Map<Node, Element> map; |
12 Map<Send, Selector> selectors; | 13 Map<Send, Selector> selectors; |
| 14 Map<TypeAnnotation, Type> types; |
| 15 |
13 TreeElementMapping() | 16 TreeElementMapping() |
14 : map = new LinkedHashMap<Node, Element>(), | 17 : map = new LinkedHashMap<Node, Element>(), |
15 selectors = new LinkedHashMap<Send, Selector>(); | 18 selectors = new LinkedHashMap<Send, Selector>(), |
| 19 types = new LinkedHashMap<TypeAnnotation, Type>(); |
16 | 20 |
17 operator []=(Node node, Element element) => map[node] = element; | 21 operator []=(Node node, Element element) => map[node] = element; |
18 operator [](Node node) => map[node]; | 22 operator [](Node node) => map[node]; |
19 void remove(Node node) { map.remove(node); } | 23 void remove(Node node) { map.remove(node); } |
20 | 24 |
| 25 void setType(TypeAnnotation annotation, Type type) { |
| 26 types[annotation] = type; |
| 27 } |
| 28 |
| 29 Type getType(TypeAnnotation annotation) => types[annotation]; |
| 30 |
21 void setSelector(Send send, Selector selector) { | 31 void setSelector(Send send, Selector selector) { |
22 selectors[send] = selector; | 32 selectors[send] = selector; |
23 } | 33 } |
24 | 34 |
25 Selector getSelector(Send send) => selectors[send]; | 35 Selector getSelector(Send send) => selectors[send]; |
26 } | 36 } |
27 | 37 |
28 class ResolverTask extends CompilerTask { | 38 class ResolverTask extends CompilerTask { |
29 Queue<ClassElement> toResolve; | 39 Queue<ClassElement> toResolve; |
30 | 40 |
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 if ((element.kind.category & allowedCategory) == 0) { | 596 if ((element.kind.category & allowedCategory) == 0) { |
587 // TODO(ahe): Improve error message. Need UX input. | 597 // TODO(ahe): Improve error message. Need UX input. |
588 error(node, MessageKind.GENERIC, ["is not an expression $element"]); | 598 error(node, MessageKind.GENERIC, ["is not an expression $element"]); |
589 } | 599 } |
590 } | 600 } |
591 return useElement(node, element); | 601 return useElement(node, element); |
592 } | 602 } |
593 } | 603 } |
594 | 604 |
595 Element visitTypeAnnotation(TypeAnnotation node) { | 605 Element visitTypeAnnotation(TypeAnnotation node) { |
596 Send send = node.typeName.asSend(); | 606 Type type = resolveTypeAnnotation(node); |
597 Element element; | 607 if (type !== null) return type.element; |
598 if (send !== null) { | 608 return null; |
599 if (typeRequired) { | |
600 element = resolveSend(send); | |
601 } else { | |
602 // Not calling resolveSend as it will emit an error instead of | |
603 // a warning if the type is bogus. | |
604 // TODO(ahe): Change resolveSend so it can emit a warning when needed. | |
605 return null; | |
606 } | |
607 } else { | |
608 element = context.lookup(node.typeName.asIdentifier().source); | |
609 } | |
610 if (element === null) { | |
611 if (typeRequired) { | |
612 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | |
613 } else { | |
614 warning(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | |
615 } | |
616 } else if (!element.impliesType()) { | |
617 if (typeRequired) { | |
618 error(node, MessageKind.NOT_A_TYPE, [node.typeName]); | |
619 } else { | |
620 warning(node, MessageKind.NOT_A_TYPE, [node.typeName]); | |
621 } | |
622 } else { | |
623 if (element.isClass()) { | |
624 // TODO(ngeoffray): Should we also resolve typedef? | |
625 ClassElement cls = element; | |
626 compiler.resolver.toResolve.add(element); | |
627 } | |
628 // TODO(ahe): This should be a Type. | |
629 useElement(node, element); | |
630 } | |
631 return element; | |
632 } | 609 } |
633 | 610 |
634 Element defineElement(Node node, Element element, | 611 Element defineElement(Node node, Element element, |
635 [bool doAddToScope = true]) { | 612 [bool doAddToScope = true]) { |
636 compiler.ensure(element !== null); | 613 compiler.ensure(element !== null); |
637 mapping[node] = element; | 614 mapping[node] = element; |
638 if (doAddToScope) { | 615 if (doAddToScope) { |
639 Element existing = context.add(element); | 616 Element existing = context.add(element); |
640 if (existing != element) { | 617 if (existing != element) { |
641 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); | 618 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); |
642 } | 619 } |
643 } | 620 } |
644 return element; | 621 return element; |
645 } | 622 } |
646 | 623 |
647 Element useElement(Node node, Element element) { | 624 Element useElement(Node node, Element element) { |
648 if (element === null) return null; | 625 if (element === null) return null; |
649 return mapping[node] = element; | 626 return mapping[node] = element; |
650 } | 627 } |
651 | 628 |
| 629 Type useType(TypeAnnotation annotation, Type type) { |
| 630 if (type !== null) { |
| 631 mapping.setType(annotation, type); |
| 632 useElement(annotation, type.element); |
| 633 } |
| 634 return type; |
| 635 } |
| 636 |
652 void setupFunction(FunctionExpression node, FunctionElement function) { | 637 void setupFunction(FunctionExpression node, FunctionElement function) { |
653 context = new MethodScope(context, function); | 638 context = new MethodScope(context, function); |
654 // Put the parameters in scope. | 639 // Put the parameters in scope. |
655 FunctionParameters functionParameters = | 640 FunctionParameters functionParameters = |
656 function.computeParameters(compiler); | 641 function.computeParameters(compiler); |
657 Link<Node> parameterNodes = node.parameters.nodes; | 642 Link<Node> parameterNodes = node.parameters.nodes; |
658 functionParameters.forEachParameter((Element element) { | 643 functionParameters.forEachParameter((Element element) { |
659 if (element == functionParameters.optionalParameters.head) { | 644 if (element == functionParameters.optionalParameters.head) { |
660 NodeList nodes = parameterNodes.head; | 645 NodeList nodes = parameterNodes.head; |
661 parameterNodes = nodes.nodes; | 646 parameterNodes = nodes.nodes; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 } else if (resolvedReceiver.kind === ElementKind.PREFIX) { | 806 } else if (resolvedReceiver.kind === ElementKind.PREFIX) { |
822 PrefixElement prefix = resolvedReceiver; | 807 PrefixElement prefix = resolvedReceiver; |
823 target = prefix.lookupLocalMember(name); | 808 target = prefix.lookupLocalMember(name); |
824 if (target == null) { | 809 if (target == null) { |
825 error(node, MessageKind.NO_SUCH_LIBRARY_MEMBER, [prefix.name, name]); | 810 error(node, MessageKind.NO_SUCH_LIBRARY_MEMBER, [prefix.name, name]); |
826 } | 811 } |
827 } | 812 } |
828 return target; | 813 return target; |
829 } | 814 } |
830 | 815 |
831 resolveTypeTest(Node argument) { | 816 Type resolveTypeTest(Node argument) { |
832 TypeAnnotation node = argument.asTypeAnnotation(); | 817 TypeAnnotation node = argument.asTypeAnnotation(); |
833 if (node == null) { | 818 if (node == null) { |
834 node = argument.asSend().receiver; | 819 // node is of the form !Type. |
| 820 node = argument.asSend().receiver.asTypeAnnotation(); |
| 821 if (node === null) compiler.cancel("malformed send"); |
835 } | 822 } |
836 resolveTypeRequired(node); | 823 return resolveTypeRequired(node); |
837 } | 824 } |
838 | 825 |
839 void handleArguments(Send node) { | 826 void handleArguments(Send node) { |
840 int count = 0; | 827 int count = 0; |
841 List<SourceString> namedArguments = <SourceString>[]; | 828 List<SourceString> namedArguments = <SourceString>[]; |
842 bool seenNamedArgument = false; | 829 bool seenNamedArgument = false; |
843 for (Link<Node> link = node.argumentsNode.nodes; | 830 for (Link<Node> link = node.argumentsNode.nodes; |
844 !link.isEmpty(); | 831 !link.isEmpty(); |
845 link = link.tail) { | 832 link = link.tail) { |
846 count++; | 833 count++; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 // TODO(karlklose): handle optional arguments. | 976 // TODO(karlklose): handle optional arguments. |
990 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { | 977 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { |
991 // TODO(ngeoffray): resolution error with wrong number of | 978 // TODO(ngeoffray): resolution error with wrong number of |
992 // parameters. We cannot do this rigth now because of the | 979 // parameters. We cannot do this rigth now because of the |
993 // List constructor. | 980 // List constructor. |
994 } | 981 } |
995 useElement(node.send, constructor); | 982 useElement(node.send, constructor); |
996 return null; | 983 return null; |
997 } | 984 } |
998 | 985 |
| 986 TypeAnnotation getTypeAnnotationFromSend(Send send) { |
| 987 if (send.selector.asTypeAnnotation() !== null) { |
| 988 return send.selector; |
| 989 } else if (send.selector.asSend() !== null) { |
| 990 Send selector = send.selector; |
| 991 if (selector.receiver.asTypeAnnotation() !== null) { |
| 992 return selector.receiver; |
| 993 } |
| 994 } else { |
| 995 compiler.internalError("malformed send in new expression"); |
| 996 } |
| 997 } |
| 998 |
999 FunctionElement resolveConstructor(NewExpression node) { | 999 FunctionElement resolveConstructor(NewExpression node) { |
1000 FunctionElement constructor = | 1000 FunctionElement constructor = |
1001 node.accept(new ConstructorResolver(compiler, this)); | 1001 node.accept(new ConstructorResolver(compiler, this)); |
| 1002 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send); |
| 1003 Type type = resolveTypeRequired(annotation); |
1002 if (constructor === null) { | 1004 if (constructor === null) { |
1003 Element resolved = resolveTypeRequired(node.send.selector); | 1005 Element resolved = (type != null) ? type.element : null; |
1004 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) { | 1006 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) { |
1005 error(node, WarningKind.TYPE_VARIABLE_AS_CONSTRUCTOR); | 1007 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR); |
1006 return null; | 1008 return null; |
1007 } else { | 1009 } else { |
1008 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | 1010 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); |
| 1011 return null; |
1009 } | 1012 } |
1010 } | 1013 } |
1011 return constructor; | 1014 return constructor; |
1012 } | 1015 } |
1013 | 1016 |
1014 Element resolveTypeRequired(Node node) { | 1017 Type resolveTypeRequired(TypeAnnotation node) { |
1015 bool old = typeRequired; | 1018 bool old = typeRequired; |
1016 typeRequired = true; | 1019 typeRequired = true; |
1017 Element element = visit(node); | 1020 Type result = resolveTypeAnnotation(node); |
1018 typeRequired = old; | 1021 typeRequired = old; |
1019 return element; | 1022 return result; |
| 1023 } |
| 1024 |
| 1025 Element resolveTypeName(node) { |
| 1026 Identifier typeName = node.typeName.asIdentifier(); |
| 1027 Send send = node.typeName.asSend(); |
| 1028 if (send !== null) { |
| 1029 typeName = send.selector; |
| 1030 } |
| 1031 if (typeName.source == Types.VOID) return compiler.types.voidType.element; |
| 1032 if (typeName.source == Types.DYNAMIC || |
| 1033 typeName.source.stringValue == "var") { |
| 1034 return compiler.types.dynamicType.element; |
| 1035 } |
| 1036 if (send !== null) { |
| 1037 Element e = context.lookup(send.receiver.asIdentifier().source); |
| 1038 if (e !== null && e.kind === ElementKind.PREFIX) { |
| 1039 // The receiver is a prefix. Lookup in the imported members. |
| 1040 PrefixElement prefix = e; |
| 1041 return prefix.lookupLocalMember(typeName.source); |
| 1042 } else if (e !== null && e.kind === ElementKind.CLASS) { |
| 1043 // The receiver is the class part of a named constructor. |
| 1044 return e; |
| 1045 } else { |
| 1046 error(send.receiver, MessageKind.CANNOT_RESOLVE); |
| 1047 } |
| 1048 } else { |
| 1049 return context.lookup(typeName.source); |
| 1050 } |
| 1051 } |
| 1052 |
| 1053 Type resolveTypeAnnotation(TypeAnnotation node) { |
| 1054 Element element = resolveTypeName(node); |
| 1055 Type type; |
| 1056 if (element === null) { |
| 1057 if (typeRequired) { |
| 1058 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); |
| 1059 } else { |
| 1060 warning(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); |
| 1061 } |
| 1062 } else if (!element.impliesType()) { |
| 1063 if (typeRequired) { |
| 1064 error(node, MessageKind.NOT_A_TYPE, [node.typeName]); |
| 1065 } else { |
| 1066 warning(node, MessageKind.NOT_A_TYPE, [node.typeName]); |
| 1067 } |
| 1068 } else { |
| 1069 if (element == compiler.types.voidType.element) { |
| 1070 type = compiler.types.voidType; |
| 1071 } else if (element == compiler.types.dynamicType.element) { |
| 1072 type = compiler.types.dynamicType; |
| 1073 } else if (element.isClass()) { |
| 1074 // TODO(ngeoffray): Should we also resolve typedef? |
| 1075 ClassElement cls = element; |
| 1076 compiler.resolver.toResolve.add(cls); |
| 1077 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); |
| 1078 if (node.typeArguments !== null) { |
| 1079 for (Link<Node> typeArguments = node.typeArguments.nodes; |
| 1080 !typeArguments.isEmpty(); |
| 1081 typeArguments = typeArguments.tail) { |
| 1082 arguments.addLast(resolveTypeAnnotation(typeArguments.head)); |
| 1083 } |
| 1084 } |
| 1085 type = new InterfaceType(element.name, element, arguments.toLink()); |
| 1086 } else if (element.isTypedef()) { |
| 1087 // TODO(karlklose): implement typedefs. We return a fake type that the |
| 1088 // code generator can use to detect typedefs in is-checks. |
| 1089 type = new SimpleType(element.name, element); |
| 1090 } else { |
| 1091 type = element.computeType(compiler); |
| 1092 } |
| 1093 } |
| 1094 return useType(node, type); |
1020 } | 1095 } |
1021 | 1096 |
1022 visitModifiers(Modifiers node) { | 1097 visitModifiers(Modifiers node) { |
1023 // TODO(ngeoffray): Implement this. | 1098 // TODO(ngeoffray): Implement this. |
1024 unimplemented(node, 'modifiers'); | 1099 unimplemented(node, 'modifiers'); |
1025 } | 1100 } |
1026 | 1101 |
1027 visitLiteralList(LiteralList node) { | 1102 visitLiteralList(LiteralList node) { |
1028 visit(node.elements); | 1103 visit(node.elements); |
1029 } | 1104 } |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 | 1710 |
1636 // TODO(ahe): This is temporary. | 1711 // TODO(ahe): This is temporary. |
1637 void resolveExpression(Node node) { | 1712 void resolveExpression(Node node) { |
1638 if (node == null) return; | 1713 if (node == null) return; |
1639 node.accept(new ResolverVisitor(compiler, enclosingElement)); | 1714 node.accept(new ResolverVisitor(compiler, enclosingElement)); |
1640 } | 1715 } |
1641 | 1716 |
1642 // TODO(ahe): This is temporary. | 1717 // TODO(ahe): This is temporary. |
1643 void resolveType(Node node) { | 1718 void resolveType(Node node) { |
1644 if (node == null) return; | 1719 if (node == null) return; |
1645 node.accept(new ResolverVisitor(compiler, enclosingElement)); | 1720 // Find the correct member context to perform the lookup in. |
| 1721 Element outer = enclosingElement; |
| 1722 Element context = outer; |
| 1723 while (outer !== null) { |
| 1724 if (outer.isMember()) { |
| 1725 context = outer; |
| 1726 break; |
| 1727 } |
| 1728 outer = outer.enclosingElement; |
| 1729 } |
| 1730 node.accept(new ResolverVisitor(compiler, context)); |
1646 } | 1731 } |
1647 | 1732 |
1648 // TODO(ahe): This is temporary. | 1733 // TODO(ahe): This is temporary. |
1649 ClassElement get currentClass() { | 1734 ClassElement get currentClass() { |
1650 return enclosingElement.isMember() | 1735 return enclosingElement.isMember() |
1651 ? enclosingElement.enclosingElement : null; | 1736 ? enclosingElement.enclosingElement : null; |
1652 } | 1737 } |
1653 } | 1738 } |
1654 | 1739 |
1655 class ConstructorResolver extends CommonResolverVisitor<Element> { | 1740 class ConstructorResolver extends CommonResolverVisitor<Element> { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1802 | 1887 |
1803 TopScope(LibraryElement library) : super(null, library); | 1888 TopScope(LibraryElement library) : super(null, library); |
1804 Element lookup(SourceString name) { | 1889 Element lookup(SourceString name) { |
1805 return library.find(name); | 1890 return library.find(name); |
1806 } | 1891 } |
1807 | 1892 |
1808 Element add(Element element) { | 1893 Element add(Element element) { |
1809 throw "Cannot add an element in the top scope"; | 1894 throw "Cannot add an element in the top scope"; |
1810 } | 1895 } |
1811 } | 1896 } |
OLD | NEW |