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

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

Issue 10386088: Add a TypeResolver to resolve type annotations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 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 | « no previous file | no next file » | 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 Type getType(TypeAnnotation annotation);
9 } 9 }
10 10
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698