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 |