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 getConstructorSelector(Send node, SourceString className, ResolverVis itor visitor) { |
|
kasperl
2012/10/15 12:14:12
Long line.
aam-me
2012/10/16 04:09:32
Done.
| |
| 93 return node.selector.asIdentifier().source; | 93 SourceString constructorName; |
| 94 if (!isNamedConstructor(node)) { | |
| 95 constructorName = const SourceString(""); | |
|
kasperl
2012/10/15 12:14:12
Why don't you just return the selector here? It fe
aam-me
2012/10/16 04:09:32
Done.
| |
| 96 } else { | |
| 97 constructorName = node.selector.asIdentifier().source; | |
| 98 if (constructorName.slowToString() == className.slowToString()) { | |
|
kasperl
2012/10/15 12:14:12
Add a comment that explains when this happens? Thi
aam-me
2012/10/16 04:09:32
You are right, Kasper. The code above is wrong. It
| |
| 99 constructorName = const SourceString(""); | |
| 100 } | |
| 101 } | |
| 102 Selector selector; | |
|
kasperl
2012/10/15 12:14:12
I would get rid of this part and just put the retu
aam-me
2012/10/16 04:09:32
Done.
| |
| 103 if (constructorName != const SourceString("")) { | |
| 104 selector = new Selector.callConstructor( | |
| 105 constructorName, | |
| 106 visitor.enclosingElement.getLibrary()); | |
| 107 } else { | |
| 108 selector = new Selector.callDefaultConstructor( | |
| 109 visitor.enclosingElement.getLibrary()); | |
| 110 } | |
| 111 return selector; | |
| 94 } | 112 } |
| 95 | 113 |
| 96 String constructorNameForDiagnostics(SourceString className, | 114 String constructorNameForDiagnostics(SourceString className, |
| 97 SourceString constructorName) { | 115 SourceString constructorName) { |
|
kasperl
2012/10/15 12:14:12
Weird indentation.
aam-me
2012/10/16 04:09:32
Done.
| |
| 98 String classNameString = className.slowToString(); | 116 String classNameString = className.slowToString(); |
| 99 String constructorNameString = constructorName.slowToString(); | 117 String constructorNameString = constructorName.slowToString(); |
| 100 return (constructorName === const SourceString('')) | 118 return (constructorName === const SourceString('')) |
| 101 ? classNameString | 119 ? classNameString |
| 102 : "$classNameString.$constructorNameString"; | 120 : "$classNameString.$constructorNameString"; |
| 103 } | 121 } |
| 104 | 122 |
| 105 FunctionElement resolveConstructorRedirection(InitializerResolver resolver, | 123 FunctionElement resolveConstructorRedirection(InitializerResolver resolver, |
| 106 FunctionElement constructor) { | 124 FunctionElement constructor) { |
| 107 if (constructor.isPatched) { | 125 if (constructor.isPatched) { |
| 108 checkMatchingPatchSignatures(constructor, constructor.patch); | 126 checkMatchingPatchSignatures(constructor, constructor.patch); |
| 109 constructor = constructor.patch; | 127 constructor = constructor.patch; |
| 110 } | 128 } |
| 111 FunctionExpression node = constructor.parseNode(compiler); | 129 FunctionExpression node = constructor.parseNode(compiler); |
| 112 | 130 |
| 113 // A synthetic constructor does not have a node. | 131 // A synthetic constructor does not have a node. |
| 114 if (node === null) return null; | 132 if (node === null) return null; |
| 115 if (node.initializers === null) return null; | 133 if (node.initializers === null) return null; |
| 116 Link<Node> initializers = node.initializers.nodes; | 134 Link<Node> initializers = node.initializers.nodes; |
| 117 if (!initializers.isEmpty() && | 135 if (!initializers.isEmpty() && |
| 118 Initializers.isConstructorRedirect(initializers.head)) { | 136 Initializers.isConstructorRedirect(initializers.head)) { |
| 119 final ClassElement classElement = constructor.getEnclosingClass(); | 137 final ClassElement classElement = constructor.getEnclosingClass(); |
| 120 Selector selector; | 138 Selector selector = getConstructorSelector(initializers.head, |
| 121 if (isNamedConstructor(initializers.head)) { | 139 classElement.name, |
| 122 SourceString constructorName = getConstructorName(initializers.head); | 140 resolver.visitor); |
| 123 selector = new Selector.callConstructor( | |
| 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); | 141 return classElement.lookupConstructor(selector); |
| 131 } | 142 } |
| 132 return null; | 143 return null; |
| 133 } | 144 } |
| 134 | 145 |
| 135 void resolveRedirectingConstructor(InitializerResolver resolver, | 146 void resolveRedirectingConstructor(InitializerResolver resolver, |
| 136 Node node, | 147 Node node, |
| 137 FunctionElement constructor, | 148 FunctionElement constructor, |
| 138 FunctionElement redirection) { | 149 FunctionElement redirection) { |
| 139 Set<FunctionElement> seen = new Set<FunctionElement>(); | 150 Set<FunctionElement> seen = new Set<FunctionElement>(); |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 visitor.resolveArguments(call.argumentsNode); | 749 visitor.resolveArguments(call.argumentsNode); |
| 739 }); | 750 }); |
| 740 Selector selector = visitor.mapping.getSelector(call); | 751 Selector selector = visitor.mapping.getSelector(call); |
| 741 bool isSuperCall = Initializers.isSuperConstructorCall(call); | 752 bool isSuperCall = Initializers.isSuperConstructorCall(call); |
| 742 | 753 |
| 743 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, | 754 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, |
| 744 isSuperCall, | 755 isSuperCall, |
| 745 call); | 756 call); |
| 746 final SourceString className = lookupTarget.name; | 757 final SourceString className = lookupTarget.name; |
| 747 | 758 |
| 748 SourceString constructorName; | 759 Selector constructorSelector = |
| 749 Selector lookupSelector; | 760 resolver.getConstructorSelector(call, className, visitor); |
| 750 if (resolver.isNamedConstructor(call)) { | 761 FunctionElement calledConstructor = |
| 751 constructorName = resolver.getConstructorName(call); | 762 lookupTarget.lookupConstructor(constructorSelector); |
| 752 lookupSelector = new Selector.callConstructor( | |
| 753 constructorName, | |
| 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 | 763 |
| 764 final bool isImplicitSuperCall = false; | 764 final bool isImplicitSuperCall = false; |
| 765 verifyThatConstructorMatchesCall(lookedupConstructor, | 765 verifyThatConstructorMatchesCall(calledConstructor, |
| 766 selector, | 766 selector, |
| 767 isImplicitSuperCall, | 767 isImplicitSuperCall, |
| 768 call, | 768 call, |
| 769 constructorName, | 769 className, |
| 770 className); | 770 constructorSelector); |
| 771 | 771 |
| 772 visitor.useElement(call, lookedupConstructor); | 772 visitor.useElement(call, calledConstructor); |
| 773 visitor.world.registerStaticUse(lookedupConstructor); | 773 visitor.world.registerStaticUse(calledConstructor); |
| 774 return lookedupConstructor; | 774 return calledConstructor; |
| 775 } | 775 } |
| 776 | 776 |
| 777 void resolveImplicitSuperConstructorSend(FunctionElement constructor, | 777 void resolveImplicitSuperConstructorSend(FunctionElement constructor, |
| 778 FunctionExpression functionNode) { | 778 FunctionExpression functionNode) { |
| 779 // If the class has a super resolve the implicit super call. | 779 // If the class has a super resolve the implicit super call. |
| 780 ClassElement classElement = constructor.getEnclosingClass(); | 780 ClassElement classElement = constructor.getEnclosingClass(); |
| 781 ClassElement superClass = classElement.superclass; | 781 ClassElement superClass = classElement.superclass; |
| 782 if (classElement != visitor.compiler.objectClass) { | 782 if (classElement != visitor.compiler.objectClass) { |
| 783 assert(superClass !== null); | 783 assert(superClass !== null); |
| 784 assert(superClass.resolutionState == STATE_DONE); | 784 assert(superClass.resolutionState == STATE_DONE); |
| 785 SourceString constructorName = const SourceString(''); | 785 SourceString constructorName = const SourceString(''); |
| 786 Selector callToMatch = new Selector.call( | 786 Selector callToMatch = new Selector.call( |
| 787 constructorName, | 787 constructorName, |
| 788 classElement.getLibrary(), | 788 classElement.getLibrary(), |
| 789 0); | 789 0); |
| 790 | 790 |
| 791 final bool isSuperCall = true; | 791 final bool isSuperCall = true; |
| 792 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, | 792 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, |
| 793 isSuperCall, | 793 isSuperCall, |
| 794 functionNode); | 794 functionNode); |
| 795 Selector constructorSelector = new Selector.callDefaultConstructor( | |
| 796 visitor.enclosingElement.getLibrary()); | |
| 797 Element calledConstructor = lookupTarget.lookupConstructor( | |
| 798 constructorSelector); | |
| 799 | |
| 795 final SourceString className = lookupTarget.name; | 800 final SourceString className = lookupTarget.name; |
| 796 Element calledConstructor = lookupTarget.lookupConstructor( | |
| 797 new Selector.callDefaultConstructor( | |
| 798 visitor.enclosingElement.getLibrary())); | |
| 799 | |
| 800 final bool isImplicitSuperCall = true; | 801 final bool isImplicitSuperCall = true; |
| 801 verifyThatConstructorMatchesCall(calledConstructor, | 802 verifyThatConstructorMatchesCall(calledConstructor, |
| 802 callToMatch, | 803 callToMatch, |
| 803 isImplicitSuperCall, | 804 isImplicitSuperCall, |
| 804 functionNode, | 805 functionNode, |
| 805 className, | 806 className, |
| 806 const SourceString('')); | 807 constructorSelector); |
| 807 | 808 |
| 808 visitor.world.registerStaticUse(calledConstructor); | 809 visitor.world.registerStaticUse(calledConstructor); |
| 809 } | 810 } |
| 810 } | 811 } |
| 811 | 812 |
| 812 void verifyThatConstructorMatchesCall( | 813 void verifyThatConstructorMatchesCall( |
| 813 FunctionElement lookedupConstructor, | 814 FunctionElement lookedupConstructor, |
| 814 Selector call, | 815 Selector call, |
| 815 bool isImplicitSuperCall, | 816 bool isImplicitSuperCall, |
| 816 Node diagnosticNode, | 817 Node diagnosticNode, |
| 817 SourceString className, | 818 SourceString className, |
| 818 SourceString constructorName) { | 819 Selector constructorSelector) { |
| 819 if (lookedupConstructor === null | 820 if (lookedupConstructor === null |
| 820 || !lookedupConstructor.isGenerativeConstructor()) { | 821 || !lookedupConstructor.isGenerativeConstructor()) { |
| 821 var fullConstructorName = | 822 var fullConstructorName = |
| 822 visitor.compiler.resolver.constructorNameForDiagnostics(className, | 823 visitor.compiler.resolver.constructorNameForDiagnostics( |
| 823 constructorName); | 824 className, |
| 825 constructorSelector.name); | |
| 824 MessageKind kind = isImplicitSuperCall | 826 MessageKind kind = isImplicitSuperCall |
| 825 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT | 827 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT |
| 826 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; | 828 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; |
| 827 error(diagnosticNode, kind, [fullConstructorName]); | 829 error(diagnosticNode, kind, [fullConstructorName]); |
| 828 } else { | 830 } else { |
| 829 if (!call.applies(lookedupConstructor, visitor.compiler)) { | 831 if (!call.applies(lookedupConstructor, visitor.compiler)) { |
| 830 MessageKind kind = isImplicitSuperCall | 832 MessageKind kind = isImplicitSuperCall |
| 831 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT | 833 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT |
| 832 : MessageKind.NO_MATCHING_CONSTRUCTOR; | 834 : MessageKind.NO_MATCHING_CONSTRUCTOR; |
| 833 error(diagnosticNode, kind); | 835 error(diagnosticNode, kind); |
| (...skipping 2393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3227 return result; | 3229 return result; |
| 3228 } | 3230 } |
| 3229 Element lookup(SourceString name) => localLookup(name); | 3231 Element lookup(SourceString name) => localLookup(name); |
| 3230 Element lexicalLookup(SourceString name) => localLookup(name); | 3232 Element lexicalLookup(SourceString name) => localLookup(name); |
| 3231 | 3233 |
| 3232 Element add(Element newElement) { | 3234 Element add(Element newElement) { |
| 3233 throw "Cannot add an element in a patch library scope"; | 3235 throw "Cannot add an element in a patch library scope"; |
| 3234 } | 3236 } |
| 3235 String toString() => 'PatchLibraryScope($origin,$patch)'; | 3237 String toString() => 'PatchLibraryScope($origin,$patch)'; |
| 3236 } | 3238 } |
| OLD | NEW |