@@ -241,8 +241,10 @@ bool fine_grained_dependencies::withReferenceDependencies(
241
241
const DependencyTracker &depTracker, StringRef outputPath,
242
242
bool alsoEmitDotFile,
243
243
llvm::function_ref<bool (SourceFileDepGraph &&)> cont) {
244
- if (MSF.dyn_cast <ModuleDecl *>()) {
245
- llvm_unreachable (" Cannot construct dependency graph for modules!" );
244
+ if (auto *MD = MSF.dyn_cast <ModuleDecl *>()) {
245
+ SourceFileDepGraph g =
246
+ ModuleDepGraphFactory (MD, alsoEmitDotFile).construct ();
247
+ return cont (std::move (g));
246
248
} else {
247
249
auto *SF = MSF.get <SourceFile *>();
248
250
SourceFileDepGraph g = FrontendSourceFileDepGraphFactory (
@@ -632,3 +634,75 @@ FrontendSourceFileDepGraphFactory::getFingerprintIfAny(const Decl *d) {
632
634
}
633
635
return None;
634
636
}
637
+
638
+ // ==============================================================================
639
+ // MARK: ModuleDepGraphFactory
640
+ // ==============================================================================
641
+
642
+ ModuleDepGraphFactory::ModuleDepGraphFactory (ModuleDecl *Mod, bool emitDot)
643
+ : AbstractSourceFileDepGraphFactory(
644
+ /* include private*/ true , Mod->getASTContext ().hadError(),
645
+ Mod->getNameStr(), "0xBADBEEF", emitDot, Mod->getASTContext().Diags),
646
+ Mod(Mod) {}
647
+
648
+ void ModuleDepGraphFactory::addAllDefinedDecls () {
649
+ // TODO: express the multiple provides and depends streams with variadic
650
+ // templates
651
+
652
+ // Many kinds of Decls become top-level depends.
653
+
654
+ SmallVector<Decl *, 32 > TopLevelDecls;
655
+ Mod->getTopLevelDecls (TopLevelDecls);
656
+ DeclFinder declFinder (TopLevelDecls, includePrivateDeps,
657
+ [this ](VisibleDeclConsumer &consumer) {
658
+ return Mod->lookupClassMembers ({}, consumer);
659
+ });
660
+
661
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(
662
+ declFinder.precedenceGroups );
663
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(
664
+ declFinder.memberOperatorDecls );
665
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(declFinder.operators );
666
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(declFinder.topNominals );
667
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(declFinder.topValues );
668
+ addAllDefinedDeclsOfAGivenType<NodeKind::nominal>(declFinder.allNominals );
669
+ addAllDefinedDeclsOfAGivenType<NodeKind::potentialMember>(
670
+ declFinder.potentialMemberHolders );
671
+ addAllDefinedDeclsOfAGivenType<NodeKind::member>(
672
+ declFinder.valuesInExtensions );
673
+ addAllDefinedDeclsOfAGivenType<NodeKind::dynamicLookup>(
674
+ declFinder.classMembers );
675
+ }
676
+
677
+ // / Given an array of Decls or pairs of them in \p declsOrPairs
678
+ // / create node pairs for context and name
679
+ template <NodeKind kind, typename ContentsT>
680
+ void ModuleDepGraphFactory::addAllDefinedDeclsOfAGivenType (
681
+ std::vector<ContentsT> &contentsVec) {
682
+ for (const auto &declOrPair : contentsVec) {
683
+ Optional<std::string> fp = getFingerprintIfAny (declOrPair);
684
+ addADefinedDecl (
685
+ DependencyKey::createForProvidedEntityInterface<kind>(declOrPair),
686
+ fp ? StringRef (fp.getValue ()) : Optional<StringRef>());
687
+ }
688
+ }
689
+
690
+ // ==============================================================================
691
+ // MARK: ModuleDepGraphFactory - adding individual defined Decls
692
+ // ==============================================================================
693
+
694
+ // / At present, only \c NominalTypeDecls have (body) fingerprints
695
+ Optional<std::string> ModuleDepGraphFactory::getFingerprintIfAny (
696
+ std::pair<const NominalTypeDecl *, const ValueDecl *>) {
697
+ return None;
698
+ }
699
+ Optional<std::string>
700
+ ModuleDepGraphFactory::getFingerprintIfAny (const Decl *d) {
701
+ if (const auto *idc = dyn_cast<IterableDeclContext>(d)) {
702
+ auto result = idc->getBodyFingerprint ();
703
+ assert ((!result || !result->empty ()) &&
704
+ " Fingerprint should never be empty" );
705
+ return result;
706
+ }
707
+ return None;
708
+ }
0 commit comments