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

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: Replaced includeInjectedMembers by implementation 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 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 checkMatchingPatchSignatures(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 checkMatchingPatchSignatures(FunctionElement origin,
137 FunctionElement patch) {
138 // TODO(johnniwinther): Stub. Implementation in a later CL.
139 }
140
129 TreeElements resolveMethodElement(FunctionElement element) { 141 TreeElements resolveMethodElement(FunctionElement element) {
130 assert(invariant(element, element.isDeclaration)); 142 assert(invariant(element, element.isDeclaration));
131 return compiler.withCurrentElement(element, () { 143 return compiler.withCurrentElement(element, () {
132 bool isConstructor = element.kind === ElementKind.GENERATIVE_CONSTRUCTOR; 144 bool isConstructor = element.kind === ElementKind.GENERATIVE_CONSTRUCTOR;
133 TreeElements elements = 145 TreeElements elements =
134 compiler.enqueuer.resolution.getCachedElements(element); 146 compiler.enqueuer.resolution.getCachedElements(element);
135 if (elements !== null) { 147 if (elements !== null) {
136 assert(isConstructor); 148 assert(isConstructor);
137 return elements; 149 return elements;
138 } 150 }
139 FunctionExpression tree = element.parseNode(compiler); 151 if (element.isPatched) {
140 if (isConstructor) { 152 checkMatchingPatchSignatures(element, element.patch);
141 if (tree.returnType !== null) { 153 element = element.patch;
142 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); 154 }
155 return compiler.withCurrentElement(element, () {
156 FunctionExpression tree = element.parseNode(compiler);
157 if (isConstructor) {
158 if (tree.returnType !== null) {
159 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
160 }
161 resolveConstructorImplementation(element, tree);
143 } 162 }
144 resolveConstructorImplementation(element, tree); 163 ResolverVisitor visitor = new ResolverVisitor(compiler, element);
145 } 164 visitor.useElement(tree, element);
146 ResolverVisitor visitor = new ResolverVisitor(compiler, element); 165 visitor.setupFunction(tree, element);
147 visitor.useElement(tree, element);
148 visitor.setupFunction(tree, element);
149 166
150 if (isConstructor) { 167 if (isConstructor) {
151 // Even if there is no initializer list we still have to do the 168 // Even if there is no initializer list we still have to do the
152 // resolution in case there is an implicit super constructor call. 169 // resolution in case there is an implicit super constructor call.
153 InitializerResolver resolver = new InitializerResolver(visitor); 170 InitializerResolver resolver = new InitializerResolver(visitor);
154 FunctionElement redirection = 171 FunctionElement redirection =
155 resolver.resolveInitializers(element, tree); 172 resolver.resolveInitializers(element, tree);
156 if (redirection !== null) { 173 if (redirection !== null) {
157 resolveRedirectingConstructor(resolver, tree, element, redirection); 174 resolveRedirectingConstructor(resolver, tree, element, redirection);
175 }
176 } else if (tree.initializers != null) {
177 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
158 } 178 }
159 } else if (tree.initializers != null) { 179 visitBody(visitor, tree.body);
160 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
161 }
162 visitBody(visitor, tree.body);
163 180
164 return visitor.mapping; 181 return visitor.mapping;
182 });
165 }); 183 });
166 } 184 }
167 185
168 void visitBody(ResolverVisitor visitor, Statement body) { 186 void visitBody(ResolverVisitor visitor, Statement body) {
169 visitor.visit(body); 187 visitor.visit(body);
170 } 188 }
171 189
172 void resolveConstructorImplementation(FunctionElement constructor, 190 void resolveConstructorImplementation(FunctionElement constructor,
173 FunctionExpression node) { 191 FunctionExpression node) {
174 if (constructor.defaultImplementation !== constructor) return; 192 if (constructor.defaultImplementation !== constructor) return;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 * 303 *
286 * Before calling this method, [element] was constructed by the 304 * Before calling this method, [element] was constructed by the
287 * scanner and most fields are null or empty. This method fills in 305 * scanner and most fields are null or empty. This method fills in
288 * these fields and also ensure that the supertypes of [element] are 306 * these fields and also ensure that the supertypes of [element] are
289 * resolved. 307 * resolved.
290 * 308 *
291 * Warning: Do not call this method directly. Instead use 309 * Warning: Do not call this method directly. Instead use
292 * [:element.ensureResolved(compiler):]. 310 * [:element.ensureResolved(compiler):].
293 */ 311 */
294 void resolveClass(ClassElement element) { 312 void resolveClass(ClassElement element) {
295 compiler.withCurrentElement(element, () => measure(() { 313 if (!element.isPatch) {
296 assert(element.resolutionState == STATE_NOT_STARTED); 314 compiler.withCurrentElement(element, () => measure(() {
315 assert(element.resolutionState == STATE_NOT_STARTED);
316 element.resolutionState = STATE_STARTED;
317 ClassNode tree = element.parseNode(compiler);
318 loadSupertypes(element, tree);
319
320 ClassResolverVisitor visitor =
321 new ClassResolverVisitor(compiler, element);
322 visitor.visit(tree);
323 element.resolutionState = STATE_DONE;
324 }));
325 if (element.isPatched) {
326 // Ensure handling patch after origin.
327 element.patch.ensureResolved(compiler);
328 }
329 } else { // Handle patch classes:
297 element.resolutionState = STATE_STARTED; 330 element.resolutionState = STATE_STARTED;
298 ClassNode tree = element.parseNode(compiler); 331 // Ensure handling origin before patch.
299 loadSupertypes(element, tree); 332 element.origin.ensureResolved(compiler);
300 333 // Ensure that the type is computed.
301 ClassResolverVisitor visitor = 334 element.computeType(compiler);
302 new ClassResolverVisitor(compiler, element); 335 // Copy class hiearchy from origin.
303 visitor.visit(tree); 336 element.supertype = element.origin.supertype;
337 element.defaultClass = element.origin.defaultClass;
338 element.interfaces = element.origin.interfaces;
ahe 2012/10/02 13:27:04 I think this is wrong.
ahe 2012/10/02 14:33:26 Never mind.
339 element.allSupertypes = element.origin.allSupertypes;
340 // Stepwise assignment to ensure invariant.
341 element.supertypeLoadState = STATE_STARTED;
342 element.supertypeLoadState = STATE_DONE;
304 element.resolutionState = STATE_DONE; 343 element.resolutionState = STATE_DONE;
305 })); 344 // TODO(johnniwinther): Check matching type variables and
345 // empty extends/implements clauses.
346 }
306 } 347 }
307 348
308 void checkMembers(ClassElement cls) { 349 void checkMembers(ClassElement cls) {
309 if (cls === compiler.objectClass) return; 350 if (cls === compiler.objectClass) return;
310 cls.forEachMember((holder, member) { 351 // Should this be done on the implementation element?
ahe 2012/10/02 13:27:04 TODO?
Johnni Winther 2012/10/03 09:22:59 Done.
352 cls.implementation.forEachMember((holder, member) {
ahe 2012/10/02 13:27:04 Shouldn't this be declaration?
Johnni Winther 2012/10/03 09:22:59 Yes. Done.
311 // Perform various checks as side effect of "computing" the type. 353 // Perform various checks as side effect of "computing" the type.
312 member.computeType(compiler); 354 member.computeType(compiler);
313 355
314 // Check modifiers. 356 // Check modifiers.
315 if (member.isFunction() && member.modifiers.isFinal()) { 357 if (member.isFunction() && member.modifiers.isFinal()) {
316 compiler.reportMessage( 358 compiler.reportMessage(
317 compiler.spanFromElement(member), 359 compiler.spanFromElement(member),
318 MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(), 360 MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(),
319 api.Diagnostic.ERROR); 361 api.Diagnostic.ERROR);
320 } 362 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 initialized[name] = init; 569 initialized[name] = init;
528 } 570 }
529 571
530 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { 572 void resolveFieldInitializer(FunctionElement constructor, SendSet init) {
531 // init is of the form [this.]field = value. 573 // init is of the form [this.]field = value.
532 final Node selector = init.selector; 574 final Node selector = init.selector;
533 final SourceString name = selector.asIdentifier().source; 575 final SourceString name = selector.asIdentifier().source;
534 // Lookup target field. 576 // Lookup target field.
535 Element target; 577 Element target;
536 if (isFieldInitializer(init)) { 578 if (isFieldInitializer(init)) {
537 final ClassElement classElement = constructor.getEnclosingClass(); 579 Scope localScope = constructor.getEnclosingClass().buildLocalScope();
538 target = classElement.lookupLocalMember(name); 580 target = localScope.lookup(name);
539 if (target === null) { 581 if (target === null) {
540 error(selector, MessageKind.CANNOT_RESOLVE, [name]); 582 error(selector, MessageKind.CANNOT_RESOLVE, [name]);
541 } else if (target.kind != ElementKind.FIELD) { 583 } else if (target.kind != ElementKind.FIELD) {
542 error(selector, MessageKind.NOT_A_FIELD, [name]); 584 error(selector, MessageKind.NOT_A_FIELD, [name]);
543 } else if (!target.isInstanceMember()) { 585 } else if (!target.isInstanceMember()) {
544 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); 586 error(selector, MessageKind.INIT_STATIC_FIELD, [name]);
545 } 587 }
546 } else { 588 } else {
547 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); 589 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
548 } 590 }
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 } 1361 }
1320 if (!inInstanceContext) { 1362 if (!inInstanceContext) {
1321 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]); 1363 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]);
1322 return null; 1364 return null;
1323 } 1365 }
1324 if (currentClass.supertype === null) { 1366 if (currentClass.supertype === null) {
1325 // This is just to guard against internal errors, so no need 1367 // This is just to guard against internal errors, so no need
1326 // for a real error message. 1368 // for a real error message.
1327 error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]); 1369 error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]);
1328 } 1370 }
1371 // TODO(johnniwinther): Is this the right semantics? Should [: super. :]
ahe 2012/10/02 13:27:04 I don't understand your questions
Johnni Winther 2012/10/03 09:22:59 I was wrong.
1372 // not access inherited methods on super?
1373 // TODO(johnniwinther): Ensure correct behavior if currentClass is a
1374 // patch.
1329 target = currentClass.lookupSuperMember(name); 1375 target = currentClass.lookupSuperMember(name);
1330 // [target] may be null which means invoking noSuchMethod on 1376 // [target] may be null which means invoking noSuchMethod on
1331 // super. 1377 // super.
1332 } else if (Elements.isUnresolved(resolvedReceiver)) { 1378 } else if (Elements.isUnresolved(resolvedReceiver)) {
1333 return null; 1379 return null;
1334 } else if (resolvedReceiver.kind === ElementKind.CLASS) { 1380 } else if (resolvedReceiver.kind === ElementKind.CLASS) {
1335 ClassElement receiverClass = resolvedReceiver; 1381 ClassElement receiverClass = resolvedReceiver;
1336 target = receiverClass.ensureResolved(compiler).lookupLocalMember(name); 1382 receiverClass.ensureResolved(compiler);
1383 target = receiverClass.buildLocalScope().lookup(name);
1337 if (target === null) { 1384 if (target === null) {
1385 // TODO(johnniwinther): With the simplified [TreeElements] invariant,
1386 // try to resolve ghost elements if [currentClass] is in the patch
1387 // library of [receiverClass].
1388
1338 // TODO(karlklose): this should be reported by the caller of 1389 // TODO(karlklose): this should be reported by the caller of
1339 // [resolveSend] to select better warning messages for getters and 1390 // [resolveSend] to select better warning messages for getters and
1340 // setters. 1391 // setters.
1341 return warnAndCreateErroneousElement(node, name, 1392 return warnAndCreateErroneousElement(node, name,
1342 MessageKind.METHOD_NOT_FOUND, 1393 MessageKind.METHOD_NOT_FOUND,
1343 [receiverClass.name, name]); 1394 [receiverClass.name, name]);
1344 } else if (target.isInstanceMember()) { 1395 } else if (target.isInstanceMember()) {
1345 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]); 1396 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]);
1346 } 1397 }
1347 } else if (resolvedReceiver.kind === ElementKind.PREFIX) { 1398 } else if (resolvedReceiver.kind === ElementKind.PREFIX) {
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 FunctionExpression tree = constructor.parseNode(compiler); 1713 FunctionExpression tree = constructor.parseNode(compiler);
1663 compiler.resolver.resolveConstructorImplementation(constructor, tree); 1714 compiler.resolver.resolveConstructorImplementation(constructor, tree);
1664 }); 1715 });
1665 // [constructor.defaultImplementation] might be the implementation element 1716 // [constructor.defaultImplementation] might be the implementation element
1666 // and only declaration elements may be registered. 1717 // and only declaration elements may be registered.
1667 world.registerStaticUse(constructor.defaultImplementation.declaration); 1718 world.registerStaticUse(constructor.defaultImplementation.declaration);
1668 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); 1719 ClassElement cls = constructor.defaultImplementation.getEnclosingClass();
1669 // [cls] might be the implementation element and only declaration elements 1720 // [cls] might be the implementation element and only declaration elements
1670 // may be registered. 1721 // may be registered.
1671 world.registerInstantiatedClass(cls.declaration); 1722 world.registerInstantiatedClass(cls.declaration);
1672 cls.forEachInstanceField( 1723 cls.implementation.forEachInstanceField(
ahe 2012/10/02 13:27:04 This feels iffy.
Johnni Winther 2012/10/03 09:22:59 Yes. We unfortunately have no invariant for getEnc
1673 includeBackendMembers: false, 1724 includeBackendMembers: false,
1674 includeSuperMembers: true, 1725 includeSuperMembers: true,
1675 f: (ClassElement enclosingClass, Element member) { 1726 f: (ClassElement enclosingClass, Element member) {
1676 world.addToWorkList(member); 1727 world.addToWorkList(member);
1677 }); 1728 });
1678 return null; 1729 return null;
1679 } 1730 }
1680 1731
1681 /** 1732 /**
1682 * Try to resolve the constructor that is referred to by [node]. 1733 * Try to resolve the constructor that is referred to by [node].
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
2314 type.element === compiler.nullClass || 2365 type.element === compiler.nullClass ||
2315 type.element === compiler.functionClass); 2366 type.element === compiler.functionClass);
2316 } 2367 }
2317 } 2368 }
2318 2369
2319 class ClassSupertypeResolver extends CommonResolverVisitor { 2370 class ClassSupertypeResolver extends CommonResolverVisitor {
2320 Scope context; 2371 Scope context;
2321 ClassElement classElement; 2372 ClassElement classElement;
2322 2373
2323 ClassSupertypeResolver(Compiler compiler, ClassElement cls) 2374 ClassSupertypeResolver(Compiler compiler, ClassElement cls)
2324 : context = new TopScope(cls.getLibrary()), 2375 : context = cls.buildEnclosingScope(),
2325 this.classElement = cls, 2376 this.classElement = cls,
2326 super(compiler); 2377 super(compiler);
2327 2378
2328 void loadSupertype(ClassElement element, Node from) { 2379 void loadSupertype(ClassElement element, Node from) {
2329 compiler.resolver.loadSupertypes(element, from); 2380 compiler.resolver.loadSupertypes(element, from);
2330 element.ensureResolved(compiler); 2381 element.ensureResolved(compiler);
2331 } 2382 }
2332 2383
2333 void visitClassNode(ClassNode node) { 2384 void visitClassNode(ClassNode node) {
2334 if (node.superclass === null) { 2385 if (node.superclass === null) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 TypeVariableType typeVariable = typeVariableLink.head; 2839 TypeVariableType typeVariable = typeVariableLink.head;
2789 if (typeVariable.name == name) { 2840 if (typeVariable.name == name) {
2790 return typeVariable.element; 2841 return typeVariable.element;
2791 } 2842 }
2792 typeVariableLink = typeVariableLink.tail; 2843 typeVariableLink = typeVariableLink.tail;
2793 } 2844 }
2794 return null; 2845 return null;
2795 } 2846 }
2796 2847
2797 String toString() => 2848 String toString() =>
2798 '$element${element.typeVariables} > $parent'; 2849 'TypeDeclarationScope($element)';
2799 } 2850 }
2800 2851
2801 class MethodScope extends Scope { 2852 class MethodScope extends Scope {
2802 final Map<SourceString, Element> elements; 2853 final Map<SourceString, Element> elements;
2803 2854
2804 MethodScope(Scope parent, Element element) 2855 MethodScope(Scope parent, Element element)
2805 : super(parent, element), 2856 : super(parent, element),
2806 this.elements = new Map<SourceString, Element>() { 2857 this.elements = new Map<SourceString, Element>() {
2807 assert(parent !== null); 2858 assert(parent !== null);
2808 } 2859 }
2809 2860
2810 Element localLookup(SourceString name) => elements[name]; 2861 Element localLookup(SourceString name) => elements[name];
2811 2862
2812 Element add(Element newElement) { 2863 Element add(Element newElement) {
2813 if (elements.containsKey(newElement.name)) { 2864 if (elements.containsKey(newElement.name)) {
2814 return elements[newElement.name]; 2865 return elements[newElement.name];
2815 } 2866 }
2816 elements[newElement.name] = newElement; 2867 elements[newElement.name] = newElement;
2817 return newElement; 2868 return newElement;
2818 } 2869 }
2819 2870
2820 String toString() => '$element${elements.getKeys()} > $parent'; 2871 String toString() => '$element${elements.getKeys()}';
2821 } 2872 }
2822 2873
2823 class BlockScope extends MethodScope { 2874 class BlockScope extends MethodScope {
2824 BlockScope(Scope parent) : super(parent, parent.element); 2875 BlockScope(Scope parent) : super(parent, parent.element);
2825 2876
2826 String toString() => 'block${elements.getKeys()} > $parent'; 2877 String toString() => 'block${elements.getKeys()}';
2827 } 2878 }
2828 2879
2829 /** 2880 /**
2830 * [ClassScope] defines the inner scope of a class/interface declaration in 2881 * [ClassScope] defines the inner scope of a class/interface declaration in
2831 * which declared members, declared type variables, entities in the enclosing 2882 * which declared members, declared type variables, entities in the enclosing
2832 * scope and inherited members are available, in the given order. 2883 * scope and inherited members are available, in the given order.
2833 */ 2884 */
2834 class ClassScope extends TypeDeclarationScope { 2885 class ClassScope extends TypeDeclarationScope {
2835 bool inStaticContext = false; 2886 bool inStaticContext = false;
2836 2887
2837 ClassScope(Scope parentScope, ClassElement element) 2888 ClassScope(Scope parentScope, ClassElement element)
2838 : super(parentScope, element); 2889 : super(parentScope, element) {
2890 assert(parent !== null);
2891 }
2839 2892
2840 Element localLookup(SourceString name) { 2893 Element localLookup(SourceString name) {
2841 ClassElement cls = element; 2894 ClassElement cls = element;
2842 Element result = cls.lookupLocalMember(name); 2895 Element result = cls.lookupLocalMember(name);
2843 if (result !== null) return result; 2896 if (result !== null) return result;
2844 if (!inStaticContext) { 2897 if (!inStaticContext) {
2845 // If not in a static context, we can lookup in the 2898 // If not in a static context, we can lookup in the
2846 // TypeDeclaration scope, which contains the type variables of 2899 // TypeDeclaration scope, which contains the type variables of
2847 // the class. 2900 // the class.
2848 return super.localLookup(name); 2901 result = super.localLookup(name);
2849 } 2902 }
2850 return null; 2903 return result;
2851 } 2904 }
2852 2905
2853 Element lookup(SourceString name) { 2906 Element lookup(SourceString name) {
2854 Element result = super.lookup(name); 2907 Element result = localLookup(name);
2908 if (result !== null) return result;
2909 result = parent.lookup(name);
2855 if (result !== null) return result; 2910 if (result !== null) return result;
2856 ClassElement cls = element; 2911 ClassElement cls = element;
2857 return cls.lookupSuperMember(name); 2912 return cls.lookupSuperMember(name);
2858 } 2913 }
2859 2914
2860 Element add(Element newElement) { 2915 Element add(Element newElement) {
2861 throw "Cannot add an element in a class scope"; 2916 throw "Cannot add an element in a class scope";
2862 } 2917 }
2863 2918
2864 String toString() => '$element > $parent'; 2919 String toString() => 'ClassScope($element)';
2920 }
2921
2922 class PatchClassScope extends TypeDeclarationScope {
ahe 2012/10/02 13:27:04 I'm concerned about the "explosion" of scope class
Johnni Winther 2012/10/03 09:22:59 Added a TODO.
2923 bool inStaticContext = false;
2924 ClassElement get origin => element;
2925 final ClassElement patch;
2926
2927 PatchClassScope(Scope parentScope,
2928 ClassElement origin, ClassElement this.patch)
2929 : super(parentScope, origin) {
2930 assert(parent !== null);
2931 }
2932
2933 Element localLookup(SourceString name) {
2934 Element result = patch.lookupLocalMember(name);
2935 if (result !== null) return result;
2936 result = origin.lookupLocalMember(name);
2937 if (result !== null) return result;
2938 if (!inStaticContext) {
2939 // If not in a static context, we can lookup in the
2940 // TypeDeclaration scope, which contains the type variables of
2941 // the class.
2942 result = super.localLookup(name);
2943 if (result !== null) return result;
2944 }
2945 result = parent.lookup(name);
2946 if (result !== null) return result;
2947 return result;
2948 }
2949
2950 Element lookup(SourceString name) {
2951 Element result = localLookup(name);
2952 if (result !== null) return result;
2953 // TODO(johnniwinther): Should we support patch lookup on supertypes?
2954 return origin.lookupSuperMember(name);
2955 }
2956
2957 Element add(Element newElement) {
2958 throw "Cannot add an element in a class scope";
2959 }
2960
2961 String toString() => 'PatchClassScope($origin,$patch)';
2962 }
2963
2964 class LocalClassScope extends Scope {
2965 LocalClassScope(ClassElement element)
2966 : super(null, element);
2967
2968 Element lookup(SourceString name) => localLookup(name);
2969
2970 Element localLookup(SourceString name) {
2971 ClassElement cls = element;
2972 return cls.lookupLocalMember(name);
2973 }
2974
2975 Element add(Element newElement) {
2976 throw "Cannot add an element in a class scope";
2977 }
2978
2979 String toString() => 'LocalClassScope($element)';
2980 }
2981
2982 class LocalPatchClassScope extends Scope {
2983 ClassElement get origin => element;
2984 final ClassElement patch;
2985
2986 LocalPatchClassScope(ClassElement origin, ClassElement this.patch)
2987 : super(null, origin);
2988
2989 Element lookup(SourceString name) => localLookup(name);
2990
2991 Element localLookup(SourceString name) {
2992 Element result = patch.lookupLocalMember(name);
2993 if (result !== null) return result;
2994 return origin.lookupLocalMember(name);
2995 }
2996
2997
2998 Element add(Element newElement) {
2999 throw "Cannot add an element in a class scope";
3000 }
3001
3002 String toString() => 'LocalPatchClassScope($origin,$patch)';
2865 } 3003 }
2866 3004
2867 class TopScope extends Scope { 3005 class TopScope extends Scope {
2868 LibraryElement get library => element; 3006 LibraryElement get library => element;
2869 3007
2870 TopScope(LibraryElement library) : super(null, library); 3008 TopScope(LibraryElement library) : super(null, library);
2871 3009
2872 Element localLookup(SourceString name) => library.find(name); 3010 Element localLookup(SourceString name) => library.find(name);
2873 Element lookup(SourceString name) => localLookup(name); 3011 Element lookup(SourceString name) => localLookup(name);
2874 Element lexicalLookup(SourceString name) => localLookup(name); 3012 Element lexicalLookup(SourceString name) => localLookup(name);
2875 3013
2876 Element add(Element newElement) { 3014 Element add(Element newElement) {
2877 throw "Cannot add an element in the top scope"; 3015 throw "Cannot add an element in the top scope";
2878 } 3016 }
2879 String toString() => '$element'; 3017 String toString() => 'LibraryScope($element)';
2880 } 3018 }
3019
3020 class PatchLibraryScope extends Scope {
3021 LibraryElement get origin => element;
3022 final LibraryElement patch;
3023
3024 PatchLibraryScope(LibraryElement origin, LibraryElement this.patch)
3025 : super(null, origin);
3026
3027 Element localLookup(SourceString name) {
3028 Element result = patch.find(name);
3029 if (result !== null) {
3030 return result;
3031 }
3032 result = origin.find(name);
3033 if (result !== null) {
3034 return result;
3035 }
3036 return result;
3037 }
3038 Element lookup(SourceString name) => localLookup(name);
3039 Element lexicalLookup(SourceString name) => localLookup(name);
3040
3041 Element add(Element newElement) {
3042 throw "Cannot add an element in a patch library scope";
3043 }
3044 String toString() => 'PatchLibraryScope($origin,$patch)';
3045 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698