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