| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import '../closure.dart'; | |
| 6 import '../common.dart'; | 5 import '../common.dart'; |
| 7 import '../common_elements.dart'; | 6 import '../common_elements.dart'; |
| 8 import '../compiler.dart'; | 7 import '../compiler.dart'; |
| 9 import '../constants/values.dart'; | 8 import '../constants/values.dart'; |
| 10 import '../elements/elements.dart'; | 9 import '../elements/elements.dart' show AbstractFieldElement, Element; |
| 11 import '../elements/entities.dart'; | 10 import '../elements/entities.dart'; |
| 12 import '../elements/names.dart'; | 11 import '../elements/names.dart'; |
| 13 import '../elements/types.dart'; | 12 import '../elements/types.dart'; |
| 14 import '../options.dart'; | 13 import '../options.dart'; |
| 15 import '../world.dart'; | 14 import '../world.dart'; |
| 16 import '../universe/world_builder.dart'; | 15 import '../universe/world_builder.dart'; |
| 17 import '../util/emptyset.dart'; | 16 import '../util/emptyset.dart'; |
| 18 | 17 |
| 19 abstract class MirrorsData { | 18 abstract class MirrorsData { |
| 20 /// True if a call to preserveMetadataMarker has been seen. This means that | 19 /// True if a call to preserveMetadataMarker has been seen. This means that |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed | 138 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed |
| 140 /// annotations. The arguments corresponds to the unions of the corresponding | 139 /// annotations. The arguments corresponds to the unions of the corresponding |
| 141 /// fields of the annotations. | 140 /// fields of the annotations. |
| 142 void registerMirrorUsage( | 141 void registerMirrorUsage( |
| 143 Set<String> symbols, Set<Element> targets, Set<Element> metaTargets); | 142 Set<String> symbols, Set<Element> targets, Set<Element> metaTargets); |
| 144 | 143 |
| 145 /// Called when `const Symbol(name)` is seen. | 144 /// Called when `const Symbol(name)` is seen. |
| 146 void registerConstSymbol(String name); | 145 void registerConstSymbol(String name); |
| 147 | 146 |
| 148 void maybeMarkClosureAsNeededForReflection( | 147 void maybeMarkClosureAsNeededForReflection( |
| 149 ClosureClassElement globalizedElement, | 148 ClassEntity closureClass, FunctionEntity callMethod, Local localFunction); |
| 150 MethodElement callFunction, | |
| 151 LocalFunctionElement function); | |
| 152 | 149 |
| 153 void computeMembersNeededForReflection( | 150 void computeMembersNeededForReflection( |
| 154 ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld); | 151 ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld); |
| 155 } | 152 } |
| 156 | 153 |
| 157 class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder { | 154 abstract class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder { |
| 158 /// True if a call to preserveMetadataMarker has been seen. This means that | 155 /// True if a call to preserveMetadataMarker has been seen. This means that |
| 159 /// metadata must be retained for dart:mirrors to work correctly. | 156 /// metadata must be retained for dart:mirrors to work correctly. |
| 160 bool mustRetainMetadata = false; | 157 bool mustRetainMetadata = false; |
| 161 | 158 |
| 162 /// True if any metadata has been retained. This is slightly different from | 159 /// True if any metadata has been retained. This is slightly different from |
| 163 /// [mustRetainMetadata] and tells us if any metadata was retained. For | 160 /// [mustRetainMetadata] and tells us if any metadata was retained. For |
| 164 /// example, if [mustRetainMetadata] is true but there is no metadata in the | 161 /// example, if [mustRetainMetadata] is true but there is no metadata in the |
| 165 /// program, this variable will stil be false. | 162 /// program, this variable will stil be false. |
| 166 bool hasRetainedMetadata = false; | 163 bool hasRetainedMetadata = false; |
| 167 | 164 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 } | 227 } |
| 231 | 228 |
| 232 /// Should [name] be retained for reflection? | 229 /// Should [name] be retained for reflection? |
| 233 bool shouldRetainName(String name) { | 230 bool shouldRetainName(String name) { |
| 234 if (hasInsufficientMirrorsUsed) return mustPreserveNames; | 231 if (hasInsufficientMirrorsUsed) return mustPreserveNames; |
| 235 if (name == '') return false; | 232 if (name == '') return false; |
| 236 return symbolsUsed.contains(name); | 233 return symbolsUsed.contains(name); |
| 237 } | 234 } |
| 238 | 235 |
| 239 @override | 236 @override |
| 240 bool retainMetadataOfMember(covariant MemberElement element) { | 237 bool retainMetadataOfMember(MemberEntity element) { |
| 241 if (mustRetainMetadata) { | 238 if (mustRetainMetadata) { |
| 242 hasRetainedMetadata = true; | 239 hasRetainedMetadata = true; |
| 243 if (isMemberReferencedFromMirrorSystem(element)) { | 240 if (isMemberReferencedFromMirrorSystem(element)) { |
| 244 _addConstantsForEmission( | 241 _addConstantsForEmission( |
| 245 getMemberMetadata(element, includeParameterMetadata: true)); | 242 getMemberMetadata(element, includeParameterMetadata: true)); |
| 246 return true; | 243 return true; |
| 247 } | 244 } |
| 248 } | 245 } |
| 249 return false; | 246 return false; |
| 250 } | 247 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 Iterable<ConstantValue> constants = getLibraryMetadata(element); | 279 Iterable<ConstantValue> constants = getLibraryMetadata(element); |
| 283 if (addForEmission) { | 280 if (addForEmission) { |
| 284 _addConstantsForEmission(constants); | 281 _addConstantsForEmission(constants); |
| 285 } | 282 } |
| 286 return true; | 283 return true; |
| 287 } | 284 } |
| 288 } | 285 } |
| 289 return false; | 286 return false; |
| 290 } | 287 } |
| 291 | 288 |
| 292 Iterable<ConstantValue> getLibraryMetadata(LibraryElement element) { | 289 Iterable<ConstantValue> getLibraryMetadata(LibraryEntity element) { |
| 293 return _elementEnvironment.getLibraryMetadata(element); | 290 return _elementEnvironment.getLibraryMetadata(element); |
| 294 } | 291 } |
| 295 | 292 |
| 296 Iterable<ConstantValue> getClassMetadata(ClassElement element) { | 293 Iterable<ConstantValue> getClassMetadata(ClassEntity element) { |
| 297 return _elementEnvironment.getClassMetadata(element); | 294 return _elementEnvironment.getClassMetadata(element); |
| 298 } | 295 } |
| 299 | 296 |
| 300 Iterable<ConstantValue> getMemberMetadata(MemberEntity element, | 297 Iterable<ConstantValue> getMemberMetadata(MemberEntity element, |
| 301 {bool includeParameterMetadata}) { | 298 {bool includeParameterMetadata}) { |
| 302 return _elementEnvironment.getMemberMetadata(element, | 299 return _elementEnvironment.getMemberMetadata(element, |
| 303 includeParameterMetadata: includeParameterMetadata); | 300 includeParameterMetadata: includeParameterMetadata); |
| 304 } | 301 } |
| 305 | 302 |
| 306 Iterable<ConstantValue> getTypedefMetadata(TypedefElement element) { | 303 Iterable<ConstantValue> getTypedefMetadata(TypedefEntity element) { |
| 307 return _elementEnvironment.getTypedefMetadata(element); | 304 return _elementEnvironment.getTypedefMetadata(element); |
| 308 } | 305 } |
| 309 | 306 |
| 310 void _addConstantsForEmission(Iterable<ConstantValue> constants) { | 307 void _addConstantsForEmission(Iterable<ConstantValue> constants) { |
| 311 for (ConstantValue constant in constants) { | 308 for (ConstantValue constant in constants) { |
| 312 CodegenWorldBuilder worldBuilder = _compiler.codegenWorldBuilder; | 309 CodegenWorldBuilder worldBuilder = _compiler.codegenWorldBuilder; |
| 313 worldBuilder.addCompileTimeConstantForEmission(constant); | 310 worldBuilder.addCompileTimeConstantForEmission(constant); |
| 314 } | 311 } |
| 315 } | 312 } |
| 316 | 313 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 _typedefMatchesMirrorsMetaTarget(element) || | 459 _typedefMatchesMirrorsMetaTarget(element) || |
| 463 _typedefsInMirrorsUsedTargets.contains(element); | 460 _typedefsInMirrorsUsedTargets.contains(element); |
| 464 } | 461 } |
| 465 | 462 |
| 466 bool _libraryReferencedFromMirrorSystem(LibraryEntity element) { | 463 bool _libraryReferencedFromMirrorSystem(LibraryEntity element) { |
| 467 return hasInsufficientMirrorsUsed || | 464 return hasInsufficientMirrorsUsed || |
| 468 _libraryMatchesMirrorsMetaTarget(element) || | 465 _libraryMatchesMirrorsMetaTarget(element) || |
| 469 librariesInMirrorsUsedTargets.contains(element); | 466 librariesInMirrorsUsedTargets.contains(element); |
| 470 } | 467 } |
| 471 | 468 |
| 472 bool _libraryMatchesMirrorsMetaTarget(LibraryElement element) { | 469 bool _libraryMatchesMirrorsMetaTarget(LibraryEntity element) { |
| 473 if (metaTargetsUsed.isEmpty) return false; | 470 if (metaTargetsUsed.isEmpty) return false; |
| 474 return _matchesMirrorsMetaTarget(getLibraryMetadata(element)); | 471 return _matchesMirrorsMetaTarget(getLibraryMetadata(element)); |
| 475 } | 472 } |
| 476 | 473 |
| 477 bool _classMatchesMirrorsMetaTarget(ClassEntity element) { | 474 bool _classMatchesMirrorsMetaTarget(ClassEntity element) { |
| 478 if (metaTargetsUsed.isEmpty) return false; | 475 if (metaTargetsUsed.isEmpty) return false; |
| 479 return _matchesMirrorsMetaTarget(getClassMetadata(element)); | 476 return _matchesMirrorsMetaTarget(getClassMetadata(element)); |
| 480 } | 477 } |
| 481 | 478 |
| 482 bool _memberMatchesMirrorsMetaTarget(MemberElement element) { | 479 bool _memberMatchesMirrorsMetaTarget(MemberEntity element) { |
| 483 if (metaTargetsUsed.isEmpty) return false; | 480 if (metaTargetsUsed.isEmpty) return false; |
| 484 return _matchesMirrorsMetaTarget( | 481 return _matchesMirrorsMetaTarget( |
| 485 getMemberMetadata(element, includeParameterMetadata: false)); | 482 getMemberMetadata(element, includeParameterMetadata: false)); |
| 486 } | 483 } |
| 487 | 484 |
| 488 bool _typedefMatchesMirrorsMetaTarget(TypedefElement element) { | 485 bool _typedefMatchesMirrorsMetaTarget(TypedefEntity element) { |
| 489 if (metaTargetsUsed.isEmpty) return false; | 486 if (metaTargetsUsed.isEmpty) return false; |
| 490 return _matchesMirrorsMetaTarget(getTypedefMetadata(element)); | 487 return _matchesMirrorsMetaTarget(getTypedefMetadata(element)); |
| 491 } | 488 } |
| 492 | 489 |
| 493 /** | 490 /** |
| 494 * Returns `true` if the element is needed because it has an annotation | 491 * Returns `true` if the element is needed because it has an annotation |
| 495 * of a type that is used as a meta target for reflection. | 492 * of a type that is used as a meta target for reflection. |
| 496 */ | 493 */ |
| 497 bool _matchesMirrorsMetaTarget(Iterable<ConstantValue> constants) { | 494 bool _matchesMirrorsMetaTarget(Iterable<ConstantValue> constants) { |
| 498 if (metaTargetsUsed.isEmpty) return false; | 495 if (metaTargetsUsed.isEmpty) return false; |
| 499 for (ConstantValue constant in constants) { | 496 for (ConstantValue constant in constants) { |
| 500 DartType type = constant.getType(_commonElements); | 497 DartType type = constant.getType(_commonElements); |
| 501 if (type is InterfaceType && metaTargetsUsed.contains(type.element)) | 498 if (type is InterfaceType && metaTargetsUsed.contains(type.element)) |
| 502 return true; | 499 return true; |
| 503 } | 500 } |
| 504 return false; | 501 return false; |
| 505 } | 502 } |
| 506 | 503 |
| 507 void createImmutableSets() { | 504 void createImmutableSets() { |
| 508 _classesNeededForReflection = const ImmutableEmptySet<ClassElement>(); | 505 _classesNeededForReflection = const ImmutableEmptySet<ClassEntity>(); |
| 509 _typedefsNeededForReflection = const ImmutableEmptySet<TypedefElement>(); | 506 _typedefsNeededForReflection = const ImmutableEmptySet<TypedefEntity>(); |
| 510 _membersNeededForReflection = const ImmutableEmptySet<MemberElement>(); | 507 _membersNeededForReflection = const ImmutableEmptySet<MemberEntity>(); |
| 511 _closuresNeededForReflection = | 508 _closuresNeededForReflection = const ImmutableEmptySet<Local>(); |
| 512 const ImmutableEmptySet<LocalFunctionElement>(); | 509 } |
| 510 |
| 511 bool isLibraryInternal(LibraryEntity library) { |
| 512 return library.canonicalUri.scheme == 'dart' && |
| 513 library.canonicalUri.path.startsWith('_'); |
| 514 } |
| 515 |
| 516 /// Whether [cls] is 'injected'. |
| 517 /// |
| 518 /// An injected class is declared in a patch library with no corresponding |
| 519 /// class in the origin library. |
| 520 // TODO(redemption): Detect injected classes from .dill. |
| 521 bool isClassInjected(ClassEntity cls) => false; |
| 522 |
| 523 bool isClassResolved(ClassEntity cls) => true; |
| 524 |
| 525 void forEachConstructor( |
| 526 ClassEntity cls, void f(ConstructorEntity constructor)) { |
| 527 _elementEnvironment.forEachConstructor(cls, f); |
| 528 } |
| 529 |
| 530 void forEachClassMember( |
| 531 ClassEntity cls, void f(MemberEntity member, Name memberName)) { |
| 532 _elementEnvironment.forEachClassMember(cls, |
| 533 (ClassEntity declarer, MemberEntity member) { |
| 534 if (member.isSetter) { |
| 535 f(member, member.memberName.setter); |
| 536 } else { |
| 537 f(member, member.memberName.getter); |
| 538 } |
| 539 }); |
| 513 } | 540 } |
| 514 | 541 |
| 515 /** | 542 /** |
| 516 * Visits all classes and computes whether its members are needed for | 543 * Visits all classes and computes whether its members are needed for |
| 517 * reflection. | 544 * reflection. |
| 518 * | 545 * |
| 519 * We have to precompute this set as we cannot easily answer the need for | 546 * We have to precompute this set as we cannot easily answer the need for |
| 520 * reflection locally when looking at the member: We lack the information by | 547 * reflection locally when looking at the member: We lack the information by |
| 521 * which classes a member is inherited. Called after resolution is complete. | 548 * which classes a member is inherited. Called after resolution is complete. |
| 522 * | 549 * |
| (...skipping 16 matching lines...) Expand all Loading... |
| 539 // Compute a mapping from class to the closures it contains, so we | 566 // Compute a mapping from class to the closures it contains, so we |
| 540 // can include the correct ones when including the class. | 567 // can include the correct ones when including the class. |
| 541 Map<ClassEntity, List<Local>> closureMap = | 568 Map<ClassEntity, List<Local>> closureMap = |
| 542 new Map<ClassEntity, List<Local>>(); | 569 new Map<ClassEntity, List<Local>>(); |
| 543 for (Local closure in worldBuilder.localFunctions) { | 570 for (Local closure in worldBuilder.localFunctions) { |
| 544 closureMap | 571 closureMap |
| 545 .putIfAbsent(closure.memberContext.enclosingClass, () => []) | 572 .putIfAbsent(closure.memberContext.enclosingClass, () => []) |
| 546 .add(closure); | 573 .add(closure); |
| 547 } | 574 } |
| 548 bool foundClosure = false; | 575 bool foundClosure = false; |
| 549 for (ClassElement cls in worldBuilder.directlyInstantiatedClasses) { | 576 for (ClassEntity cls in worldBuilder.directlyInstantiatedClasses) { |
| 550 // Do not process internal classes. | 577 // Do not process internal classes. |
| 551 if (cls.library.isInternalLibrary || cls.isInjected) continue; | 578 if (isLibraryInternal(cls.library) || isClassInjected(cls)) continue; |
| 552 if (isClassReferencedFromMirrorSystem(cls)) { | 579 if (isClassReferencedFromMirrorSystem(cls)) { |
| 553 Set<Name> memberNames = new Set<Name>(); | 580 Set<Name> memberNames = new Set<Name>(); |
| 554 // 1) the class (should be resolved) | 581 // 1) the class (should be resolved) |
| 555 assert(cls.isResolved, failedAt(cls)); | 582 assert(isClassResolved(cls), failedAt(cls)); |
| 556 _classesNeededForReflection.add(cls); | 583 _classesNeededForReflection.add(cls); |
| 557 // 2) its constructors (if resolved) | 584 // 2) its constructors (if resolved) |
| 558 cls.constructors.forEach((Element _constructor) { | 585 forEachConstructor(cls, (ConstructorEntity constructor) { |
| 559 ConstructorElement constructor = _constructor; | |
| 560 if (worldBuilder.isMemberUsed(constructor)) { | 586 if (worldBuilder.isMemberUsed(constructor)) { |
| 561 _membersNeededForReflection.add(constructor); | 587 _membersNeededForReflection.add(constructor); |
| 562 } | 588 } |
| 563 }); | 589 }); |
| 564 // 3) all members, including fields via getter/setters (if resolved) | 590 // 3) all members, including fields via getter/setters (if resolved) |
| 565 cls.forEachClassMember((Member member) { | 591 forEachClassMember(cls, (MemberEntity member, Name memberName) { |
| 566 MemberElement element = member.element; | 592 if (worldBuilder.isMemberUsed(member)) { |
| 567 if (worldBuilder.isMemberUsed(element)) { | 593 memberNames.add(memberName); |
| 568 memberNames.add(member.name); | 594 _membersNeededForReflection.add(member); |
| 569 _membersNeededForReflection.add(element); | |
| 570 element.nestedClosures.forEach((FunctionElement _callFunction) { | |
| 571 SynthesizedCallMethodElementX callFunction = _callFunction; | |
| 572 _membersNeededForReflection.add(callFunction); | |
| 573 _classesNeededForReflection.add(callFunction.closureClass); | |
| 574 }); | |
| 575 } | 595 } |
| 576 }); | 596 }); |
| 577 // 4) all overriding members of subclasses/subtypes (should be resolved) | 597 // 4) all overriding members of subclasses/subtypes (should be resolved) |
| 578 if (closedWorld.hasAnyStrictSubtype(cls)) { | 598 if (closedWorld.hasAnyStrictSubtype(cls)) { |
| 579 closedWorld.forEachStrictSubtypeOf(cls, (ClassEntity _subcls) { | 599 closedWorld.forEachStrictSubtypeOf(cls, (ClassEntity subcls) { |
| 580 ClassElement subcls = _subcls; | 600 forEachClassMember(subcls, (MemberEntity member, Name memberName) { |
| 581 subcls.forEachClassMember((Member member) { | 601 if (memberNames.contains(memberName)) { |
| 582 if (memberNames.contains(member.name)) { | |
| 583 // TODO(20993): find out why this assertion fails. | 602 // TODO(20993): find out why this assertion fails. |
| 584 // assert(worldBuilder.isMemberUsed(member.element), | 603 // assert(worldBuilder.isMemberUsed(member.element), |
| 585 // failedAt(member.element)); | 604 // failedAt(member.element)); |
| 586 if (worldBuilder.isMemberUsed(member.element)) { | 605 if (worldBuilder.isMemberUsed(member)) { |
| 587 _membersNeededForReflection.add(member.element); | 606 _membersNeededForReflection.add(member); |
| 588 } | 607 } |
| 589 } | 608 } |
| 590 }); | 609 }); |
| 591 }); | 610 }); |
| 592 } | 611 } |
| 593 // 5) all its closures | 612 // 5) all its closures |
| 594 List<Local> closures = closureMap[cls]; | 613 List<Local> closures = closureMap[cls]; |
| 595 if (closures != null) { | 614 if (closures != null) { |
| 596 _closuresNeededForReflection.addAll(closures); | 615 _closuresNeededForReflection.addAll(closures); |
| 597 foundClosure = true; | 616 foundClosure = true; |
| 598 } | 617 } |
| 599 } else { | 618 } else { |
| 600 // check members themselves | 619 // check members themselves |
| 601 cls.constructors.forEach((Element _element) { | 620 forEachConstructor(cls, (ConstructorEntity element) { |
| 602 ConstructorElement element = _element; | |
| 603 if (!worldBuilder.isMemberUsed(element)) return; | 621 if (!worldBuilder.isMemberUsed(element)) return; |
| 604 if (_memberReferencedFromMirrorSystem(element)) { | 622 if (_memberReferencedFromMirrorSystem(element)) { |
| 605 _membersNeededForReflection.add(element); | 623 _membersNeededForReflection.add(element); |
| 606 } | 624 } |
| 607 }); | 625 }); |
| 608 cls.forEachClassMember((Member member) { | 626 forEachClassMember(cls, (MemberEntity member, _) { |
| 609 if (!worldBuilder.isMemberUsed(member.element)) return; | 627 if (!worldBuilder.isMemberUsed(member)) return; |
| 610 if (_memberReferencedFromMirrorSystem(member.element)) { | 628 if (_memberReferencedFromMirrorSystem(member)) { |
| 611 _membersNeededForReflection.add(member.element); | 629 _membersNeededForReflection.add(member); |
| 612 } | 630 } |
| 613 }); | 631 }); |
| 614 // Also add in closures. Those might be reflectable is their enclosing | 632 // Also add in closures. Those might be reflectable is their enclosing |
| 615 // member is. | 633 // member is. |
| 616 List<Local> closures = closureMap[cls]; | 634 List<Local> closures = closureMap[cls]; |
| 617 if (closures != null) { | 635 if (closures != null) { |
| 618 for (Local closure in closures) { | 636 for (Local closure in closures) { |
| 619 MemberEntity member = closure.memberContext; | 637 MemberEntity member = closure.memberContext; |
| 620 if (_memberReferencedFromMirrorSystem(member)) { | 638 if (_memberReferencedFromMirrorSystem(member)) { |
| 621 _closuresNeededForReflection.add(closure); | 639 _closuresNeededForReflection.add(closure); |
| 622 foundClosure = true; | 640 foundClosure = true; |
| 623 } | 641 } |
| 624 } | 642 } |
| 625 } | 643 } |
| 626 } | 644 } |
| 627 } | 645 } |
| 628 // We also need top-level non-class elements like static functions and | 646 // We also need top-level non-class elements like static functions and |
| 629 // global fields. We use the resolution queue to decide which elements are | 647 // global fields. We use the resolution queue to decide which elements are |
| 630 // part of the live world. | 648 // part of the live world. |
| 631 for (LibraryElement lib in _compiler.libraryLoader.libraries) { | 649 for (LibraryEntity lib in _elementEnvironment.libraries) { |
| 632 if (lib.isInternalLibrary) continue; | 650 if (isLibraryInternal(lib)) continue; |
| 633 lib.forEachLocalMember((Element element) { | 651 _elementEnvironment.forEachLibraryMember(lib, (MemberEntity member) { |
| 634 if (element.isClass || element.isTypedef) return; | |
| 635 MemberElement member = element; | |
| 636 if (worldBuilder.isMemberUsed(member) && | 652 if (worldBuilder.isMemberUsed(member) && |
| 637 isMemberReferencedFromMirrorSystem(member)) { | 653 isMemberReferencedFromMirrorSystem(member)) { |
| 638 _membersNeededForReflection.add(member); | 654 _membersNeededForReflection.add(member); |
| 639 } | 655 } |
| 640 }); | 656 }); |
| 641 } | 657 } |
| 642 // And closures inside top-level elements that do not have a surrounding | 658 // And closures inside top-level elements that do not have a surrounding |
| 643 // class. These will be in the [:null:] bucket of the [closureMap]. | 659 // class. These will be in the [:null:] bucket of the [closureMap]. |
| 644 if (closureMap.containsKey(null)) { | 660 if (closureMap.containsKey(null)) { |
| 645 for (Local closure in closureMap[null]) { | 661 for (Local closure in closureMap[null]) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 676 for (MemberEntity element in _membersNeededForReflection) { | 692 for (MemberEntity element in _membersNeededForReflection) { |
| 677 symbolsUsed.add(element.name); | 693 symbolsUsed.add(element.name); |
| 678 } | 694 } |
| 679 for (Local element in _closuresNeededForReflection) { | 695 for (Local element in _closuresNeededForReflection) { |
| 680 symbolsUsed.add(element.name); | 696 symbolsUsed.add(element.name); |
| 681 } | 697 } |
| 682 } | 698 } |
| 683 | 699 |
| 684 // TODO(20791): compute closure classes after resolution and move this code to | 700 // TODO(20791): compute closure classes after resolution and move this code to |
| 685 // [computeMembersNeededForReflection]. | 701 // [computeMembersNeededForReflection]. |
| 686 void maybeMarkClosureAsNeededForReflection( | 702 void maybeMarkClosureAsNeededForReflection(ClassEntity closureClass, |
| 687 ClosureClassElement globalizedElement, | 703 FunctionEntity callMethod, Local localFunction) { |
| 688 MethodElement callFunction, | 704 if (!_closuresNeededForReflection.contains(localFunction)) return; |
| 689 LocalFunctionElement function) { | 705 _membersNeededForReflection.add(callMethod); |
| 690 if (!_closuresNeededForReflection.contains(function)) return; | 706 _classesNeededForReflection.add(closureClass); |
| 691 _membersNeededForReflection.add(callFunction); | |
| 692 _classesNeededForReflection.add(globalizedElement); | |
| 693 } | 707 } |
| 694 | 708 |
| 695 /// Called when `const Symbol(name)` is seen. | 709 /// Called when `const Symbol(name)` is seen. |
| 696 void registerConstSymbol(String name) { | 710 void registerConstSymbol(String name) { |
| 697 symbolsUsed.add(name); | 711 symbolsUsed.add(name); |
| 698 if (name.endsWith('=')) { | 712 if (name.endsWith('=')) { |
| 699 symbolsUsed.add(name.substring(0, name.length - 1)); | 713 symbolsUsed.add(name.substring(0, name.length - 1)); |
| 700 } | 714 } |
| 701 } | 715 } |
| 702 } | 716 } |
| OLD | NEW |