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 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 return null; | 566 return null; |
567 } else { | 567 } else { |
568 Element element = lookup(node, node.source); | 568 Element element = lookup(node, node.source); |
569 if (element == null) { | 569 if (element == null) { |
570 error(node, MessageKind.CANNOT_RESOLVE, [node]); | 570 error(node, MessageKind.CANNOT_RESOLVE, [node]); |
571 } | 571 } |
572 return useElement(node, element); | 572 return useElement(node, element); |
573 } | 573 } |
574 } | 574 } |
575 | 575 |
576 visitTypeAnnotation(TypeAnnotation node) { | 576 ClassElement visitTypeAnnotation(TypeAnnotation node) { |
577 SourceString className; | 577 return resolveTypeAnnotation(node).element; |
578 if (node.typeName.asSend() !== null) { | |
579 // In new and const expressions, the type name can be a Send to | |
580 // denote named constructors or library prefixes. | |
581 Send send = node.typeName.asSend(); | |
582 className = send.receiver.asIdentifier().source; | |
583 } else { | |
584 className = node.typeName.asIdentifier().source; | |
585 } | |
586 if (className == const SourceString('var')) return null; | |
587 if (className == const SourceString('void')) return null; | |
588 Element element = context.lookup(className); | |
589 if (element === null) { | |
590 if (typeRequired) { | |
591 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [className]); | |
592 } else { | |
593 warning(node, MessageKind.CANNOT_RESOLVE_TYPE, [className]); | |
594 } | |
595 } else if (element.kind !== ElementKind.CLASS) { | |
596 if (typeRequired) { | |
597 error(node, MessageKind.NOT_A_TYPE, [className]); | |
598 } else { | |
599 warning(node, MessageKind.NOT_A_TYPE, [className]); | |
600 } | |
601 } else { | |
602 ClassElement cls = element; | |
603 compiler.resolver.toResolve.add(element); | |
604 // TODO(ahe): This should be a Type. | |
605 useElement(node, element); | |
606 } | |
607 return element; | |
608 } | 578 } |
609 | 579 |
610 Element defineElement(Node node, Element element, | 580 Element defineElement(Node node, Element element, |
611 [bool doAddToScope = true]) { | 581 [bool doAddToScope = true]) { |
612 compiler.ensure(element !== null); | 582 compiler.ensure(element !== null); |
613 mapping[node] = element; | 583 mapping[node] = element; |
614 if (doAddToScope) { | 584 if (doAddToScope) { |
615 Element existing = context.add(element); | 585 Element existing = context.add(element); |
616 if (existing != element) { | 586 if (existing != element) { |
617 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); | 587 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
769 target = prefix.library.lookupLocalMember(name); | 739 target = prefix.library.lookupLocalMember(name); |
770 if (target == null) { | 740 if (target == null) { |
771 error(node, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 741 error(node, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
772 [resolvedReceiver.name, name]); | 742 [resolvedReceiver.name, name]); |
773 } | 743 } |
774 } | 744 } |
775 } | 745 } |
776 return target; | 746 return target; |
777 } | 747 } |
778 | 748 |
779 resolveTypeTest(Node argument) { | |
780 TypeAnnotation node = argument.asTypeAnnotation(); | |
781 if (node == null) { | |
782 node = argument.asSend().receiver; | |
783 } | |
784 resolveTypeRequired(node); | |
785 } | |
786 | |
787 void handleArguments(Send node) { | 749 void handleArguments(Send node) { |
788 int count = 0; | 750 int count = 0; |
789 List<SourceString> namedArguments = <SourceString>[]; | 751 List<SourceString> namedArguments = <SourceString>[]; |
790 for (Link<Node> link = node.argumentsNode.nodes; | 752 for (Link<Node> link = node.argumentsNode.nodes; |
791 !link.isEmpty(); | 753 !link.isEmpty(); |
792 link = link.tail) { | 754 link = link.tail) { |
793 count++; | 755 count++; |
794 Expression argument = link.head; | 756 Expression argument = link.head; |
795 visit(argument); | 757 visit(argument); |
796 if (argument.asNamedArgument() != null) { | 758 if (argument.asNamedArgument() != null) { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 SourceString constructorName; | 909 SourceString constructorName; |
948 Node selector = node.send.selector; | 910 Node selector = node.send.selector; |
949 Node typeName = selector.asTypeAnnotation().typeName; | 911 Node typeName = selector.asTypeAnnotation().typeName; |
950 if (typeName.asSend() !== null) { | 912 if (typeName.asSend() !== null) { |
951 SourceString className = typeName.asSend().receiver.asIdentifier().source; | 913 SourceString className = typeName.asSend().receiver.asIdentifier().source; |
952 SourceString name = typeName.asSend().selector.asIdentifier().source; | 914 SourceString name = typeName.asSend().selector.asIdentifier().source; |
953 constructorName = Elements.constructConstructorName(className, name); | 915 constructorName = Elements.constructConstructorName(className, name); |
954 } else { | 916 } else { |
955 constructorName = typeName.asIdentifier().source; | 917 constructorName = typeName.asIdentifier().source; |
956 } | 918 } |
957 ClassElement cls = resolveTypeRequired(selector); | 919 ClassElement cls = resolveTypeRequired(selector).element; |
958 if (cls === null) { | 920 if (cls === null) { |
959 error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]); | 921 error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]); |
960 return null; | 922 return null; |
961 } | 923 } |
962 cls.resolve(compiler); | 924 cls.resolve(compiler); |
963 if (cls.isInterface() && (cls.defaultClass === null)) { | 925 if (cls.isInterface() && (cls.defaultClass === null)) { |
964 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | 926 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); |
965 } | 927 } |
966 FunctionElement constructor = cls.lookupConstructor(constructorName); | 928 FunctionElement constructor = cls.lookupConstructor(constructorName); |
967 if (constructor !== null) return constructor; | 929 if (constructor !== null) return constructor; |
968 if (constructorName == cls.name && node.send.argumentsNode.isEmpty()) { | 930 if (constructorName == cls.name && node.send.argumentsNode.isEmpty()) { |
969 return cls.getSynthesizedConstructor(); | 931 return cls.getSynthesizedConstructor(); |
970 } | 932 } |
971 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | 933 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); |
972 return null; | 934 return null; |
973 } | 935 } |
974 | 936 |
975 ClassElement resolveTypeRequired(Node node) { | 937 Type resolveTypeRequired(TypeAnnotation node) { |
976 bool old = typeRequired; | 938 bool old = typeRequired; |
977 typeRequired = true; | 939 typeRequired = true; |
978 ClassElement cls = visit(node); | 940 Type result = resolveTypeAnnotation(node); |
979 typeRequired = old; | 941 typeRequired = old; |
980 return cls; | 942 return result; |
943 } | |
944 | |
945 Type resolveTypeTest(Node argument) { | |
946 TypeAnnotation node = argument.asTypeAnnotation(); | |
947 if (node == null) { | |
ahe
2012/02/29 12:49:15
Add comment saying this is handling "x is !Foo".
karlklose
2012/03/30 11:56:40
Done.
| |
948 node = argument.asSend().receiver; | |
ahe
2012/02/29 12:49:15
node = argument.asSend().receiver.asTypeAnnotation
karlklose
2012/03/30 11:56:40
Done.
| |
949 } | |
950 return resolveTypeRequired(node); | |
951 } | |
952 | |
953 Type resolveTypeAnnotation(TypeAnnotation node) { | |
954 SourceString className; | |
955 if (node.typeName.asSend() !== null) { | |
ahe
2012/02/29 12:49:15
Please create a visitor.
karlklose
2012/03/30 11:56:40
I moved this code to a function.
| |
956 // In new and const expressions, the type name can be a Send to | |
957 // denote named constructors or library prefixes. | |
ahe
2012/02/29 12:49:15
Add:
// TODO(ahe): We assume it is a named constr
karlklose
2012/03/30 11:56:40
Obsolete.
| |
958 Send send = node.typeName.asSend(); | |
959 className = send.receiver.asIdentifier().source; | |
960 } else { | |
961 className = node.typeName.asIdentifier().source; | |
962 } | |
963 if (className == const SourceString('var') || | |
964 className == const SourceString('void')){ | |
ahe
2012/02/29 12:49:15
Move this if-test to right after line 961. In the
karlklose
2012/03/30 11:56:40
Done.
| |
965 return compiler.types.lookup(className); | |
966 } | |
967 Element element = context.lookup(className); | |
968 var report = typeRequired ? error : warning; | |
969 if (element === null) { | |
970 report(node, MessageKind.CANNOT_RESOLVE_TYPE, [className]); | |
971 } else if (element.kind !== ElementKind.CLASS) { | |
972 report(node, MessageKind.NOT_A_TYPE, [className]); | |
973 } else { | |
974 ClassElement cls = element; | |
975 // Register class of this type to be resolved and associate it with node. | |
ngeoffray
2012/02/24 13:36:15
the class ... with the node.
karlklose
2012/03/30 11:56:40
Comment removed.
| |
976 compiler.resolver.toResolve.add(cls); | |
977 useElement(node, cls); | |
978 // Resolve type arguments, if any. | |
979 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); | |
980 Link link = node.typeArguments != null ? node.typeArguments.nodes | |
ngeoffray
2012/02/24 13:36:15
Link<TypeAnnotation>
karlklose
2012/03/30 11:56:40
Done.
| |
981 : const EmptyLink(); | |
982 for (; !link.isEmpty(); link = link.tail) { | |
983 TypeAnnotation argumentAnnotation = link.head; | |
984 arguments.addLast(resolveTypeAnnotation(argumentAnnotation)); | |
985 } | |
ngeoffray
2012/02/24 13:36:15
Do you think you could write a full Dart test or a
karlklose
2012/03/30 11:56:40
I will add a test to the ResolverTest.
| |
986 // Construct and return resulting type. | |
987 return new InterfaceType(className, cls, arguments.toLink()); | |
988 } | |
989 return compiler.types.dynamicType; | |
981 } | 990 } |
982 | 991 |
983 visitModifiers(Modifiers node) { | 992 visitModifiers(Modifiers node) { |
984 // TODO(ngeoffray): Implement this. | 993 // TODO(ngeoffray): Implement this. |
985 unimplemented(node, 'modifiers'); | 994 unimplemented(node, 'modifiers'); |
986 } | 995 } |
987 | 996 |
988 visitLiteralList(LiteralList node) { | 997 visitLiteralList(LiteralList node) { |
989 if (node.isConst()) { | 998 if (node.isConst()) { |
990 warning(node, MessageKind.GENERIC, | 999 warning(node, MessageKind.GENERIC, |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1423 class TopScope extends Scope { | 1432 class TopScope extends Scope { |
1424 LibraryElement get library() => element; | 1433 LibraryElement get library() => element; |
1425 | 1434 |
1426 TopScope(LibraryElement library) : super(null, library); | 1435 TopScope(LibraryElement library) : super(null, library); |
1427 Element lookup(SourceString name) => library.find(name); | 1436 Element lookup(SourceString name) => library.find(name); |
1428 | 1437 |
1429 Element add(Element element) { | 1438 Element add(Element element) { |
1430 throw "Cannot add an element in the top scope"; | 1439 throw "Cannot add an element in the top scope"; |
1431 } | 1440 } |
1432 } | 1441 } |
OLD | NEW |