| 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 |