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

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

Powered by Google App Engine
This is Rietveld 408576698