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 Type getType(TypeAnnotation annotation); |
9 } | 9 } |
10 | 10 |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
584 nestingLevel++; | 584 nestingLevel++; |
585 } | 585 } |
586 | 586 |
587 void exitSwitch() { | 587 void exitSwitch() { |
588 nestingLevel--; | 588 nestingLevel--; |
589 breakTargetStack = breakTargetStack.tail; | 589 breakTargetStack = breakTargetStack.tail; |
590 labels = labels.outer; | 590 labels = labels.outer; |
591 } | 591 } |
592 } | 592 } |
593 | 593 |
594 class TypeResolver { | |
595 final Compiler compiler; | |
596 TypeResolver(this.compiler); | |
597 | |
598 Element resolveTypeName(Scope context, TypeAnnotation node) { | |
599 Identifier typeName = node.typeName.asIdentifier(); | |
600 Send send = node.typeName.asSend(); | |
601 if (send !== null) { | |
602 typeName = send.selector; | |
603 } | |
604 if (typeName.source == Types.VOID) { | |
605 return compiler.types.voidType.element; | |
606 } else if (send !== null) { | |
607 Element e = context.lookup(send.receiver.asIdentifier().source); | |
608 if (e !== null && e.kind === ElementKind.PREFIX) { | |
609 // The receiver is a prefix. Lookup in the imported members. | |
610 PrefixElement prefix = e; | |
611 return prefix.lookupLocalMember(typeName.source); | |
612 } else if (e !== null && e.kind === ElementKind.CLASS) { | |
613 // The receiver is the class part of a named constructor. | |
614 return e; | |
615 } else { | |
616 return null; | |
617 } | |
618 } else { | |
619 return context.lookup(typeName.source); | |
620 } | |
621 } | |
622 | |
623 Type resolveTypeAnnotation(TypeAnnotation node, | |
624 [Scope inContext, ClassElement inClass, | |
625 onFailure(Node, MessageKind, [List arguments]), | |
626 whenResolved(Node, Type)]) { | |
627 if (onFailure === null) { | |
628 onFailure = (n, k, [arguments]) => {}; | |
ngeoffray
2012/06/06 11:12:26
Returns a map? :-)
karlklose
2012/06/06 11:43:37
Done.
| |
629 } | |
630 if (whenResolved === null) { | |
631 whenResolved = (n, t) => {}; | |
ngeoffray
2012/06/06 11:12:26
ditto
karlklose
2012/06/06 11:43:37
Done.
| |
632 } | |
633 if (inClass !== null) { | |
634 inContext = new ClassScope(inClass, inClass.getLibrary()); | |
635 } | |
636 if (inContext === null) { | |
637 compiler.internalError('resolveTypeAnnotation: no scope specified'); | |
638 } | |
639 return resolveTypeAnnotationInContext(inContext, node, onFailure, | |
640 whenResolved); | |
641 } | |
642 | |
643 Type resolveTypeAnnotationInContext(Scope context, TypeAnnotation node, | |
644 onFailure, whenResolved) { | |
645 Element element = resolveTypeName(context, node); | |
646 Type type; | |
647 if (element === null) { | |
648 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | |
649 } else if (!element.impliesType()) { | |
650 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); | |
651 } else { | |
652 if (element === compiler.types.voidType.element || | |
653 element === compiler.types.dynamicType.element) { | |
654 type = element.computeType(compiler); | |
655 } else if (element.isClass()) { | |
656 ClassElement cls = element; | |
657 if (!cls.isResolved) compiler.resolveClass(cls); | |
658 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); | |
659 if (node.typeArguments !== null) { | |
660 int index = 0; | |
661 for (Link<Node> typeArguments = node.typeArguments.nodes; | |
662 !typeArguments.isEmpty(); | |
663 typeArguments = typeArguments.tail) { | |
664 if (++index > cls.typeParameters.length) { | |
665 onFailure(typeArguments.head, | |
666 MessageKind.ADDITIONAL_TYPE_ARGUMENT); | |
667 } | |
668 Type argType = resolveTypeAnnotationInContext(context, | |
669 typeArguments.head, | |
670 onFailure, | |
671 whenResolved); | |
672 arguments.addLast(argType); | |
673 } | |
674 if (index < cls.typeParameters.length) { | |
675 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | |
676 } | |
677 } | |
678 if (cls.typeParameters.length == 0) { | |
679 // Return the canonical type if it has no type parameters. | |
680 type = cls.computeType(compiler); | |
681 } else { | |
682 type = new InterfaceType(cls, arguments.toLink()); | |
683 } | |
684 } else if (element.isTypedef()) { | |
685 type = element.computeType(compiler); | |
686 } else if (element.isTypeVariable()) { | |
687 type = element.computeType(compiler); | |
688 } else { | |
689 compiler.cancel("unexpected element kind ${element.kind}", | |
690 node: node); | |
691 } | |
692 } | |
693 whenResolved(node, type); | |
694 return type; | |
695 } | |
696 } | |
697 | |
594 class ResolverVisitor extends CommonResolverVisitor<Element> { | 698 class ResolverVisitor extends CommonResolverVisitor<Element> { |
595 final TreeElementMapping mapping; | 699 final TreeElementMapping mapping; |
596 final Element enclosingElement; | 700 final Element enclosingElement; |
701 final TypeResolver typeResolver; | |
597 bool inInstanceContext; | 702 bool inInstanceContext; |
598 Scope context; | 703 Scope context; |
599 ClassElement currentClass; | 704 ClassElement currentClass; |
600 bool typeRequired = false; | 705 bool typeRequired = false; |
601 StatementScope statementScope; | 706 StatementScope statementScope; |
602 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; | 707 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; |
603 | 708 |
604 ResolverVisitor(Compiler compiler, Element element) | 709 ResolverVisitor(Compiler compiler, Element element) |
605 : this.mapping = new TreeElementMapping(), | 710 : this.mapping = new TreeElementMapping(), |
606 this.enclosingElement = element, | 711 this.enclosingElement = element, |
607 inInstanceContext = element.isInstanceMember() | 712 inInstanceContext = element.isInstanceMember() |
608 || element.isGenerativeConstructor(), | 713 || element.isGenerativeConstructor(), |
609 this.currentClass = element.isMember() ? element.enclosingElement : null, | 714 this.currentClass = element.isMember() ? element.enclosingElement : null, |
610 this.statementScope = new StatementScope(), | 715 this.statementScope = new StatementScope(), |
716 typeResolver = new TypeResolver(compiler), | |
611 super(compiler) { | 717 super(compiler) { |
612 LibraryElement library = element.getLibrary(); | 718 LibraryElement library = element.getLibrary(); |
613 element = element.getEnclosingMember(); | 719 element = element.getEnclosingMember(); |
614 if (element !== null) { | 720 if (element !== null) { |
615 context = new ClassScope(element.enclosingElement, library); | 721 context = new ClassScope(element.enclosingElement, library); |
616 } else { | 722 } else { |
617 this.context = new TopScope(library); | 723 this.context = new TopScope(library); |
618 } | 724 } |
619 } | 725 } |
620 | 726 |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1089 } | 1195 } |
1090 | 1196 |
1091 Type resolveTypeRequired(TypeAnnotation node) { | 1197 Type resolveTypeRequired(TypeAnnotation node) { |
1092 bool old = typeRequired; | 1198 bool old = typeRequired; |
1093 typeRequired = true; | 1199 typeRequired = true; |
1094 Type result = resolveTypeAnnotation(node); | 1200 Type result = resolveTypeAnnotation(node); |
1095 typeRequired = old; | 1201 typeRequired = old; |
1096 return result; | 1202 return result; |
1097 } | 1203 } |
1098 | 1204 |
1099 Element resolveTypeName(TypeAnnotation node) { | |
1100 Identifier typeName = node.typeName.asIdentifier(); | |
1101 Send send = node.typeName.asSend(); | |
1102 if (send !== null) { | |
1103 typeName = send.selector; | |
1104 } | |
1105 if (typeName.source == Types.VOID) { | |
1106 return compiler.types.voidType.element; | |
1107 } else if (send !== null) { | |
1108 Element e = context.lookup(send.receiver.asIdentifier().source); | |
1109 if (e !== null && e.kind === ElementKind.PREFIX) { | |
1110 // The receiver is a prefix. Lookup in the imported members. | |
1111 PrefixElement prefix = e; | |
1112 return prefix.lookupLocalMember(typeName.source); | |
1113 } else if (e !== null && e.kind === ElementKind.CLASS) { | |
1114 // The receiver is the class part of a named constructor. | |
1115 return e; | |
1116 } else { | |
1117 return null; | |
1118 } | |
1119 } else { | |
1120 return context.lookup(typeName.source); | |
1121 } | |
1122 } | |
1123 | |
1124 Type resolveTypeAnnotation(TypeAnnotation node) { | 1205 Type resolveTypeAnnotation(TypeAnnotation node) { |
1125 Function report = typeRequired ? error : warning; | 1206 Function report = typeRequired ? error : warning; |
1126 Element element = resolveTypeName(node); | 1207 return typeResolver.resolveTypeAnnotation(node, inContext: context, |
1127 Type type; | 1208 onFailure: report, |
1128 if (element === null) { | 1209 whenResolved: useType); |
1129 report(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | |
1130 } else if (!element.impliesType()) { | |
1131 report(node, MessageKind.NOT_A_TYPE, [node.typeName]); | |
1132 } else { | |
1133 if (element === compiler.types.voidType.element || | |
1134 element === compiler.types.dynamicType.element) { | |
1135 type = element.computeType(compiler); | |
1136 } else if (element.isClass()) { | |
1137 ClassElement cls = element; | |
1138 if (!cls.isResolved) compiler.resolveClass(cls); | |
1139 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); | |
1140 if (node.typeArguments !== null) { | |
1141 int index = 0; | |
1142 for (Link<Node> typeArguments = node.typeArguments.nodes; | |
1143 !typeArguments.isEmpty(); | |
1144 typeArguments = typeArguments.tail) { | |
1145 if (++index > cls.typeParameters.length) { | |
1146 report(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | |
1147 } | |
1148 arguments.addLast(resolveTypeAnnotation(typeArguments.head)); | |
1149 } | |
1150 if (index < cls.typeParameters.length) { | |
1151 report(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | |
1152 } | |
1153 } | |
1154 if (cls.typeParameters.length == 0) { | |
1155 // Return the canonical type if it has no type parameters. | |
1156 type = cls.computeType(compiler); | |
1157 } else { | |
1158 type = new InterfaceType(cls, arguments.toLink()); | |
1159 } | |
1160 } else if (element.isTypedef()) { | |
1161 type = element.computeType(compiler); | |
1162 } else if (element.isTypeVariable()) { | |
1163 type = element.computeType(compiler); | |
1164 } else { | |
1165 compiler.cancel("unexpected element kind ${element.kind}", | |
1166 node: node); | |
1167 } | |
1168 } | |
1169 return useType(node, type); | |
1170 } | 1210 } |
1171 | 1211 |
1172 visitModifiers(Modifiers node) { | 1212 visitModifiers(Modifiers node) { |
1173 // TODO(ngeoffray): Implement this. | 1213 // TODO(ngeoffray): Implement this. |
1174 unimplemented(node, 'modifiers'); | 1214 unimplemented(node, 'modifiers'); |
1175 } | 1215 } |
1176 | 1216 |
1177 visitLiteralList(LiteralList node) { | 1217 visitLiteralList(LiteralList node) { |
1178 visit(node.elements); | 1218 visit(node.elements); |
1179 } | 1219 } |
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1964 | 2004 |
1965 TopScope(LibraryElement library) : super(null, library); | 2005 TopScope(LibraryElement library) : super(null, library); |
1966 Element lookup(SourceString name) { | 2006 Element lookup(SourceString name) { |
1967 return library.find(name); | 2007 return library.find(name); |
1968 } | 2008 } |
1969 | 2009 |
1970 Element add(Element newElement) { | 2010 Element add(Element newElement) { |
1971 throw "Cannot add an element in the top scope"; | 2011 throw "Cannot add an element in the top scope"; |
1972 } | 2012 } |
1973 } | 2013 } |
OLD | NEW |