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

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, 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) { 27 if (node is FunctionExpression) {
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;
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 assert(invariant(cls, cls.isDeclaration));
351 if (cls.isObject(compiler)) return;
352 // TODO(johnniwinther): Should this be done on the implementation element as
353 // well?
310 cls.forEachMember((holder, member) { 354 cls.forEachMember((holder, member) {
311 // Perform various checks as side effect of "computing" the type. 355 // Perform various checks as side effect of "computing" the type.
312 member.computeType(compiler); 356 member.computeType(compiler);
313 357
314 // Check modifiers. 358 // Check modifiers.
315 if (member.isFunction() && member.modifiers.isFinal()) { 359 if (member.isFunction() && member.modifiers.isFinal()) {
316 compiler.reportMessage( 360 compiler.reportMessage(
317 compiler.spanFromElement(member), 361 compiler.spanFromElement(member),
318 MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(), 362 MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(),
319 api.Diagnostic.ERROR); 363 api.Diagnostic.ERROR);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 initialized[name] = init; 571 initialized[name] = init;
528 } 572 }
529 573
530 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { 574 void resolveFieldInitializer(FunctionElement constructor, SendSet init) {
531 // init is of the form [this.]field = value. 575 // init is of the form [this.]field = value.
532 final Node selector = init.selector; 576 final Node selector = init.selector;
533 final SourceString name = selector.asIdentifier().source; 577 final SourceString name = selector.asIdentifier().source;
534 // Lookup target field. 578 // Lookup target field.
535 Element target; 579 Element target;
536 if (isFieldInitializer(init)) { 580 if (isFieldInitializer(init)) {
537 final ClassElement classElement = constructor.getEnclosingClass(); 581 Scope localScope = constructor.getEnclosingClass().buildLocalScope();
538 target = classElement.lookupLocalMember(name); 582 target = localScope.lookup(name);
539 if (target === null) { 583 if (target === null) {
540 error(selector, MessageKind.CANNOT_RESOLVE, [name]); 584 error(selector, MessageKind.CANNOT_RESOLVE, [name]);
541 } else if (target.kind != ElementKind.FIELD) { 585 } else if (target.kind != ElementKind.FIELD) {
542 error(selector, MessageKind.NOT_A_FIELD, [name]); 586 error(selector, MessageKind.NOT_A_FIELD, [name]);
543 } else if (!target.isInstanceMember()) { 587 } else if (!target.isInstanceMember()) {
544 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); 588 error(selector, MessageKind.INIT_STATIC_FIELD, [name]);
545 } 589 }
546 } else { 590 } else {
547 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); 591 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
548 } 592 }
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 } 1363 }
1320 if (!inInstanceContext) { 1364 if (!inInstanceContext) {
1321 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]); 1365 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]);
1322 return null; 1366 return null;
1323 } 1367 }
1324 if (currentClass.supertype === null) { 1368 if (currentClass.supertype === null) {
1325 // This is just to guard against internal errors, so no need 1369 // This is just to guard against internal errors, so no need
1326 // for a real error message. 1370 // for a real error message.
1327 error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]); 1371 error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]);
1328 } 1372 }
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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 FunctionExpression tree = constructor.parseNode(compiler); 1722 FunctionExpression tree = constructor.parseNode(compiler);
1672 compiler.resolver.resolveConstructorImplementation(constructor, tree); 1723 compiler.resolver.resolveConstructorImplementation(constructor, tree);
1673 }); 1724 });
1674 // [constructor.defaultImplementation] might be the implementation element 1725 // [constructor.defaultImplementation] might be the implementation element
1675 // and only declaration elements may be registered. 1726 // and only declaration elements may be registered.
1676 world.registerStaticUse(constructor.defaultImplementation.declaration); 1727 world.registerStaticUse(constructor.defaultImplementation.declaration);
1677 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); 1728 ClassElement cls = constructor.defaultImplementation.getEnclosingClass();
1678 // [cls] might be the implementation element and only declaration elements 1729 // [cls] might be the implementation element and only declaration elements
1679 // may be registered. 1730 // may be registered.
1680 world.registerInstantiatedClass(cls.declaration); 1731 world.registerInstantiatedClass(cls.declaration);
1681 cls.forEachInstanceField( 1732 // [cls] might be the declaration element and we want to include injected
1733 // members.
1734 cls.implementation.forEachInstanceField(
1682 includeBackendMembers: false, 1735 includeBackendMembers: false,
1683 includeSuperMembers: true, 1736 includeSuperMembers: true,
1684 f: (ClassElement enclosingClass, Element member) { 1737 f: (ClassElement enclosingClass, Element member) {
1685 world.addToWorkList(member); 1738 world.addToWorkList(member);
1686 }); 1739 });
1687 return null; 1740 return null;
1688 } 1741 }
1689 1742
1690 /** 1743 /**
1691 * Try to resolve the constructor that is referred to by [node]. 1744 * Try to resolve the constructor that is referred to by [node].
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
2323 type.element === compiler.nullClass || 2376 type.element === compiler.nullClass ||
2324 type.element === compiler.functionClass); 2377 type.element === compiler.functionClass);
2325 } 2378 }
2326 } 2379 }
2327 2380
2328 class ClassSupertypeResolver extends CommonResolverVisitor { 2381 class ClassSupertypeResolver extends CommonResolverVisitor {
2329 Scope context; 2382 Scope context;
2330 ClassElement classElement; 2383 ClassElement classElement;
2331 2384
2332 ClassSupertypeResolver(Compiler compiler, ClassElement cls) 2385 ClassSupertypeResolver(Compiler compiler, ClassElement cls)
2333 : context = new TopScope(cls.getLibrary()), 2386 : context = cls.buildEnclosingScope(),
2334 this.classElement = cls, 2387 this.classElement = cls,
2335 super(compiler); 2388 super(compiler);
2336 2389
2337 void loadSupertype(ClassElement element, Node from) { 2390 void loadSupertype(ClassElement element, Node from) {
2338 compiler.resolver.loadSupertypes(element, from); 2391 compiler.resolver.loadSupertypes(element, from);
2339 element.ensureResolved(compiler); 2392 element.ensureResolved(compiler);
2340 } 2393 }
2341 2394
2342 void visitClassNode(ClassNode node) { 2395 void visitClassNode(ClassNode node) {
2343 if (node.superclass === null) { 2396 if (node.superclass === null) {
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2796 TypeVariableType typeVariable = typeVariableLink.head; 2849 TypeVariableType typeVariable = typeVariableLink.head;
2797 if (typeVariable.name == name) { 2850 if (typeVariable.name == name) {
2798 return typeVariable.element; 2851 return typeVariable.element;
2799 } 2852 }
2800 typeVariableLink = typeVariableLink.tail; 2853 typeVariableLink = typeVariableLink.tail;
2801 } 2854 }
2802 return null; 2855 return null;
2803 } 2856 }
2804 2857
2805 String toString() => 2858 String toString() =>
2806 '$element${element.typeVariables} > $parent'; 2859 'TypeDeclarationScope($element)';
2807 } 2860 }
2808 2861
2809 class MethodScope extends Scope { 2862 class MethodScope extends Scope {
2810 final Map<SourceString, Element> elements; 2863 final Map<SourceString, Element> elements;
2811 2864
2812 MethodScope(Scope parent, Element element) 2865 MethodScope(Scope parent, Element element)
2813 : super(parent, element), 2866 : super(parent, element),
2814 this.elements = new Map<SourceString, Element>() { 2867 this.elements = new Map<SourceString, Element>() {
2815 assert(parent !== null); 2868 assert(parent !== null);
2816 } 2869 }
2817 2870
2818 Element localLookup(SourceString name) => elements[name]; 2871 Element localLookup(SourceString name) => elements[name];
2819 2872
2820 Element add(Element newElement) { 2873 Element add(Element newElement) {
2821 if (elements.containsKey(newElement.name)) { 2874 if (elements.containsKey(newElement.name)) {
2822 return elements[newElement.name]; 2875 return elements[newElement.name];
2823 } 2876 }
2824 elements[newElement.name] = newElement; 2877 elements[newElement.name] = newElement;
2825 return newElement; 2878 return newElement;
2826 } 2879 }
2827 2880
2828 String toString() => '$element${elements.getKeys()} > $parent'; 2881 String toString() => '$element${elements.getKeys()}';
2829 } 2882 }
2830 2883
2831 class BlockScope extends MethodScope { 2884 class BlockScope extends MethodScope {
2832 BlockScope(Scope parent) : super(parent, parent.element); 2885 BlockScope(Scope parent) : super(parent, parent.element);
2833 2886
2834 String toString() => 'block${elements.getKeys()} > $parent'; 2887 String toString() => 'block${elements.getKeys()}';
2835 } 2888 }
2836 2889
2837 /** 2890 /**
2838 * [ClassScope] defines the inner scope of a class/interface declaration in 2891 * [ClassScope] defines the inner scope of a class/interface declaration in
2839 * which declared members, declared type variables, entities in the enclosing 2892 * which declared members, declared type variables, entities in the enclosing
2840 * scope and inherited members are available, in the given order. 2893 * scope and inherited members are available, in the given order.
2841 */ 2894 */
2842 class ClassScope extends TypeDeclarationScope { 2895 class ClassScope extends TypeDeclarationScope {
2843 bool inStaticContext = false; 2896 bool inStaticContext = false;
2844 2897
2845 ClassScope(Scope parentScope, ClassElement element) 2898 ClassScope(Scope parentScope, ClassElement element)
2846 : super(parentScope, element); 2899 : super(parentScope, element) {
2900 assert(parent !== null);
2901 }
2847 2902
2848 Element localLookup(SourceString name) { 2903 Element localLookup(SourceString name) {
2849 ClassElement cls = element; 2904 ClassElement cls = element;
2850 Element result = cls.lookupLocalMember(name); 2905 Element result = cls.lookupLocalMember(name);
2851 if (result !== null) return result; 2906 if (result !== null) return result;
2852 if (!inStaticContext) { 2907 if (!inStaticContext) {
2853 // If not in a static context, we can lookup in the 2908 // If not in a static context, we can lookup in the
2854 // TypeDeclaration scope, which contains the type variables of 2909 // TypeDeclaration scope, which contains the type variables of
2855 // the class. 2910 // the class.
2856 return super.localLookup(name); 2911 result = super.localLookup(name);
2857 } 2912 }
2858 return null; 2913 return result;
2859 } 2914 }
2860 2915
2861 Element lookup(SourceString name) { 2916 Element lookup(SourceString name) {
2862 Element result = super.lookup(name); 2917 Element result = localLookup(name);
2918 if (result !== null) return result;
2919 result = parent.lookup(name);
2863 if (result !== null) return result; 2920 if (result !== null) return result;
2864 ClassElement cls = element; 2921 ClassElement cls = element;
2865 return cls.lookupSuperMember(name); 2922 return cls.lookupSuperMember(name);
2866 } 2923 }
2867 2924
2868 Element add(Element newElement) { 2925 Element add(Element newElement) {
2869 throw "Cannot add an element in a class scope"; 2926 throw "Cannot add an element in a class scope";
2870 } 2927 }
2871 2928
2872 String toString() => '$element > $parent'; 2929 String toString() => 'ClassScope($element)';
2930 }
2931
2932 // TODO(johnniwinther): Refactor scopes to avoid class explosion.
2933 class PatchClassScope extends TypeDeclarationScope {
2934 bool inStaticContext = false;
2935 ClassElement get origin => element;
2936 final ClassElement patch;
2937
2938 PatchClassScope(Scope parentScope,
2939 ClassElement origin, ClassElement this.patch)
2940 : super(parentScope, origin) {
2941 assert(parent !== null);
2942 }
2943
2944 Element localLookup(SourceString name) {
2945 Element result = patch.lookupLocalMember(name);
2946 if (result !== null) return result;
2947 result = origin.lookupLocalMember(name);
2948 if (result !== null) return result;
2949 if (!inStaticContext) {
2950 // If not in a static context, we can lookup in the
2951 // TypeDeclaration scope, which contains the type variables of
2952 // the class.
2953 result = super.localLookup(name);
2954 if (result !== null) return result;
2955 }
2956 result = parent.lookup(name);
2957 if (result !== null) return result;
2958 return result;
2959 }
2960
2961 Element lookup(SourceString name) {
2962 Element result = localLookup(name);
2963 if (result !== null) return result;
2964 // TODO(johnniwinther): Should we support patch lookup on supertypes?
2965 return origin.lookupSuperMember(name);
2966 }
2967
2968 Element add(Element newElement) {
2969 throw "Cannot add an element in a class scope";
2970 }
2971
2972 String toString() => 'PatchClassScope($origin,$patch)';
2973 }
2974
2975 class LocalClassScope extends Scope {
2976 LocalClassScope(ClassElement element)
2977 : super(null, element);
2978
2979 Element lookup(SourceString name) => localLookup(name);
2980
2981 Element localLookup(SourceString name) {
2982 ClassElement cls = element;
2983 return cls.lookupLocalMember(name);
2984 }
2985
2986 Element add(Element newElement) {
2987 throw "Cannot add an element in a class scope";
2988 }
2989
2990 String toString() => 'LocalClassScope($element)';
2991 }
2992
2993 class LocalPatchClassScope extends Scope {
2994 ClassElement get origin => element;
2995 final ClassElement patch;
2996
2997 LocalPatchClassScope(ClassElement origin, ClassElement this.patch)
2998 : super(null, origin);
2999
3000 Element lookup(SourceString name) => localLookup(name);
3001
3002 Element localLookup(SourceString name) {
3003 Element result = patch.lookupLocalMember(name);
3004 if (result !== null) return result;
3005 return origin.lookupLocalMember(name);
3006 }
3007
3008
3009 Element add(Element newElement) {
3010 throw "Cannot add an element in a class scope";
3011 }
3012
3013 String toString() => 'LocalPatchClassScope($origin,$patch)';
2873 } 3014 }
2874 3015
2875 class TopScope extends Scope { 3016 class TopScope extends Scope {
2876 LibraryElement get library => element; 3017 LibraryElement get library => element;
2877 3018
2878 TopScope(LibraryElement library) : super(null, library); 3019 TopScope(LibraryElement library) : super(null, library);
2879 3020
2880 Element localLookup(SourceString name) => library.find(name); 3021 Element localLookup(SourceString name) => library.find(name);
2881 Element lookup(SourceString name) => localLookup(name); 3022 Element lookup(SourceString name) => localLookup(name);
2882 Element lexicalLookup(SourceString name) => localLookup(name); 3023 Element lexicalLookup(SourceString name) => localLookup(name);
2883 3024
2884 Element add(Element newElement) { 3025 Element add(Element newElement) {
2885 throw "Cannot add an element in the top scope"; 3026 throw "Cannot add an element in the top scope";
2886 } 3027 }
2887 String toString() => '$element'; 3028 String toString() => 'LibraryScope($element)';
2888 } 3029 }
3030
3031 class PatchLibraryScope extends Scope {
3032 LibraryElement get origin => element;
3033 final LibraryElement patch;
3034
3035 PatchLibraryScope(LibraryElement origin, LibraryElement this.patch)
3036 : super(null, origin);
3037
3038 Element localLookup(SourceString name) {
3039 Element result = patch.find(name);
3040 if (result !== null) {
3041 return result;
3042 }
3043 result = origin.find(name);
3044 if (result !== null) {
3045 return result;
3046 }
3047 return result;
3048 }
3049 Element lookup(SourceString name) => localLookup(name);
3050 Element lexicalLookup(SourceString name) => localLookup(name);
3051
3052 Element add(Element newElement) {
3053 throw "Cannot add an element in a patch library scope";
3054 }
3055 String toString() => 'PatchLibraryScope($origin,$patch)';
3056 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698