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 abstract class TreeElements { | 5 abstract class TreeElements { |
| 6 Element operator[](Node node); | 6 Element operator[](Node node); |
| 7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
| 8 DartType getType(TypeAnnotation annotation); | 8 DartType getType(TypeAnnotation annotation); |
| 9 bool isParameterChecked(Element element); | 9 bool isParameterChecked(Element element); |
| 10 } | 10 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 return resolveParameter(element); | 82 return resolveParameter(element); |
| 83 } | 83 } |
| 84 | 84 |
| 85 compiler.unimplemented("resolve($element)", | 85 compiler.unimplemented("resolve($element)", |
| 86 node: element.parseNode(compiler)); | 86 node: element.parseNode(compiler)); |
| 87 }); | 87 }); |
| 88 } | 88 } |
| 89 | 89 |
| 90 bool isNamedConstructor(Send node) => node.receiver !== null; | 90 bool isNamedConstructor(Send node) => node.receiver !== null; |
| 91 | 91 |
| 92 SourceString getConstructorName(Send node) { | 92 Selector getRedirectingThisOrSuperConstructorSelector( |
| 93 return node.selector.asIdentifier().source; | 93 Send node, |
| 94 SourceString className, | |
|
kasperl
2012/10/16 05:24:02
Unused parameter.
aam-me
2012/10/16 12:07:49
Quite amazing! Done.
| |
| 95 ResolverVisitor visitor) { | |
| 96 if (!isNamedConstructor(node)) { | |
|
kasperl
2012/10/16 05:24:02
Maybe invert this condition (get rid of !) so the
aam-me
2012/10/16 12:07:49
Agree. Done.
| |
| 97 return new Selector.callDefaultConstructor( | |
| 98 visitor.enclosingElement.getLibrary()); | |
| 99 } else { | |
| 100 SourceString constructorName = node.selector.asIdentifier().source; | |
| 101 return new Selector.callConstructor( | |
| 102 constructorName, | |
| 103 visitor.enclosingElement.getLibrary()); | |
| 104 } | |
| 94 } | 105 } |
| 95 | 106 |
| 96 String constructorNameForDiagnostics(SourceString className, | 107 String constructorNameForDiagnostics(SourceString className, |
| 97 SourceString constructorName) { | 108 SourceString constructorName) { |
| 98 String classNameString = className.slowToString(); | 109 String classNameString = className.slowToString(); |
| 99 String constructorNameString = constructorName.slowToString(); | 110 String constructorNameString = constructorName.slowToString(); |
| 100 return (constructorName === const SourceString('')) | 111 return (constructorName === const SourceString('')) |
| 101 ? classNameString | 112 ? classNameString |
| 102 : "$classNameString.$constructorNameString"; | 113 : "$classNameString.$constructorNameString"; |
| 103 } | 114 } |
| 104 | 115 |
| 105 FunctionElement resolveConstructorRedirection(InitializerResolver resolver, | 116 FunctionElement resolveConstructorRedirection(InitializerResolver resolver, |
| 106 FunctionElement constructor) { | 117 FunctionElement constructor) { |
| 107 if (constructor.isPatched) { | 118 if (constructor.isPatched) { |
| 108 checkMatchingPatchSignatures(constructor, constructor.patch); | 119 checkMatchingPatchSignatures(constructor, constructor.patch); |
| 109 constructor = constructor.patch; | 120 constructor = constructor.patch; |
| 110 } | 121 } |
| 111 FunctionExpression node = constructor.parseNode(compiler); | 122 FunctionExpression node = constructor.parseNode(compiler); |
| 112 | 123 |
| 113 // A synthetic constructor does not have a node. | 124 // A synthetic constructor does not have a node. |
| 114 if (node === null) return null; | 125 if (node === null) return null; |
| 115 if (node.initializers === null) return null; | 126 if (node.initializers === null) return null; |
| 116 Link<Node> initializers = node.initializers.nodes; | 127 Link<Node> initializers = node.initializers.nodes; |
| 117 if (!initializers.isEmpty() && | 128 if (!initializers.isEmpty() && |
| 118 Initializers.isConstructorRedirect(initializers.head)) { | 129 Initializers.isConstructorRedirect(initializers.head)) { |
| 119 final ClassElement classElement = constructor.getEnclosingClass(); | 130 final ClassElement classElement = constructor.getEnclosingClass(); |
| 120 Selector selector; | 131 Selector selector = |
| 121 if (isNamedConstructor(initializers.head)) { | 132 getRedirectingThisOrSuperConstructorSelector(initializers.head, |
| 122 SourceString constructorName = getConstructorName(initializers.head); | 133 classElement.name, |
| 123 selector = new Selector.callConstructor( | 134 resolver.visitor); |
| 124 constructorName, | |
| 125 resolver.visitor.enclosingElement.getLibrary()); | |
| 126 } else { | |
| 127 selector = new Selector.callDefaultConstructor( | |
| 128 resolver.visitor.enclosingElement.getLibrary()); | |
| 129 } | |
| 130 return classElement.lookupConstructor(selector); | 135 return classElement.lookupConstructor(selector); |
| 131 } | 136 } |
| 132 return null; | 137 return null; |
| 133 } | 138 } |
| 134 | 139 |
| 135 void resolveRedirectingConstructor(InitializerResolver resolver, | 140 void resolveRedirectingConstructor(InitializerResolver resolver, |
| 136 Node node, | 141 Node node, |
| 137 FunctionElement constructor, | 142 FunctionElement constructor, |
| 138 FunctionElement redirection) { | 143 FunctionElement redirection) { |
| 139 Set<FunctionElement> seen = new Set<FunctionElement>(); | 144 Set<FunctionElement> seen = new Set<FunctionElement>(); |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 visitor.resolveArguments(call.argumentsNode); | 743 visitor.resolveArguments(call.argumentsNode); |
| 739 }); | 744 }); |
| 740 Selector selector = visitor.mapping.getSelector(call); | 745 Selector selector = visitor.mapping.getSelector(call); |
| 741 bool isSuperCall = Initializers.isSuperConstructorCall(call); | 746 bool isSuperCall = Initializers.isSuperConstructorCall(call); |
| 742 | 747 |
| 743 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, | 748 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, |
| 744 isSuperCall, | 749 isSuperCall, |
| 745 call); | 750 call); |
| 746 final SourceString className = lookupTarget.name; | 751 final SourceString className = lookupTarget.name; |
| 747 | 752 |
| 748 SourceString constructorName; | 753 Selector constructorSelector = |
| 749 Selector lookupSelector; | 754 resolver.getRedirectingThisOrSuperConstructorSelector(call, |
| 750 if (resolver.isNamedConstructor(call)) { | 755 className, |
| 751 constructorName = resolver.getConstructorName(call); | 756 visitor); |
| 752 lookupSelector = new Selector.callConstructor( | 757 FunctionElement calledConstructor = |
| 753 constructorName, | 758 lookupTarget.lookupConstructor(constructorSelector); |
| 754 visitor.enclosingElement.getLibrary()); | |
| 755 } else { | |
| 756 constructorName = const SourceString(''); | |
| 757 lookupSelector = new Selector.callDefaultConstructor( | |
| 758 visitor.enclosingElement.getLibrary()); | |
| 759 } | |
| 760 | |
| 761 FunctionElement lookedupConstructor = | |
| 762 lookupTarget.lookupConstructor(lookupSelector); | |
| 763 | 759 |
| 764 final bool isImplicitSuperCall = false; | 760 final bool isImplicitSuperCall = false; |
| 765 verifyThatConstructorMatchesCall(lookedupConstructor, | 761 verifyThatConstructorMatchesCall(calledConstructor, |
| 766 selector, | 762 selector, |
| 767 isImplicitSuperCall, | 763 isImplicitSuperCall, |
| 768 call, | 764 call, |
| 769 constructorName, | 765 className, |
| 770 className); | 766 constructorSelector); |
| 771 | 767 |
| 772 visitor.useElement(call, lookedupConstructor); | 768 visitor.useElement(call, calledConstructor); |
| 773 visitor.world.registerStaticUse(lookedupConstructor); | 769 visitor.world.registerStaticUse(calledConstructor); |
| 774 return lookedupConstructor; | 770 return calledConstructor; |
| 775 } | 771 } |
| 776 | 772 |
| 777 void resolveImplicitSuperConstructorSend(FunctionElement constructor, | 773 void resolveImplicitSuperConstructorSend(FunctionElement constructor, |
| 778 FunctionExpression functionNode) { | 774 FunctionExpression functionNode) { |
| 779 // If the class has a super resolve the implicit super call. | 775 // If the class has a super resolve the implicit super call. |
| 780 ClassElement classElement = constructor.getEnclosingClass(); | 776 ClassElement classElement = constructor.getEnclosingClass(); |
| 781 ClassElement superClass = classElement.superclass; | 777 ClassElement superClass = classElement.superclass; |
| 782 if (classElement != visitor.compiler.objectClass) { | 778 if (classElement != visitor.compiler.objectClass) { |
| 783 assert(superClass !== null); | 779 assert(superClass !== null); |
| 784 assert(superClass.resolutionState == STATE_DONE); | 780 assert(superClass.resolutionState == STATE_DONE); |
| 785 SourceString constructorName = const SourceString(''); | 781 SourceString constructorName = const SourceString(''); |
| 786 Selector callToMatch = new Selector.call( | 782 Selector callToMatch = new Selector.call( |
| 787 constructorName, | 783 constructorName, |
| 788 classElement.getLibrary(), | 784 classElement.getLibrary(), |
| 789 0); | 785 0); |
| 790 | 786 |
| 791 final bool isSuperCall = true; | 787 final bool isSuperCall = true; |
| 792 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, | 788 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, |
| 793 isSuperCall, | 789 isSuperCall, |
| 794 functionNode); | 790 functionNode); |
| 791 Selector constructorSelector = new Selector.callDefaultConstructor( | |
| 792 visitor.enclosingElement.getLibrary()); | |
| 793 Element calledConstructor = lookupTarget.lookupConstructor( | |
| 794 constructorSelector); | |
| 795 | |
| 795 final SourceString className = lookupTarget.name; | 796 final SourceString className = lookupTarget.name; |
| 796 Element calledConstructor = lookupTarget.lookupConstructor( | |
| 797 new Selector.callDefaultConstructor( | |
| 798 visitor.enclosingElement.getLibrary())); | |
| 799 | |
| 800 final bool isImplicitSuperCall = true; | 797 final bool isImplicitSuperCall = true; |
| 801 verifyThatConstructorMatchesCall(calledConstructor, | 798 verifyThatConstructorMatchesCall(calledConstructor, |
| 802 callToMatch, | 799 callToMatch, |
| 803 isImplicitSuperCall, | 800 isImplicitSuperCall, |
| 804 functionNode, | 801 functionNode, |
| 805 className, | 802 className, |
| 806 const SourceString('')); | 803 constructorSelector); |
| 807 | 804 |
| 808 visitor.world.registerStaticUse(calledConstructor); | 805 visitor.world.registerStaticUse(calledConstructor); |
| 809 } | 806 } |
| 810 } | 807 } |
| 811 | 808 |
| 812 void verifyThatConstructorMatchesCall( | 809 void verifyThatConstructorMatchesCall( |
| 813 FunctionElement lookedupConstructor, | 810 FunctionElement lookedupConstructor, |
| 814 Selector call, | 811 Selector call, |
| 815 bool isImplicitSuperCall, | 812 bool isImplicitSuperCall, |
| 816 Node diagnosticNode, | 813 Node diagnosticNode, |
| 817 SourceString className, | 814 SourceString className, |
| 818 SourceString constructorName) { | 815 Selector constructorSelector) { |
| 819 if (lookedupConstructor === null | 816 if (lookedupConstructor === null |
| 820 || !lookedupConstructor.isGenerativeConstructor()) { | 817 || !lookedupConstructor.isGenerativeConstructor()) { |
| 821 var fullConstructorName = | 818 var fullConstructorName = |
| 822 visitor.compiler.resolver.constructorNameForDiagnostics(className, | 819 visitor.compiler.resolver.constructorNameForDiagnostics( |
| 823 constructorName); | 820 className, |
| 821 constructorSelector.name); | |
| 824 MessageKind kind = isImplicitSuperCall | 822 MessageKind kind = isImplicitSuperCall |
| 825 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT | 823 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT |
| 826 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; | 824 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; |
| 827 error(diagnosticNode, kind, [fullConstructorName]); | 825 error(diagnosticNode, kind, [fullConstructorName]); |
| 828 } else { | 826 } else { |
| 829 if (!call.applies(lookedupConstructor, visitor.compiler)) { | 827 if (!call.applies(lookedupConstructor, visitor.compiler)) { |
| 830 MessageKind kind = isImplicitSuperCall | 828 MessageKind kind = isImplicitSuperCall |
| 831 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT | 829 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT |
| 832 : MessageKind.NO_MATCHING_CONSTRUCTOR; | 830 : MessageKind.NO_MATCHING_CONSTRUCTOR; |
| 833 error(diagnosticNode, kind); | 831 error(diagnosticNode, kind); |
| (...skipping 2393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3227 return result; | 3225 return result; |
| 3228 } | 3226 } |
| 3229 Element lookup(SourceString name) => localLookup(name); | 3227 Element lookup(SourceString name) => localLookup(name); |
| 3230 Element lexicalLookup(SourceString name) => localLookup(name); | 3228 Element lexicalLookup(SourceString name) => localLookup(name); |
| 3231 | 3229 |
| 3232 Element add(Element newElement) { | 3230 Element add(Element newElement) { |
| 3233 throw "Cannot add an element in a patch library scope"; | 3231 throw "Cannot add an element in a patch library scope"; |
| 3234 } | 3232 } |
| 3235 String toString() => 'PatchLibraryScope($origin,$patch)'; | 3233 String toString() => 'PatchLibraryScope($origin,$patch)'; |
| 3236 } | 3234 } |
| OLD | NEW |