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

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

Issue 10905305: Patch refactoring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 8 years, 3 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 11 matching lines...) Expand all
22 types = new LinkedHashMap<TypeAnnotation, DartType>(), 22 types = new LinkedHashMap<TypeAnnotation, DartType>(),
23 checkedParameters = new Set<Element>(); 23 checkedParameters = new Set<Element>();
24 24
25 operator []=(Node node, Element element) { 25 operator []=(Node node, Element element) {
26 assert(invariant(node, () { 26 assert(invariant(node, () {
27 if (node is FunctionExpression && node.modifiers != null) { 27 if (node is FunctionExpression && node.modifiers != null) {
28 return !node.modifiers.isExternal(); 28 return !node.modifiers.isExternal();
29 } 29 }
30 return true; 30 return true;
31 })); 31 }));
32 // TODO(johnniwinther): Simplify this invariant to use only declarations in
33 // [TreeElements].
32 assert(invariant(node, () { 34 assert(invariant(node, () {
33 if (!element.isErroneous() && currentElement != null && element.isPatch) { 35 if (!element.isErroneous() && currentElement != null && element.isPatch) {
34 return currentElement.getImplementationLibrary().isPatch; 36 return currentElement.getImplementationLibrary().isPatch;
35 } 37 }
36 return true; 38 return true;
37 })); 39 }));
38 40
39 map[node] = element; 41 map[node] = element;
40 } 42 }
41 operator [](Node node) => map[node]; 43 operator [](Node node) => map[node];
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 89
88 SourceString getConstructorName(Send node) { 90 SourceString getConstructorName(Send node) {
89 if (node.receiver !== null) { 91 if (node.receiver !== null) {
90 return node.selector.asIdentifier().source; 92 return node.selector.asIdentifier().source;
91 } else { 93 } else {
92 return const SourceString(''); 94 return const SourceString('');
93 } 95 }
94 } 96 }
95 97
96 FunctionElement resolveConstructorRedirection(FunctionElement constructor) { 98 FunctionElement resolveConstructorRedirection(FunctionElement constructor) {
99 if (constructor.isPatched){
100 checkMatchingSignatures(constructor, constructor.patch);
101 constructor = constructor.patch;
102 }
97 FunctionExpression node = constructor.parseNode(compiler); 103 FunctionExpression node = constructor.parseNode(compiler);
104
98 // A synthetic constructor does not have a node. 105 // A synthetic constructor does not have a node.
99 if (node === null) return null; 106 if (node === null) return null;
100 if (node.initializers === null) return null; 107 if (node.initializers === null) return null;
101 Link<Node> initializers = node.initializers.nodes; 108 Link<Node> initializers = node.initializers.nodes;
102 if (!initializers.isEmpty() && 109 if (!initializers.isEmpty() &&
103 Initializers.isConstructorRedirect(initializers.head)) { 110 Initializers.isConstructorRedirect(initializers.head)) {
104 final ClassElement classElement = constructor.getEnclosingClass(); 111 final ClassElement classElement = constructor.getEnclosingClass();
105 final SourceString constructorName = 112 final SourceString constructorName =
106 getConstructorName(initializers.head); 113 getConstructorName(initializers.head);
107 final SourceString className = classElement.name; 114 final SourceString className = classElement.name;
(...skipping 11 matching lines...) Expand all
119 while (redirection !== null) { 126 while (redirection !== null) {
120 if (seen.contains(redirection)) { 127 if (seen.contains(redirection)) {
121 resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); 128 resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
122 return; 129 return;
123 } 130 }
124 seen.add(redirection); 131 seen.add(redirection);
125 redirection = resolveConstructorRedirection(redirection); 132 redirection = resolveConstructorRedirection(redirection);
126 } 133 }
127 } 134 }
128 135
136 void checkMatchingParameters(FunctionElement origin,
ahe 2012/09/24 12:30:18 Use the word "patch" in method name.
Johnni Winther 2012/09/25 09:01:07 Done.
137 Link<Element> originParameters,
138 Link<Element> patchParameters) {
139 while (!originParameters.isEmpty()) {
140 Element originParameter = originParameters.head;
141 Element patchParameter = patchParameters.head;
142 String originParameterText =
143 originParameter.parseNode(compiler).toString();
144 String patchParameterText =
145 patchParameter.parseNode(compiler).toString();
146 if (originParameterText != patchParameterText) {
147 error(originParameter.parseNode(compiler),
148 MessageKind.PATCH_PARAMETER_MISMATCH,
149 [origin.name, originParameterText, patchParameterText]);
150 }
151
152 originParameters = originParameters.tail;
153 patchParameters = patchParameters.tail;
154 }
155 }
156
157 void checkMatchingSignatures(FunctionElement origin, FunctionElement patch) {
ahe 2012/09/24 12:30:18 Use the word "patch" in method name.
Johnni Winther 2012/09/25 09:01:07 Done.
158 // TODO(johnniwinther): Show both origin and patch locations on errors.
159 FunctionExpression originTree = compiler.withCurrentElement(origin, () {
160 return origin.parseNode(compiler);
161 });
162 FunctionSignature originSignature = compiler.withCurrentElement(origin, () {
163 return origin.computeSignature(compiler);
164 });
165 FunctionExpression patchTree = compiler.withCurrentElement(patch, () {
166 return patch.parseNode(compiler);
167 });
168 FunctionSignature patchSignature = compiler.withCurrentElement(patch, () {
169 return patch.computeSignature(compiler);
170 });
171
172 if (originSignature.returnType != patchSignature.returnType) {
173 Node errorNode =
174 originTree.returnType !== null ? originTree.returnType : originTree;
175 error(errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH,
176 [origin.name, originSignature.returnType, patchSignature.returnType]);
177 }
178 if (originSignature.requiredParameterCount !=
179 patchSignature.requiredParameterCount) {
180 error(originTree,
181 MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
182 [origin.name, originSignature.requiredParameterCount,
183 patchSignature.requiredParameterCount]);
184 } else {
185 checkMatchingParameters(origin,
186 originSignature.requiredParameters,
187 patchSignature.requiredParameters);
188 }
189 if (originSignature.optionalParameterCount !=
190 patchSignature.optionalParameterCount) {
191 error(originTree,
192 MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH,
193 [origin.name, originSignature.optionalParameterCount,
194 patchSignature.optionalParameterCount]);
195 } else {
196 checkMatchingParameters(origin,
197 originSignature.optionalParameters,
198 patchSignature.optionalParameters);
199 }
200 }
201
129 TreeElements resolveMethodElement(FunctionElement element) { 202 TreeElements resolveMethodElement(FunctionElement element) {
130 assert(invariant(element, element.isDeclaration)); 203 assert(invariant(element, element.isDeclaration));
131 return compiler.withCurrentElement(element, () { 204 return compiler.withCurrentElement(element, () {
132 bool isConstructor = element.kind === ElementKind.GENERATIVE_CONSTRUCTOR; 205 bool isConstructor = element.kind === ElementKind.GENERATIVE_CONSTRUCTOR;
133 TreeElements elements = 206 TreeElements elements =
134 compiler.enqueuer.resolution.getCachedElements(element); 207 compiler.enqueuer.resolution.getCachedElements(element);
135 if (elements !== null) { 208 if (elements !== null) {
136 assert(isConstructor); 209 assert(isConstructor);
137 return elements; 210 return elements;
138 } 211 }
139 FunctionExpression tree = element.parseNode(compiler); 212 if (element.isPatched) {
140 if (isConstructor) { 213 checkMatchingSignatures(element, element.patch);
141 if (tree.returnType !== null) { 214 element = element.patch;
142 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); 215 }
216 return compiler.withCurrentElement(element, () {
217 FunctionExpression tree = element.parseNode(compiler);
218
219 // TODO(johnniwinther): Check signature match.
ahe 2012/09/24 12:30:18 Stale TODO?
Johnni Winther 2012/09/25 09:01:07 Done.
220 if (isConstructor) {
221 if (tree.returnType !== null) {
222 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
223 }
224 resolveConstructorImplementation(element, tree);
143 } 225 }
144 resolveConstructorImplementation(element, tree); 226 ResolverVisitor visitor = new ResolverVisitor(compiler, element);
145 } 227 visitor.useElement(tree, element);
146 ResolverVisitor visitor = new ResolverVisitor(compiler, element); 228 visitor.setupFunction(tree, element);
147 visitor.useElement(tree, element);
148 visitor.setupFunction(tree, element);
149 229
150 if (isConstructor) { 230 if (isConstructor) {
151 // Even if there is no initializer list we still have to do the 231 // Even if there is no initializer list we still have to do the
152 // resolution in case there is an implicit super constructor call. 232 // resolution in case there is an implicit super constructor call.
153 InitializerResolver resolver = new InitializerResolver(visitor); 233 InitializerResolver resolver = new InitializerResolver(visitor);
154 FunctionElement redirection = 234 FunctionElement redirection =
155 resolver.resolveInitializers(element, tree); 235 resolver.resolveInitializers(element, tree);
156 if (redirection !== null) { 236 if (redirection !== null) {
157 resolveRedirectingConstructor(resolver, tree, element, redirection); 237 resolveRedirectingConstructor(resolver, tree, element, redirection);
238 }
239 } else if (tree.initializers != null) {
240 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
158 } 241 }
159 } else if (tree.initializers != null) { 242 visitBody(visitor, tree.body);
160 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
161 }
162 visitBody(visitor, tree.body);
163 243
164 return visitor.mapping; 244 return visitor.mapping;
245 });
165 }); 246 });
166 } 247 }
167 248
168 void visitBody(ResolverVisitor visitor, Statement body) { 249 void visitBody(ResolverVisitor visitor, Statement body) {
169 visitor.visit(body); 250 visitor.visit(body);
170 } 251 }
171 252
172 void resolveConstructorImplementation(FunctionElement constructor, 253 void resolveConstructorImplementation(FunctionElement constructor,
173 FunctionExpression node) { 254 FunctionExpression node) {
174 if (constructor.defaultImplementation !== constructor) return; 255 if (constructor.defaultImplementation !== constructor) return;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 381
301 ClassResolverVisitor visitor = 382 ClassResolverVisitor visitor =
302 new ClassResolverVisitor(compiler, element); 383 new ClassResolverVisitor(compiler, element);
303 visitor.visit(tree); 384 visitor.visit(tree);
304 element.resolutionState = STATE_DONE; 385 element.resolutionState = STATE_DONE;
305 })); 386 }));
306 } 387 }
307 388
308 void checkMembers(ClassElement cls) { 389 void checkMembers(ClassElement cls) {
309 if (cls === compiler.objectClass) return; 390 if (cls === compiler.objectClass) return;
310 cls.forEachMember((holder, member) { 391 cls.forEachMember(includeInjectedMembers: true,
392 f: (holder, member) {
311 // Perform various checks as side effect of "computing" the type. 393 // Perform various checks as side effect of "computing" the type.
312 member.computeType(compiler); 394 member.computeType(compiler);
313 395
314 // Check modifiers. 396 // Check modifiers.
315 if (member.isFunction() && member.modifiers.isFinal()) { 397 if (member.isFunction() && member.modifiers.isFinal()) {
316 compiler.reportMessage( 398 compiler.reportMessage(
317 compiler.spanFromElement(member), 399 compiler.spanFromElement(member),
318 MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(), 400 MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(),
319 api.Diagnostic.ERROR); 401 api.Diagnostic.ERROR);
320 } 402 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 initialized[name] = init; 609 initialized[name] = init;
528 } 610 }
529 611
530 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { 612 void resolveFieldInitializer(FunctionElement constructor, SendSet init) {
531 // init is of the form [this.]field = value. 613 // init is of the form [this.]field = value.
532 final Node selector = init.selector; 614 final Node selector = init.selector;
533 final SourceString name = selector.asIdentifier().source; 615 final SourceString name = selector.asIdentifier().source;
534 // Lookup target field. 616 // Lookup target field.
535 Element target; 617 Element target;
536 if (isFieldInitializer(init)) { 618 if (isFieldInitializer(init)) {
537 final ClassElement classElement = constructor.getEnclosingClass(); 619 Scope localScope = constructor.getEnclosingClass().buildLocalScope();
538 target = classElement.lookupLocalMember(name); 620 target = localScope.lookup(name);
539 if (target === null) { 621 if (target === null) {
540 error(selector, MessageKind.CANNOT_RESOLVE, [name]); 622 error(selector, MessageKind.CANNOT_RESOLVE, [name]);
541 } else if (target.kind != ElementKind.FIELD) { 623 } else if (target.kind != ElementKind.FIELD) {
542 error(selector, MessageKind.NOT_A_FIELD, [name]); 624 error(selector, MessageKind.NOT_A_FIELD, [name]);
543 } else if (!target.isInstanceMember()) { 625 } else if (!target.isInstanceMember()) {
544 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); 626 error(selector, MessageKind.INIT_STATIC_FIELD, [name]);
545 } 627 }
546 } else { 628 } else {
547 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); 629 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
548 } 630 }
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 } 1401 }
1320 if (!inInstanceContext) { 1402 if (!inInstanceContext) {
1321 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]); 1403 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]);
1322 return null; 1404 return null;
1323 } 1405 }
1324 if (currentClass.supertype === null) { 1406 if (currentClass.supertype === null) {
1325 // This is just to guard against internal errors, so no need 1407 // This is just to guard against internal errors, so no need
1326 // for a real error message. 1408 // for a real error message.
1327 error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]); 1409 error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]);
1328 } 1410 }
1411 // TODO(johnniwinther): Is this the right semantics? Should [: super. :]
1412 // not access inherited methods on super?
1413 // TODO(johnniwinther): Ensure correct behavior if currentClass is a
1414 // patch.
1329 target = currentClass.lookupSuperMember(name); 1415 target = currentClass.lookupSuperMember(name);
1330 // [target] may be null which means invoking noSuchMethod on 1416 // [target] may be null which means invoking noSuchMethod on
1331 // super. 1417 // super.
1332 } else if (Elements.isUnresolved(resolvedReceiver)) { 1418 } else if (Elements.isUnresolved(resolvedReceiver)) {
1333 return null; 1419 return null;
1334 } else if (resolvedReceiver.kind === ElementKind.CLASS) { 1420 } else if (resolvedReceiver.kind === ElementKind.CLASS) {
1335 ClassElement receiverClass = resolvedReceiver; 1421 ClassElement receiverClass = resolvedReceiver;
1336 target = receiverClass.ensureResolved(compiler).lookupLocalMember(name); 1422 receiverClass.ensureResolved(compiler);
1423 target = receiverClass.buildLocalScope().lookup(name);
1337 if (target === null) { 1424 if (target === null) {
1425 // TODO(johnniwinther): With the simplified [TreeElements] invariant,
1426 // try to resolve ghost elements if [currentClass] is in the patch
1427 // library of [receiverClass].
1428
1338 // TODO(karlklose): this should be reported by the caller of 1429 // TODO(karlklose): this should be reported by the caller of
1339 // [resolveSend] to select better warning messages for getters and 1430 // [resolveSend] to select better warning messages for getters and
1340 // setters. 1431 // setters.
1341 return warnAndCreateErroneousElement(node, name, 1432 return warnAndCreateErroneousElement(node, name,
1342 MessageKind.METHOD_NOT_FOUND, 1433 MessageKind.METHOD_NOT_FOUND,
1343 [receiverClass.name, name]); 1434 [receiverClass.name, name]);
1344 } else if (target.isInstanceMember()) { 1435 } else if (target.isInstanceMember()) {
1345 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]); 1436 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]);
1346 } 1437 }
1347 } else if (resolvedReceiver.kind === ElementKind.PREFIX) { 1438 } else if (resolvedReceiver.kind === ElementKind.PREFIX) {
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 // [constructor.defaultImplementation] might be the implementation element 1756 // [constructor.defaultImplementation] might be the implementation element
1666 // and only declaration elements may be registered. 1757 // and only declaration elements may be registered.
1667 world.registerStaticUse(constructor.defaultImplementation.declaration); 1758 world.registerStaticUse(constructor.defaultImplementation.declaration);
1668 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); 1759 ClassElement cls = constructor.defaultImplementation.getEnclosingClass();
1669 // [cls] might be the implementation element and only declaration elements 1760 // [cls] might be the implementation element and only declaration elements
1670 // may be registered. 1761 // may be registered.
1671 world.registerInstantiatedClass(cls.declaration); 1762 world.registerInstantiatedClass(cls.declaration);
1672 cls.forEachInstanceField( 1763 cls.forEachInstanceField(
1673 includeBackendMembers: false, 1764 includeBackendMembers: false,
1674 includeSuperMembers: true, 1765 includeSuperMembers: true,
1766 includeInjectedMembers: true,
1675 f: (ClassElement enclosingClass, Element member) { 1767 f: (ClassElement enclosingClass, Element member) {
1676 world.addToWorkList(member); 1768 world.addToWorkList(member);
1677 }); 1769 });
1678 return null; 1770 return null;
1679 } 1771 }
1680 1772
1681 /** 1773 /**
1682 * Try to resolve the constructor that is referred to by [node]. 1774 * Try to resolve the constructor that is referred to by [node].
1683 * Note: this function may return an ErroneousFunctionElement instead of 1775 * Note: this function may return an ErroneousFunctionElement instead of
1684 * [null], if there is no corresponding constructor, class or library. 1776 * [null], if there is no corresponding constructor, class or library.
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after
2314 type.element === compiler.nullClass || 2406 type.element === compiler.nullClass ||
2315 type.element === compiler.functionClass); 2407 type.element === compiler.functionClass);
2316 } 2408 }
2317 } 2409 }
2318 2410
2319 class ClassSupertypeResolver extends CommonResolverVisitor { 2411 class ClassSupertypeResolver extends CommonResolverVisitor {
2320 Scope context; 2412 Scope context;
2321 ClassElement classElement; 2413 ClassElement classElement;
2322 2414
2323 ClassSupertypeResolver(Compiler compiler, ClassElement cls) 2415 ClassSupertypeResolver(Compiler compiler, ClassElement cls)
2324 : context = new TopScope(cls.getLibrary()), 2416 : context = cls.buildEnclosingScope(),
2325 this.classElement = cls, 2417 this.classElement = cls,
2326 super(compiler); 2418 super(compiler);
2327 2419
2328 void loadSupertype(ClassElement element, Node from) { 2420 void loadSupertype(ClassElement element, Node from) {
2329 compiler.resolver.loadSupertypes(element, from); 2421 compiler.resolver.loadSupertypes(element, from);
2330 element.ensureResolved(compiler); 2422 element.ensureResolved(compiler);
2331 } 2423 }
2332 2424
2333 void visitClassNode(ClassNode node) { 2425 void visitClassNode(ClassNode node) {
2334 if (node.superclass === null) { 2426 if (node.superclass === null) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 TypeVariableType typeVariable = typeVariableLink.head; 2880 TypeVariableType typeVariable = typeVariableLink.head;
2789 if (typeVariable.name == name) { 2881 if (typeVariable.name == name) {
2790 return typeVariable.element; 2882 return typeVariable.element;
2791 } 2883 }
2792 typeVariableLink = typeVariableLink.tail; 2884 typeVariableLink = typeVariableLink.tail;
2793 } 2885 }
2794 return null; 2886 return null;
2795 } 2887 }
2796 2888
2797 String toString() => 2889 String toString() =>
2798 '$element${element.typeVariables} > $parent'; 2890 'TypeDeclarationScope($element)';
2799 } 2891 }
2800 2892
2801 class MethodScope extends Scope { 2893 class MethodScope extends Scope {
2802 final Map<SourceString, Element> elements; 2894 final Map<SourceString, Element> elements;
2803 2895
2804 MethodScope(Scope parent, Element element) 2896 MethodScope(Scope parent, Element element)
2805 : super(parent, element), 2897 : super(parent, element),
2806 this.elements = new Map<SourceString, Element>() { 2898 this.elements = new Map<SourceString, Element>() {
2807 assert(parent !== null); 2899 assert(parent !== null);
2808 } 2900 }
2809 2901
2810 Element localLookup(SourceString name) => elements[name]; 2902 Element localLookup(SourceString name) => elements[name];
2811 2903
2812 Element add(Element newElement) { 2904 Element add(Element newElement) {
2813 if (elements.containsKey(newElement.name)) { 2905 if (elements.containsKey(newElement.name)) {
2814 return elements[newElement.name]; 2906 return elements[newElement.name];
2815 } 2907 }
2816 elements[newElement.name] = newElement; 2908 elements[newElement.name] = newElement;
2817 return newElement; 2909 return newElement;
2818 } 2910 }
2819 2911
2820 String toString() => '$element${elements.getKeys()} > $parent'; 2912 String toString() => '$element${elements.getKeys()}';
2821 } 2913 }
2822 2914
2823 class BlockScope extends MethodScope { 2915 class BlockScope extends MethodScope {
2824 BlockScope(Scope parent) : super(parent, parent.element); 2916 BlockScope(Scope parent) : super(parent, parent.element);
2825 2917
2826 String toString() => 'block${elements.getKeys()} > $parent'; 2918 String toString() => 'block${elements.getKeys()}';
2827 } 2919 }
2828 2920
2829 /** 2921 /**
2830 * [ClassScope] defines the inner scope of a class/interface declaration in 2922 * [ClassScope] defines the inner scope of a class/interface declaration in
2831 * which declared members, declared type variables, entities in the enclosing 2923 * which declared members, declared type variables, entities in the enclosing
2832 * scope and inherited members are available, in the given order. 2924 * scope and inherited members are available, in the given order.
2833 */ 2925 */
2834 class ClassScope extends TypeDeclarationScope { 2926 class ClassScope extends TypeDeclarationScope {
2835 bool inStaticContext = false; 2927 bool inStaticContext = false;
2836 2928
2837 ClassScope(Scope parentScope, ClassElement element) 2929 ClassScope(Scope parentScope, ClassElement element)
2838 : super(parentScope, element); 2930 : super(parentScope, element) {
2931 assert(parent !== null);
2932 }
2839 2933
2840 Element localLookup(SourceString name) { 2934 Element localLookup(SourceString name) {
2841 ClassElement cls = element; 2935 ClassElement cls = element;
2842 Element result = cls.lookupLocalMember(name); 2936 Element result = cls.lookupLocalMember(name);
2843 if (result !== null) return result; 2937 if (result !== null) return result;
2844 if (!inStaticContext) { 2938 if (!inStaticContext) {
2845 // If not in a static context, we can lookup in the 2939 // If not in a static context, we can lookup in the
2846 // TypeDeclaration scope, which contains the type variables of 2940 // TypeDeclaration scope, which contains the type variables of
2847 // the class. 2941 // the class.
2848 return super.localLookup(name); 2942 result = super.localLookup(name);
2849 } 2943 }
2850 return null; 2944 return result;
2851 } 2945 }
2852 2946
2853 Element lookup(SourceString name) { 2947 Element lookup(SourceString name) {
2854 Element result = super.lookup(name); 2948 Element result = localLookup(name);
2949 if (result !== null) return result;
2950 result = parent.lookup(name);
2855 if (result !== null) return result; 2951 if (result !== null) return result;
2856 ClassElement cls = element; 2952 ClassElement cls = element;
2857 return cls.lookupSuperMember(name); 2953 return cls.lookupSuperMember(name);
2858 } 2954 }
2859 2955
2860 Element add(Element newElement) { 2956 Element add(Element newElement) {
2861 throw "Cannot add an element in a class scope"; 2957 throw "Cannot add an element in a class scope";
2862 } 2958 }
2863 2959
2864 String toString() => '$element > $parent'; 2960 String toString() => 'ClassScope($element)';
2961 }
2962
2963 class PatchClassScope extends TypeDeclarationScope {
2964 bool inStaticContext = false;
2965 ClassElement get origin => element;
2966 final ClassElement patch;
2967
2968 PatchClassScope(Scope parentScope,
2969 ClassElement origin, ClassElement this.patch)
2970 : super(parentScope, origin) {
2971 assert(parent !== null);
2972 }
2973
2974 Element localLookup(SourceString name) {
2975 Element result = patch.lookupLocalMember(name);
2976 if (result !== null) return result;
2977 result = origin.lookupLocalMember(name);
2978 if (result !== null) return result;
2979 if (!inStaticContext) {
2980 // If not in a static context, we can lookup in the
2981 // TypeDeclaration scope, which contains the type variables of
2982 // the class.
2983 result = super.localLookup(name);
2984 if (result !== null) return result;
2985 }
2986 result = parent.lookup(name);
2987 if (result !== null) return result;
2988 return result;
2989 }
2990
2991 Element lookup(SourceString name) {
2992 Element result = localLookup(name);
2993 if (result !== null) return result;
2994 // TODO(johnniwinther): Should we support patch lookup on supertypes?
2995 return origin.lookupSuperMember(name);
2996 }
2997
2998 Element add(Element newElement) {
2999 throw "Cannot add an element in a class scope";
3000 }
3001
3002 String toString() => 'PatchClassScope($origin,$patch)';
3003 }
3004
3005 class LocalClassScope extends Scope {
3006 LocalClassScope(ClassElement element)
3007 : super(null, element);
3008
3009 Element lookup(SourceString name) => localLookup(name);
3010
3011 Element localLookup(SourceString name) {
3012 ClassElement cls = element;
3013 return cls.lookupLocalMember(name);
3014 }
3015
3016 Element add(Element newElement) {
3017 throw "Cannot add an element in a class scope";
3018 }
3019
3020 String toString() => 'LocalClassScope($element)';
3021 }
3022
3023 class LocalPatchClassScope extends Scope {
3024 ClassElement get origin => element;
3025 final ClassElement patch;
3026
3027 LocalPatchClassScope(ClassElement origin, ClassElement this.patch)
3028 : super(null, origin);
3029
3030 Element lookup(SourceString name) => localLookup(name);
3031
3032 Element localLookup(SourceString name) {
3033 Element result = patch.lookupLocalMember(name);
3034 if (result !== null) return result;
3035 return origin.lookupLocalMember(name);
3036 }
3037
3038
3039 Element add(Element newElement) {
3040 throw "Cannot add an element in a class scope";
3041 }
3042
3043 String toString() => 'LocalPatchClassScope($origin,$patch)';
2865 } 3044 }
2866 3045
2867 class TopScope extends Scope { 3046 class TopScope extends Scope {
2868 LibraryElement get library => element; 3047 LibraryElement get library => element;
2869 3048
2870 TopScope(LibraryElement library) : super(null, library); 3049 TopScope(LibraryElement library) : super(null, library);
2871 3050
2872 Element localLookup(SourceString name) => library.find(name); 3051 Element localLookup(SourceString name) => library.find(name);
2873 Element lookup(SourceString name) => localLookup(name); 3052 Element lookup(SourceString name) => localLookup(name);
2874 Element lexicalLookup(SourceString name) => localLookup(name); 3053 Element lexicalLookup(SourceString name) => localLookup(name);
2875 3054
2876 Element add(Element newElement) { 3055 Element add(Element newElement) {
2877 throw "Cannot add an element in the top scope"; 3056 throw "Cannot add an element in the top scope";
2878 } 3057 }
2879 String toString() => '$element'; 3058 String toString() => 'LibraryScope($element)';
2880 } 3059 }
3060
3061 class PatchLibraryScope extends Scope {
3062 LibraryElement get origin => element;
3063 final LibraryElement patch;
3064
3065 PatchLibraryScope(LibraryElement origin, LibraryElement this.patch)
3066 : super(null, origin);
3067
3068 Element localLookup(SourceString name) {
3069 Element result = patch.find(name);
3070 if (result !== null) {
3071 return result;
3072 }
3073 result = origin.find(name);
3074 if (result !== null) {
3075 return result;
3076 }
3077 return result;
3078 }
3079 Element lookup(SourceString name) => localLookup(name);
3080 Element lexicalLookup(SourceString name) => localLookup(name);
3081
3082 Element add(Element newElement) {
3083 throw "Cannot add an element in a patch library scope";
3084 }
3085 String toString() => 'PatchLibraryScope($origin,$patch)';
3086 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698