Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: lib/compiler/implementation/resolver.dart

Issue 10095014: Implement interface types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/compiler.dart ('k') | lib/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/compiler.dart ('k') | lib/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698