Chromium Code Reviews| 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 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 692 nestingLevel--; | 692 nestingLevel--; |
| 693 breakTargetStack = breakTargetStack.tail; | 693 breakTargetStack = breakTargetStack.tail; |
| 694 labels = labels.outer; | 694 labels = labels.outer; |
| 695 } | 695 } |
| 696 } | 696 } |
| 697 | 697 |
| 698 class TypeResolver { | 698 class TypeResolver { |
| 699 final Compiler compiler; | 699 final Compiler compiler; |
| 700 TypeResolver(this.compiler); | 700 TypeResolver(this.compiler); |
| 701 | 701 |
| 702 Element resolveTypeName(Scope context, TypeAnnotation node) { | 702 Element resolveTypeName(Scope context, Node typeNode) { |
| 703 Identifier typeName = node.typeName.asIdentifier(); | 703 Identifier typeName = typeNode.asIdentifier(); |
| 704 Send send = node.typeName.asSend(); | 704 Send send = typeNode.asSend(); |
| 705 if (send !== null) { | 705 if (send !== null) { |
| 706 typeName = send.selector; | 706 typeName = send.selector; |
| 707 } | 707 } |
| 708 if (typeName.source.stringValue === 'void') { | 708 if (typeName.source.stringValue === 'void') { |
| 709 return compiler.types.voidType.element; | 709 return compiler.types.voidType.element; |
| 710 } else if (send !== null) { | 710 } else if (send !== null) { |
| 711 Element e = context.lookup(send.receiver.asIdentifier().source); | 711 Element e = context.lookup(send.receiver.asIdentifier().source); |
| 712 if (e !== null && e.kind === ElementKind.PREFIX) { | 712 if (e !== null && e.kind === ElementKind.PREFIX) { |
| 713 // The receiver is a prefix. Lookup in the imported members. | 713 // The receiver is a prefix. Lookup in the imported members. |
| 714 PrefixElement prefix = e; | 714 PrefixElement prefix = e; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 737 if (inClass !== null) { | 737 if (inClass !== null) { |
| 738 inContext = new ClassScope(inClass, inClass.getLibrary()); | 738 inContext = new ClassScope(inClass, inClass.getLibrary()); |
| 739 } | 739 } |
| 740 if (inContext === null) { | 740 if (inContext === null) { |
| 741 compiler.internalError('resolveTypeAnnotation: no scope specified'); | 741 compiler.internalError('resolveTypeAnnotation: no scope specified'); |
| 742 } | 742 } |
| 743 return resolveTypeAnnotationInContext(inContext, node, onFailure, | 743 return resolveTypeAnnotationInContext(inContext, node, onFailure, |
| 744 whenResolved); | 744 whenResolved); |
| 745 } | 745 } |
| 746 | 746 |
| 747 Type resolveTypeVariableInContext(Scope context, TypeVariable node, | |
| 748 onFailure) { | |
| 749 Element element = resolveTypeName(context, node.name); | |
| 750 Type type; | |
| 751 if (element === null) { | |
| 752 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.name]); | |
| 753 } else if (!element.impliesType()) { | |
| 754 onFailure(node, MessageKind.NOT_A_TYPE, [node.name]); | |
| 755 } else if (element.isTypeVariable()) { | |
| 756 type = element.computeType(compiler); | |
|
ahe
2012/08/02 18:56:15
I cannot rule out that this won't lead to an infin
| |
| 757 } else { | |
| 758 compiler.cancel("unexpected element kind ${element.kind}", | |
| 759 node: node); | |
| 760 } | |
| 761 return type; | |
| 762 } | |
| 763 | |
| 747 Type resolveTypeAnnotationInContext(Scope context, TypeAnnotation node, | 764 Type resolveTypeAnnotationInContext(Scope context, TypeAnnotation node, |
| 748 onFailure, whenResolved) { | 765 onFailure, whenResolved) { |
| 749 Element element = resolveTypeName(context, node); | 766 Element element = resolveTypeName(context, node.typeName); |
| 750 Type type; | 767 Type type; |
| 751 if (element === null) { | 768 if (element === null) { |
| 752 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | 769 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); |
| 753 } else if (!element.impliesType()) { | 770 } else if (!element.impliesType()) { |
| 754 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); | 771 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); |
| 755 } else { | 772 } else { |
| 756 if (element === compiler.types.voidType.element || | 773 if (element === compiler.types.voidType.element || |
| 757 element === compiler.types.dynamicType.element) { | 774 element === compiler.types.dynamicType.element) { |
| 758 type = element.computeType(compiler); | 775 type = element.computeType(compiler); |
| 759 } else if (element.isClass()) { | 776 } else if (element.isClass()) { |
| 760 ClassElement cls = element; | 777 ClassElement cls = element; |
| 761 if (!cls.isResolved) compiler.resolveClass(cls); | 778 if (!cls.isResolved) compiler.resolveClass(cls); |
| 762 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); | 779 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); |
| 763 if (node.typeArguments !== null) { | 780 if (node.typeArguments !== null) { |
| 764 int index = 0; | 781 int index = 0; |
| 765 for (Link<Node> typeArguments = node.typeArguments.nodes; | 782 for (Link<Node> typeArguments = node.typeArguments.nodes; |
| 766 !typeArguments.isEmpty(); | 783 !typeArguments.isEmpty(); |
| 767 typeArguments = typeArguments.tail) { | 784 typeArguments = typeArguments.tail) { |
| 768 if (++index > cls.typeParameters.length) { | 785 if (++index > cls.typeParameters.length) { |
| 769 onFailure(typeArguments.head, | 786 onFailure(typeArguments.head, |
| 770 MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 787 MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
| 771 } | 788 } |
| 772 Type argType = resolveTypeAnnotationInContext(context, | 789 // TypeVariable may happen in default clause of an interface. |
|
ahe
2012/08/02 18:56:15
The original code is probably broken as well and m
|
ahe
2012/08/02 18:56:15
This is a hack. The problem is that the default cl
|
| 773 typeArguments.head, | 790 Type argType; |
| 774 onFailure, | 791 if (typeArguments.head is TypeVariable) { |
| 775 whenResolved); | 792 argType = resolveTypeVariableInContext( |
| 793 new ClassScope(cls, cls.getLibrary()), typeArguments.head, | |
| 794 onFailure); | |
| 795 } else { | |
| 796 argType = resolveTypeAnnotationInContext(context, | |
| 797 typeArguments.head, onFailure, whenResolved); | |
| 798 } | |
| 776 arguments.addLast(argType); | 799 arguments.addLast(argType); |
| 777 } | 800 } |
| 778 if (index < cls.typeParameters.length) { | 801 if (index < cls.typeParameters.length) { |
| 779 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | 802 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); |
| 780 } | 803 } |
| 781 } | 804 } |
| 782 if (cls.typeParameters.length == 0) { | 805 if (cls.typeParameters.length == 0) { |
| 783 // Return the canonical type if it has no type parameters. | 806 // Return the canonical type if it has no type parameters. |
| 784 type = cls.computeType(compiler); | 807 type = cls.computeType(compiler); |
| 785 } else { | 808 } else { |
| (...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2212 | 2235 |
| 2213 TopScope(LibraryElement library) : super(null, library); | 2236 TopScope(LibraryElement library) : super(null, library); |
| 2214 Element lookup(SourceString name) { | 2237 Element lookup(SourceString name) { |
| 2215 return library.find(name); | 2238 return library.find(name); |
| 2216 } | 2239 } |
| 2217 | 2240 |
| 2218 Element add(Element newElement) { | 2241 Element add(Element newElement) { |
| 2219 throw "Cannot add an element in the top scope"; | 2242 throw "Cannot add an element in the top scope"; |
| 2220 } | 2243 } |
| 2221 } | 2244 } |
| OLD | NEW |