| OLD | NEW | 
|---|
| 1 // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 /// Mixins that implement convenience methods on [Element] subclasses. | 5 /// Mixins that implement convenience methods on [Element] subclasses. | 
| 6 | 6 | 
| 7 library elements.common; | 7 library elements.common; | 
| 8 | 8 | 
| 9 import '../common/names.dart' show | 9 import '../common/names.dart' show Names, Uris; | 
| 10     Names, | 10 import '../core_types.dart' show CoreClasses; | 
| 11     Uris; | 11 import '../dart_types.dart' show DartType, InterfaceType, FunctionType; | 
| 12 import '../core_types.dart' show | 12 import '../util/util.dart' show Link; | 
| 13     CoreClasses; |  | 
| 14 import '../dart_types.dart' show |  | 
| 15     DartType, |  | 
| 16     InterfaceType, |  | 
| 17     FunctionType; |  | 
| 18 import '../util/util.dart' show |  | 
| 19     Link; |  | 
| 20 | 13 | 
| 21 import 'elements.dart'; | 14 import 'elements.dart'; | 
| 22 | 15 | 
| 23 abstract class ElementCommon implements Element { | 16 abstract class ElementCommon implements Element { | 
| 24   @override | 17   @override | 
| 25   bool get isLibrary => kind == ElementKind.LIBRARY; | 18   bool get isLibrary => kind == ElementKind.LIBRARY; | 
| 26 | 19 | 
| 27   @override | 20   @override | 
| 28   bool get isCompilationUnit => kind == ElementKind.COMPILATION_UNIT; | 21   bool get isCompilationUnit => kind == ElementKind.COMPILATION_UNIT; | 
| 29 | 22 | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 45   @override | 38   @override | 
| 46   bool get isAccessor => isGetter || isSetter; | 39   bool get isAccessor => isGetter || isSetter; | 
| 47 | 40 | 
| 48   @override | 41   @override | 
| 49   bool get isGetter => kind == ElementKind.GETTER; | 42   bool get isGetter => kind == ElementKind.GETTER; | 
| 50 | 43 | 
| 51   @override | 44   @override | 
| 52   bool get isSetter => kind == ElementKind.SETTER; | 45   bool get isSetter => kind == ElementKind.SETTER; | 
| 53 | 46 | 
| 54   @override | 47   @override | 
| 55   bool get isConstructor => isGenerativeConstructor ||  isFactoryConstructor; | 48   bool get isConstructor => isGenerativeConstructor || isFactoryConstructor; | 
| 56 | 49 | 
| 57   @override | 50   @override | 
| 58   bool get isGenerativeConstructor => | 51   bool get isGenerativeConstructor => | 
| 59       kind == ElementKind.GENERATIVE_CONSTRUCTOR; | 52       kind == ElementKind.GENERATIVE_CONSTRUCTOR; | 
| 60 | 53 | 
| 61   @override | 54   @override | 
| 62   bool get isGenerativeConstructorBody => | 55   bool get isGenerativeConstructorBody => | 
| 63       kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY; | 56       kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY; | 
| 64 | 57 | 
| 65   bool get isFactoryConstructor => | 58   bool get isFactoryConstructor => kind == ElementKind.FACTORY_CONSTRUCTOR; | 
| 66       kind == ElementKind.FACTORY_CONSTRUCTOR; |  | 
| 67 | 59 | 
| 68   @override | 60   @override | 
| 69   bool get isVariable => kind == ElementKind.VARIABLE; | 61   bool get isVariable => kind == ElementKind.VARIABLE; | 
| 70 | 62 | 
| 71   @override | 63   @override | 
| 72   bool get isField => kind == ElementKind.FIELD; | 64   bool get isField => kind == ElementKind.FIELD; | 
| 73 | 65 | 
| 74   @override | 66   @override | 
| 75   bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD; | 67   bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD; | 
| 76 | 68 | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 171 } | 163 } | 
| 172 | 164 | 
| 173 abstract class CompilationUnitElementCommon implements CompilationUnitElement { | 165 abstract class CompilationUnitElementCommon implements CompilationUnitElement { | 
| 174   int compareTo(CompilationUnitElement other) { | 166   int compareTo(CompilationUnitElement other) { | 
| 175     if (this == other) return 0; | 167     if (this == other) return 0; | 
| 176     return '${script.readableUri}'.compareTo('${other.script.readableUri}'); | 168     return '${script.readableUri}'.compareTo('${other.script.readableUri}'); | 
| 177   } | 169   } | 
| 178 } | 170 } | 
| 179 | 171 | 
| 180 abstract class ClassElementCommon implements ClassElement { | 172 abstract class ClassElementCommon implements ClassElement { | 
| 181 |  | 
| 182   @override | 173   @override | 
| 183   Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes; | 174   Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes; | 
| 184 | 175 | 
| 185   @override | 176   @override | 
| 186   int get hierarchyDepth => allSupertypesAndSelf.maxDepth; | 177   int get hierarchyDepth => allSupertypesAndSelf.maxDepth; | 
| 187 | 178 | 
| 188   @override | 179   @override | 
| 189   InterfaceType asInstanceOf(ClassElement cls) { | 180   InterfaceType asInstanceOf(ClassElement cls) { | 
| 190     if (cls == this) return thisType; | 181     if (cls == this) return thisType; | 
| 191     return allSupertypesAndSelf.asInstanceOf(cls); | 182     return allSupertypesAndSelf.asInstanceOf(cls); | 
| 192   } | 183   } | 
| 193 | 184 | 
| 194   @override | 185   @override | 
| 195   ConstructorElement lookupConstructor(String name) { | 186   ConstructorElement lookupConstructor(String name) { | 
| 196     Element result = localLookup(name); | 187     Element result = localLookup(name); | 
| 197     return result != null && result.isConstructor ? result : null; | 188     return result != null && result.isConstructor ? result : null; | 
| 198   } | 189   } | 
| 199 | 190 | 
| 200 |  | 
| 201   /** | 191   /** | 
| 202    * Find the first member in the class chain with the given [memberName]. | 192    * Find the first member in the class chain with the given [memberName]. | 
| 203    * | 193    * | 
| 204    * This method is NOT to be used for resolving | 194    * This method is NOT to be used for resolving | 
| 205    * unqualified sends because it does not implement the scoping | 195    * unqualified sends because it does not implement the scoping | 
| 206    * rules, where library scope comes before superclass scope. | 196    * rules, where library scope comes before superclass scope. | 
| 207    * | 197    * | 
| 208    * When called on the implementation element both members declared in the | 198    * When called on the implementation element both members declared in the | 
| 209    * origin and the patch class are returned. | 199    * origin and the patch class are returned. | 
| 210    */ | 200    */ | 
| 211   Element lookupByName(Name memberName) { | 201   Element lookupByName(Name memberName) { | 
| 212     return internalLookupByName(memberName, isSuperLookup: false); | 202     return internalLookupByName(memberName, isSuperLookup: false); | 
| 213   } | 203   } | 
| 214 | 204 | 
| 215   Element lookupSuperByName(Name memberName) { | 205   Element lookupSuperByName(Name memberName) { | 
| 216     return internalLookupByName(memberName, isSuperLookup: true); | 206     return internalLookupByName(memberName, isSuperLookup: true); | 
| 217   } | 207   } | 
| 218 | 208 | 
| 219   Element internalLookupByName(Name memberName, {bool isSuperLookup}) { | 209   Element internalLookupByName(Name memberName, {bool isSuperLookup}) { | 
| 220     String name = memberName.text; | 210     String name = memberName.text; | 
| 221     bool isPrivate = memberName.isPrivate; | 211     bool isPrivate = memberName.isPrivate; | 
| 222     LibraryElement library = memberName.library; | 212     LibraryElement library = memberName.library; | 
| 223     for (ClassElement current = isSuperLookup ? superclass : this; | 213     for (ClassElement current = isSuperLookup ? superclass : this; | 
| 224          current != null; | 214         current != null; | 
| 225          current = current.superclass) { | 215         current = current.superclass) { | 
| 226       Element member = current.lookupLocalMember(name); | 216       Element member = current.lookupLocalMember(name); | 
| 227       if (member == null && current.isPatched) { | 217       if (member == null && current.isPatched) { | 
| 228         // Doing lookups on selectors is done after resolution, so it | 218         // Doing lookups on selectors is done after resolution, so it | 
| 229         // is safe to look in the patch class. | 219         // is safe to look in the patch class. | 
| 230         member = current.patch.lookupLocalMember(name); | 220         member = current.patch.lookupLocalMember(name); | 
| 231       } | 221       } | 
| 232       if (member == null) continue; | 222       if (member == null) continue; | 
| 233       // Private members from a different library are not visible. | 223       // Private members from a different library are not visible. | 
| 234       if (isPrivate && !identical(library, member.library)) continue; | 224       if (isPrivate && !identical(library, member.library)) continue; | 
| 235       // Static members are not inherited. | 225       // Static members are not inherited. | 
| 236       if (member.isStatic && !identical(this, current)) continue; | 226       if (member.isStatic && !identical(this, current)) continue; | 
| 237       // If we find an abstract field we have to make sure that it has | 227       // If we find an abstract field we have to make sure that it has | 
| 238       // the getter or setter part we're actually looking | 228       // the getter or setter part we're actually looking | 
| 239       // for. Otherwise, we continue up the superclass chain. | 229       // for. Otherwise, we continue up the superclass chain. | 
| 240       if (member.isAbstractField) { | 230       if (member.isAbstractField) { | 
| 241         AbstractFieldElement field = member; | 231         AbstractFieldElement field = member; | 
| 242         FunctionElement getter = field.getter; | 232         FunctionElement getter = field.getter; | 
| 243         FunctionElement setter = field.setter; | 233         FunctionElement setter = field.setter; | 
| 244         if (memberName.isSetter) { | 234         if (memberName.isSetter) { | 
| 245           // Abstract members can be defined in a super class. | 235           // Abstract members can be defined in a super class. | 
| 246           if (setter != null && !setter.isAbstract) { | 236           if (setter != null && !setter.isAbstract) { | 
| 247             return setter; | 237             return setter; | 
| 248           } | 238           } | 
| 249         } else { | 239         } else { | 
| 250           if (getter != null && !getter.isAbstract) { | 240           if (getter != null && !getter.isAbstract) { | 
| 251             return getter; | 241             return getter; | 
| 252           } | 242           } | 
| 253         } | 243         } | 
| 254       // Abstract members can be defined in a super class. | 244         // Abstract members can be defined in a super class. | 
| 255       } else if (!member.isAbstract) { | 245       } else if (!member.isAbstract) { | 
| 256         return member; | 246         return member; | 
| 257       } | 247       } | 
| 258     } | 248     } | 
| 259     return null; | 249     return null; | 
| 260   } | 250   } | 
| 261 | 251 | 
| 262   /** | 252   /** | 
| 263    * Find the first member in the class chain with the given | 253    * Find the first member in the class chain with the given | 
| 264    * [memberName]. This method is NOT to be used for resolving | 254    * [memberName]. This method is NOT to be used for resolving | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 288   @override | 278   @override | 
| 289   Element lookupSuperMember(String memberName) { | 279   Element lookupSuperMember(String memberName) { | 
| 290     return lookupSuperMemberInLibrary(memberName, library); | 280     return lookupSuperMemberInLibrary(memberName, library); | 
| 291   } | 281   } | 
| 292 | 282 | 
| 293   /** | 283   /** | 
| 294    * Lookup super members for the class that is accessible in [library]. | 284    * Lookup super members for the class that is accessible in [library]. | 
| 295    * This will ignore constructors. | 285    * This will ignore constructors. | 
| 296    */ | 286    */ | 
| 297   @override | 287   @override | 
| 298   Element lookupSuperMemberInLibrary(String memberName, | 288   Element lookupSuperMemberInLibrary( | 
| 299                                      LibraryElement library) { | 289       String memberName, LibraryElement library) { | 
| 300     bool isPrivate = Name.isPrivateName(memberName); | 290     bool isPrivate = Name.isPrivateName(memberName); | 
| 301     for (ClassElement s = superclass; s != null; s = s.superclass) { | 291     for (ClassElement s = superclass; s != null; s = s.superclass) { | 
| 302       // Private members from a different library are not visible. | 292       // Private members from a different library are not visible. | 
| 303       if (isPrivate && !identical(library, s.library)) continue; | 293       if (isPrivate && !identical(library, s.library)) continue; | 
| 304       Element e = s.lookupLocalMember(memberName); | 294       Element e = s.lookupLocalMember(memberName); | 
| 305       if (e == null) continue; | 295       if (e == null) continue; | 
| 306       // Static members are not inherited. | 296       // Static members are not inherited. | 
| 307       if (e.isStatic) continue; | 297       if (e.isStatic) continue; | 
| 308       return e; | 298       return e; | 
| 309     } | 299     } | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 325    * | 315    * | 
| 326    * The enclosing class is passed to the callback. This is useful when | 316    * The enclosing class is passed to the callback. This is useful when | 
| 327    * [includeSuperAndInjectedMembers] is [:true:]. | 317    * [includeSuperAndInjectedMembers] is [:true:]. | 
| 328    * | 318    * | 
| 329    * When called on an implementation element both the members in the origin | 319    * When called on an implementation element both the members in the origin | 
| 330    * and patch class are included. | 320    * and patch class are included. | 
| 331    */ | 321    */ | 
| 332   // TODO(johnniwinther): Clean up lookup to get rid of the include predicates. | 322   // TODO(johnniwinther): Clean up lookup to get rid of the include predicates. | 
| 333   @override | 323   @override | 
| 334   void forEachMember(void f(ClassElement enclosingClass, Element member), | 324   void forEachMember(void f(ClassElement enclosingClass, Element member), | 
| 335                      {includeBackendMembers: false, | 325       {includeBackendMembers: false, includeSuperAndInjectedMembers: false}) { | 
| 336                       includeSuperAndInjectedMembers: false}) { |  | 
| 337     bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch; | 326     bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch; | 
| 338     ClassElement classElement = declaration; | 327     ClassElement classElement = declaration; | 
| 339     do { | 328     do { | 
| 340       // Iterate through the members in textual order, which requires | 329       // Iterate through the members in textual order, which requires | 
| 341       // to reverse the data structure [localMembers] we created. | 330       // to reverse the data structure [localMembers] we created. | 
| 342       // Textual order may be important for certain operations, for | 331       // Textual order may be important for certain operations, for | 
| 343       // example when emitting the initializers of fields. | 332       // example when emitting the initializers of fields. | 
| 344       classElement.forEachLocalMember((e) => f(classElement, e)); | 333       classElement.forEachLocalMember((e) => f(classElement, e)); | 
| 345       if (includeBackendMembers) { | 334       if (includeBackendMembers) { | 
| 346         classElement.forEachBackendMember((e) => f(classElement, e)); | 335         classElement.forEachBackendMember((e) => f(classElement, e)); | 
| 347       } | 336       } | 
| 348       if (includeInjectedMembers) { | 337       if (includeInjectedMembers) { | 
| 349         if (classElement.isPatched) { | 338         if (classElement.isPatched) { | 
| 350           classElement.patch.forEachLocalMember((e) { | 339           classElement.patch.forEachLocalMember((e) { | 
| 351             if (!e.isPatch) f(classElement, e); | 340             if (!e.isPatch) f(classElement, e); | 
| 352           }); | 341           }); | 
| 353         } | 342         } | 
| 354       } | 343       } | 
| 355       classElement = includeSuperAndInjectedMembers | 344       classElement = | 
| 356           ? classElement.superclass | 345           includeSuperAndInjectedMembers ? classElement.superclass : null; | 
| 357           : null; |  | 
| 358     } while (classElement != null); | 346     } while (classElement != null); | 
| 359   } | 347   } | 
| 360 | 348 | 
| 361   /** | 349   /** | 
| 362    * Runs through all instance-field members of this class. | 350    * Runs through all instance-field members of this class. | 
| 363    * | 351    * | 
| 364    * The enclosing class is passed to the callback. This is useful when | 352    * The enclosing class is passed to the callback. This is useful when | 
| 365    * [includeSuperAndInjectedMembers] is [:true:]. | 353    * [includeSuperAndInjectedMembers] is [:true:]. | 
| 366    * | 354    * | 
| 367    * When called on the implementation element both the fields declared in the | 355    * When called on the implementation element both the fields declared in the | 
| 368    * origin and in the patch are included. | 356    * origin and in the patch are included. | 
| 369    */ | 357    */ | 
| 370   @override | 358   @override | 
| 371   void forEachInstanceField(void f(ClassElement enclosingClass, | 359   void forEachInstanceField( | 
| 372                                    FieldElement field), | 360       void f(ClassElement enclosingClass, FieldElement field), | 
| 373                             {bool includeSuperAndInjectedMembers: false}) { | 361       {bool includeSuperAndInjectedMembers: false}) { | 
| 374     // Filters so that [f] is only invoked with instance fields. | 362     // Filters so that [f] is only invoked with instance fields. | 
| 375     void fieldFilter(ClassElement enclosingClass, Element member) { | 363     void fieldFilter(ClassElement enclosingClass, Element member) { | 
| 376       if (member.isInstanceMember && member.kind == ElementKind.FIELD) { | 364       if (member.isInstanceMember && member.kind == ElementKind.FIELD) { | 
| 377         f(enclosingClass, member); | 365         f(enclosingClass, member); | 
| 378       } | 366       } | 
| 379     } | 367     } | 
| 380 | 368 | 
| 381     forEachMember(fieldFilter, | 369     forEachMember(fieldFilter, | 
| 382         includeSuperAndInjectedMembers: includeSuperAndInjectedMembers); | 370         includeSuperAndInjectedMembers: includeSuperAndInjectedMembers); | 
| 383   } | 371   } | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 426   } | 414   } | 
| 427 | 415 | 
| 428   @override | 416   @override | 
| 429   bool implementsInterface(ClassElement intrface) { | 417   bool implementsInterface(ClassElement intrface) { | 
| 430     return this != intrface && | 418     return this != intrface && | 
| 431         allSupertypesAndSelf.asInstanceOf(intrface) != null; | 419         allSupertypesAndSelf.asInstanceOf(intrface) != null; | 
| 432   } | 420   } | 
| 433 | 421 | 
| 434   @override | 422   @override | 
| 435   bool implementsFunction(CoreClasses coreClasses) { | 423   bool implementsFunction(CoreClasses coreClasses) { | 
| 436     return asInstanceOf(coreClasses.functionClass) != null || | 424     return asInstanceOf(coreClasses.functionClass) != null || callType != null; | 
| 437         callType != null; |  | 
| 438   } | 425   } | 
| 439 | 426 | 
| 440   @override | 427   @override | 
| 441   bool isSubclassOf(ClassElement cls) { | 428   bool isSubclassOf(ClassElement cls) { | 
| 442     // Use [declaration] for both [this] and [cls], because | 429     // Use [declaration] for both [this] and [cls], because | 
| 443     // declaration classes hold the superclass hierarchy. | 430     // declaration classes hold the superclass hierarchy. | 
| 444     cls = cls.declaration; | 431     cls = cls.declaration; | 
| 445     for (ClassElement s = declaration; s != null; s = s.superclass) { | 432     for (ClassElement s = declaration; s != null; s = s.superclass) { | 
| 446       if (identical(s, cls)) return true; | 433       if (identical(s, cls)) return true; | 
| 447     } | 434     } | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 491     if (optionalParametersAreNamed) { | 478     if (optionalParametersAreNamed) { | 
| 492       if (!signature.optionalParametersAreNamed) { | 479       if (!signature.optionalParametersAreNamed) { | 
| 493         return requiredParameterCount == signature.parameterCount; | 480         return requiredParameterCount == signature.parameterCount; | 
| 494       } | 481       } | 
| 495       // If both signatures have named parameters, then they must have | 482       // If both signatures have named parameters, then they must have | 
| 496       // the same number of required parameters, and the names in | 483       // the same number of required parameters, and the names in | 
| 497       // [signature] must all be in [:this:]. | 484       // [signature] must all be in [:this:]. | 
| 498       if (requiredParameterCount != signature.requiredParameterCount) { | 485       if (requiredParameterCount != signature.requiredParameterCount) { | 
| 499         return false; | 486         return false; | 
| 500       } | 487       } | 
| 501       Set<String> names = optionalParameters.map( | 488       Set<String> names = | 
| 502           (Element element) => element.name).toSet(); | 489           optionalParameters.map((Element element) => element.name).toSet(); | 
| 503       for (Element namedParameter in signature.optionalParameters) { | 490       for (Element namedParameter in signature.optionalParameters) { | 
| 504         if (!names.contains(namedParameter.name)) { | 491         if (!names.contains(namedParameter.name)) { | 
| 505           return false; | 492           return false; | 
| 506         } | 493         } | 
| 507       } | 494       } | 
| 508     } else { | 495     } else { | 
| 509       if (signature.optionalParametersAreNamed) return false; | 496       if (signature.optionalParametersAreNamed) return false; | 
| 510       // There must be at least as many arguments as in the other signature, but | 497       // There must be at least as many arguments as in the other signature, but | 
| 511       // this signature must not have more required parameters.  Having more | 498       // this signature must not have more required parameters.  Having more | 
| 512       // optional parameters is not a problem, they simply are never provided | 499       // optional parameters is not a problem, they simply are never provided | 
| 513       // by call sites of a call to a method with the other signature. | 500       // by call sites of a call to a method with the other signature. | 
| 514       int otherTotalCount = signature.parameterCount; | 501       int otherTotalCount = signature.parameterCount; | 
| 515       return requiredParameterCount <= otherTotalCount | 502       return requiredParameterCount <= otherTotalCount && | 
| 516           && parameterCount >= otherTotalCount; | 503           parameterCount >= otherTotalCount; | 
| 517     } | 504     } | 
| 518     return true; | 505     return true; | 
| 519   } | 506   } | 
| 520 } | 507 } | 
| 521 | 508 | 
| 522 abstract class MixinApplicationElementCommon | 509 abstract class MixinApplicationElementCommon | 
| 523     implements MixinApplicationElement { | 510     implements MixinApplicationElement { | 
| 524   Link<ConstructorElement> get constructors { | 511   Link<ConstructorElement> get constructors { | 
| 525     throw new UnsupportedError('Unimplemented $this.constructors'); | 512     throw new UnsupportedError('Unimplemented $this.constructors'); | 
| 526   } | 513   } | 
| 527 | 514 | 
| 528   FunctionElement _lookupLocalConstructor(String name) { | 515   FunctionElement _lookupLocalConstructor(String name) { | 
| 529     for (Link<Element> link = constructors; | 516     for (Link<Element> link = constructors; !link.isEmpty; link = link.tail) { | 
| 530          !link.isEmpty; |  | 
| 531          link = link.tail) { |  | 
| 532       if (link.head.name == name) return link.head; | 517       if (link.head.name == name) return link.head; | 
| 533     } | 518     } | 
| 534     return null; | 519     return null; | 
| 535   } | 520   } | 
| 536 | 521 | 
| 537   @override | 522   @override | 
| 538   Element localLookup(String name) { | 523   Element localLookup(String name) { | 
| 539     Element constructor = _lookupLocalConstructor(name); | 524     Element constructor = _lookupLocalConstructor(name); | 
| 540     if (constructor != null) return constructor; | 525     if (constructor != null) return constructor; | 
| 541     if (mixin == null) return null; | 526     if (mixin == null) return null; | 
| 542     Element mixedInElement = mixin.localLookup(name); | 527     Element mixedInElement = mixin.localLookup(name); | 
| 543     if (mixedInElement == null) return null; | 528     if (mixedInElement == null) return null; | 
| 544     return mixedInElement.isInstanceMember ? mixedInElement : null; | 529     return mixedInElement.isInstanceMember ? mixedInElement : null; | 
| 545   } | 530   } | 
| 546 | 531 | 
| 547   @override | 532   @override | 
| 548   void forEachLocalMember(void f(Element member)) { | 533   void forEachLocalMember(void f(Element member)) { | 
| 549     constructors.forEach(f); | 534     constructors.forEach(f); | 
| 550     if (mixin != null) mixin.forEachLocalMember((Element mixedInElement) { | 535     if (mixin != null) | 
|  | 536       mixin.forEachLocalMember((Element mixedInElement) { | 
| 551       if (mixedInElement.isInstanceMember) f(mixedInElement); | 537       if (mixedInElement.isInstanceMember) f(mixedInElement); | 
| 552     }); | 538     }); | 
| 553   } | 539   } | 
| 554 } | 540 } | 
| OLD | NEW | 
|---|