@@ -551,24 +551,134 @@ void FrontendSourceFileDepGraphFactory::addAllDefinedDeclsOfAGivenType(
551
551
// MARK: FrontendSourceFileDepGraphFactory - adding collections of used Decls
552
552
// ==============================================================================
553
553
554
+ namespace {
555
+ // / Extracts uses out of a SourceFile
556
+ class UsedDeclEnumerator {
557
+ SourceFile *SF;
558
+ const DependencyTracker &depTracker;
559
+ StringRef swiftDeps;
560
+
561
+ // / Cache these for efficiency
562
+ const DependencyKey sourceFileInterface;
563
+ const DependencyKey sourceFileImplementation;
564
+
565
+ const bool includeIntrafileDeps;
566
+
567
+ function_ref<void (const DependencyKey &, const DependencyKey &)> createDefUse;
568
+
569
+ public:
570
+ UsedDeclEnumerator (
571
+ SourceFile *SF, const DependencyTracker &depTracker, StringRef swiftDeps,
572
+ bool includeIntrafileDeps,
573
+ function_ref<void (const DependencyKey &, const DependencyKey &)>
574
+ createDefUse)
575
+ : SF(SF), depTracker(depTracker), swiftDeps(swiftDeps),
576
+ sourceFileInterface (DependencyKey::createKeyForWholeSourceFile(
577
+ DeclAspect::interface, swiftDeps)),
578
+ sourceFileImplementation(DependencyKey::createKeyForWholeSourceFile(
579
+ DeclAspect::implementation, swiftDeps)),
580
+ includeIntrafileDeps(includeIntrafileDeps), createDefUse(createDefUse) {
581
+ }
582
+
583
+ public:
584
+ void enumerateAllUses () {
585
+ auto &Ctx = SF->getASTContext ();
586
+ std::unordered_set<std::string> holdersOfCascadingMembers;
587
+ Ctx.evaluator .enumerateReferencesInFile (SF, [&](const auto &ref) {
588
+ const auto cascades = ref.cascades ;
589
+ std::string name = ref.name .userFacingName ().str ();
590
+ const auto *nominal = ref.subject ;
591
+ using Kind = evaluator::DependencyCollector::Reference::Kind;
592
+
593
+ switch (ref.kind ) {
594
+ case Kind::Empty:
595
+ case Kind::Tombstone:
596
+ llvm_unreachable (" Cannot enumerate dead reference!" );
597
+ case Kind::TopLevel:
598
+ return enumerateUse<NodeKind::topLevel>(" " , name, cascades);
599
+ case Kind::Dynamic:
600
+ return enumerateUse<NodeKind::dynamicLookup>(" " , name, cascades);
601
+ case Kind::PotentialMember: {
602
+ std::string context = DependencyKey::computeContextForProvidedEntity<
603
+ NodeKind::potentialMember>(nominal);
604
+ appendHolderOfCascadingMembers (holdersOfCascadingMembers, nominal,
605
+ cascades);
606
+ return enumerateUse<NodeKind::potentialMember>(context, " " , cascades);
607
+ }
608
+ case Kind::UsedMember: {
609
+ std::string context =
610
+ DependencyKey::computeContextForProvidedEntity<NodeKind::member>(
611
+ nominal);
612
+ appendHolderOfCascadingMembers (holdersOfCascadingMembers, nominal,
613
+ cascades);
614
+ return enumerateUse<NodeKind::member>(context, name, cascades);
615
+ }
616
+ }
617
+ });
618
+ enumerateExternalUses ();
619
+ enumerateNominalUses (std::move (holdersOfCascadingMembers));
620
+ }
621
+
622
+ private:
623
+ template <NodeKind kind>
624
+ void enumerateUse (StringRef context, StringRef name, bool isCascadingUse) {
625
+ // Assume that what is depended-upon is the interface
626
+ createDefUse (
627
+ DependencyKey (kind, DeclAspect::interface, context.str (), name.str ()),
628
+ isCascadingUse ? sourceFileInterface : sourceFileImplementation);
629
+ }
630
+
631
+ void appendHolderOfCascadingMembers (std::unordered_set<std::string> &holders,
632
+ const NominalTypeDecl *subject,
633
+ bool isCascading) {
634
+ bool isPrivate = subject->isPrivateToEnclosingFile ();
635
+ if (isPrivate && !includeIntrafileDeps)
636
+ return ;
637
+
638
+ std::string context =
639
+ DependencyKey::computeContextForProvidedEntity<NodeKind::nominal>(
640
+ subject);
641
+ if (isCascading) {
642
+ holders.insert (context);
643
+ }
644
+ }
645
+
646
+ void enumerateNominalUses (
647
+ const std::unordered_set<std::string> &&holdersOfCascadingMembers) {
648
+ auto &Ctx = SF->getASTContext ();
649
+ Ctx.evaluator .enumerateReferencesInFile (SF, [&](const auto &ref) {
650
+ const NominalTypeDecl *subject = ref.subject ;
651
+ if (!subject) {
652
+ return ;
653
+ }
654
+
655
+ bool isPrivate = subject->isPrivateToEnclosingFile ();
656
+ if (isPrivate && !includeIntrafileDeps) {
657
+ return ;
658
+ }
659
+
660
+ std::string context =
661
+ DependencyKey::computeContextForProvidedEntity<NodeKind::nominal>(
662
+ subject);
663
+ const bool isCascadingUse = holdersOfCascadingMembers.count (context) != 0 ;
664
+ enumerateUse<NodeKind::nominal>(context, " " , isCascadingUse);
665
+ });
666
+ }
667
+
668
+ void enumerateExternalUses () {
669
+ // external dependencies always cascade
670
+ for (StringRef s : depTracker.getDependencies ())
671
+ enumerateUse<NodeKind::externalDepend>(" " , s, true );
672
+ }
673
+ };
674
+ } // end namespace
675
+
554
676
void FrontendSourceFileDepGraphFactory::addAllUsedDecls () {
555
- const DependencyKey sourceFileInterface =
556
- DependencyKey::createKeyForWholeSourceFile (DeclAspect::interface,
557
- swiftDeps);
558
-
559
- const DependencyKey sourceFileImplementation =
560
- DependencyKey::createKeyForWholeSourceFile (DeclAspect::implementation,
561
- swiftDeps);
562
-
563
- SF->getConfiguredReferencedNameTracker ()->enumerateAllUses (
564
- includePrivateDeps, depTracker,
565
- [&](const fine_grained_dependencies::NodeKind kind, StringRef context,
566
- StringRef name, const bool isCascadingUse) {
567
- addAUsedDecl (DependencyKey (kind, DeclAspect::interface, context.str (),
568
- name.str ()),
569
- isCascadingUse ? sourceFileInterface
570
- : sourceFileImplementation);
571
- });
677
+ UsedDeclEnumerator (SF, depTracker, swiftDeps, includePrivateDeps,
678
+ [&](const DependencyKey &def, const DependencyKey &use) {
679
+ addAUsedDecl (def, use);
680
+ })
681
+ .enumerateAllUses ();
572
682
}
573
683
574
684
// ==============================================================================
0 commit comments