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

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

Issue 11140018: Ensure that ClassElement.lookupConstructor fails when looking up default constructor using Selector… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed redirecting constructor lookup logic. Created 8 years, 2 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 | « lib/compiler/implementation/elements/elements.dart ('k') | tests/co19/co19-dart2dart.status » ('j') | 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 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
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
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
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 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/elements/elements.dart ('k') | tests/co19/co19-dart2dart.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698