Skip to content

Commit b205a9c

Browse files
authored
Merge pull request #62696 from artemcm/BetterScannerDependencyResolution
[Dependency Scanning] Refactor the scanner to resolve unqualified module imports
2 parents be69529 + 12477b7 commit b205a9c

22 files changed

+686
-747
lines changed

include/swift/AST/ASTContext.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -991,18 +991,20 @@ class ASTContext final {
991991

992992
/// Retrieve the module dependencies for the module with the given name.
993993
///
994-
/// \param isUnderlyingClangModule When true, only look for a Clang module
995-
/// with the given name, ignoring any Swift modules.
996-
Optional<ModuleDependencyInfo> getModuleDependencies(
994+
Optional<const ModuleDependencyInfo*> getModuleDependencies(
997995
StringRef moduleName,
998-
bool isUnderlyingClangModule,
999996
ModuleDependenciesCache &cache,
1000997
InterfaceSubContextDelegate &delegate,
1001-
bool cacheOnly = false,
1002998
llvm::Optional<std::pair<std::string, swift::ModuleDependencyKind>> dependencyOf = None);
1003999

1000+
/// Retrieve the module dependencies for the Clang module with the given name.
1001+
Optional<const ModuleDependencyInfo*> getClangModuleDependencies(
1002+
StringRef moduleName,
1003+
ModuleDependenciesCache &cache,
1004+
InterfaceSubContextDelegate &delegate);
1005+
10041006
/// Retrieve the module dependencies for the Swift module with the given name.
1005-
Optional<ModuleDependencyInfo> getSwiftModuleDependencies(
1007+
Optional<const ModuleDependencyInfo*> getSwiftModuleDependencies(
10061008
StringRef moduleName,
10071009
ModuleDependenciesCache &cache,
10081010
InterfaceSubContextDelegate &delegate);

include/swift/AST/ModuleDependencies.h

Lines changed: 85 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -74,29 +74,44 @@ enum class ModuleDependencyKind : int8_t {
7474
LastKind = SwiftPlaceholder + 1
7575
};
7676

77+
using ModuleDependencyID = std::pair<std::string, ModuleDependencyKind>;
78+
using ModuleDependencyIDSetVector =
79+
llvm::SetVector<ModuleDependencyID, std::vector<ModuleDependencyID>,
80+
std::set<ModuleDependencyID>>;
81+
7782
struct ModuleDependencyKindHash {
7883
std::size_t operator()(ModuleDependencyKind k) const {
7984
using UnderlyingType = std::underlying_type<ModuleDependencyKind>::type;
8085
return std::hash<UnderlyingType>{}(static_cast<UnderlyingType>(k));
8186
}
8287
};
8388

89+
namespace dependencies {
90+
std::string createEncodedModuleKindAndName(ModuleDependencyID id);
91+
}
92+
8493
/// Base class for the variant storage of ModuleDependencyInfo.
8594
///
8695
/// This class is mostly an implementation detail for \c ModuleDependencyInfo.
8796
class ModuleDependencyInfoStorageBase {
8897
public:
8998
const ModuleDependencyKind dependencyKind;
9099

91-
ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind)
92-
: dependencyKind(dependencyKind) { }
100+
ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind,
101+
bool resolved = false)
102+
: dependencyKind(dependencyKind), resolved(resolved) { }
93103

94104
virtual ModuleDependencyInfoStorageBase *clone() const = 0;
95105

96106
virtual ~ModuleDependencyInfoStorageBase();
97107

98108
/// The set of modules on which this module depends.
99-
std::vector<std::string> moduleDependencies;
109+
std::vector<std::string> moduleImports;
110+
111+
/// The set of modules on which this module depends, resolved
112+
/// to Module IDs, qualified by module kind: Swift, Clang, etc.
113+
std::vector<ModuleDependencyID> resolvedModuleDependencies;
114+
bool resolved;
100115
};
101116

102117
struct CommonSwiftTextualModuleDependencyDetails {
@@ -400,9 +415,29 @@ class ModuleDependencyInfo {
400415
compiledModulePath, moduleDocPath, sourceInfoPath));
401416
}
402417

403-
/// Retrieve the module-level dependencies.
404-
ArrayRef<std::string> getModuleDependencies() const {
405-
return storage->moduleDependencies;
418+
/// Retrieve the module-level imports.
419+
ArrayRef<std::string> getModuleImports() const {
420+
return storage->moduleImports;
421+
}
422+
423+
/// Retreive the module-level dependencies.
424+
const ArrayRef<ModuleDependencyID> getModuleDependencies() const {
425+
assert(storage->resolved);
426+
return storage->resolvedModuleDependencies;
427+
}
428+
429+
/// Resolve a dependency's set of `imports` with qualified Module IDs
430+
void resolveDependencies(const std::vector<ModuleDependencyID> &dependencyIDs) {
431+
assert(!storage->resolved && "Resolving an already-resolved dependency");
432+
storage->resolved = true;
433+
storage->resolvedModuleDependencies.assign(dependencyIDs.begin(), dependencyIDs.end());
434+
}
435+
436+
bool isResolved() const {
437+
return storage->resolved;
438+
}
439+
void setIsResolved(bool isResolved) {
440+
storage->resolved = isResolved;
406441
}
407442

408443
/// Whether the dependencies are for a Swift module: either Textual, Source, Binary, or Placeholder.
@@ -444,19 +479,22 @@ class ModuleDependencyInfo {
444479
getAsPlaceholderDependencyModule() const;
445480

446481
/// Add a dependency on the given module, if it was not already in the set.
447-
void addModuleDependency(StringRef module,
448-
llvm::StringSet<> *alreadyAddedModules = nullptr);
482+
void addModuleImport(StringRef module,
483+
llvm::StringSet<> *alreadyAddedModules = nullptr);
449484

450485
/// Add a dependency on the given module, if it was not already in the set.
451-
void addModuleDependency(ImportPath::Module module,
452-
llvm::StringSet<> *alreadyAddedModules = nullptr) {
453-
addModuleDependency(module.front().Item.str(), alreadyAddedModules);
486+
void addModuleImport(ImportPath::Module module,
487+
llvm::StringSet<> *alreadyAddedModules = nullptr) {
488+
addModuleImport(module.front().Item.str(), alreadyAddedModules);
454489
}
455490

456-
/// Add all of the module dependencies for the imports in the given source
457-
/// file to the set of module dependencies.
458-
void addModuleDependencies(const SourceFile &sf,
459-
llvm::StringSet<> &alreadyAddedModules);
491+
/// Add all of the module imports in the given source
492+
/// file to the set of module imports.
493+
void addModuleImport(const SourceFile &sf,
494+
llvm::StringSet<> &alreadyAddedModules);
495+
/// Add a kind-qualified module dependency ID to the set of
496+
/// module dependencies.
497+
void addModuleDependency(ModuleDependencyID dependencyID);
460498

461499
/// Get the bridging header.
462500
Optional<std::string> getBridgingHeader() const;
@@ -477,11 +515,9 @@ class ModuleDependencyInfo {
477515
/// Collect a map from a secondary module name to a list of cross-import
478516
/// overlays, when this current module serves as the primary module.
479517
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
480-
collectCrossImportOverlayNames(ASTContext &ctx, StringRef moduleName);
518+
collectCrossImportOverlayNames(ASTContext &ctx, StringRef moduleName) const;
481519
};
482520

483-
using ModuleDependencyID = std::pair<std::string, ModuleDependencyKind>;
484-
using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencyInfo, 1>;
485521
using ModuleNameToDependencyMap = llvm::StringMap<ModuleDependencyInfo>;
486522
using ModuleDependenciesKindMap =
487523
std::unordered_map<ModuleDependencyKind,
@@ -505,6 +541,9 @@ class SwiftDependencyScanningService {
505541
/// encountered.
506542
std::vector<ModuleDependencyID> AllModules;
507543

544+
/// Set containing all of the Clang modules that have already been seen.
545+
llvm::StringSet<> alreadySeenClangModules;
546+
508547
/// Dependencies for modules that have already been computed.
509548
/// This maps a dependency kind to a map of a module's name to a Dependency
510549
/// object
@@ -565,6 +604,10 @@ class SwiftDependencyScanningService {
565604
return *SharedFilesystemCache;
566605
}
567606

607+
llvm::StringSet<>& getAlreadySeenClangModules() {
608+
return getCurrentCache()->alreadySeenClangModules;
609+
}
610+
568611
/// Wrap the filesystem on the specified `CompilerInstance` with a
569612
/// caching `DependencyScanningWorkerFilesystem`
570613
void overlaySharedFilesystemCacheForCompilation(CompilerInstance &Instance);
@@ -587,8 +630,8 @@ class SwiftDependencyScanningService {
587630
}
588631

589632
/// Whether we have cached dependency information for the given module.
590-
bool hasDependencies(StringRef moduleName,
591-
Optional<ModuleDependencyKind> kind) const;
633+
bool hasDependency(StringRef moduleName,
634+
Optional<ModuleDependencyKind> kind) const;
592635

593636
/// Return a pointer to the context-specific cache state of the current
594637
/// scanning action.
@@ -599,22 +642,22 @@ class SwiftDependencyScanningService {
599642
getCacheForScanningContextHash(StringRef scanningContextHash) const;
600643

601644
/// Look for source-based module dependency details
602-
Optional<ModuleDependencyInfo>
645+
Optional<const ModuleDependencyInfo*>
603646
findSourceModuleDependency(StringRef moduleName) const;
604647

605648
/// Look for module dependencies for a module with the given name
606649
///
607650
/// \returns the cached result, or \c None if there is no cached entry.
608-
Optional<ModuleDependencyInfo>
609-
findDependencies(StringRef moduleName,
610-
Optional<ModuleDependencyKind> kind) const;
651+
Optional<const ModuleDependencyInfo*>
652+
findDependency(StringRef moduleName,
653+
Optional<ModuleDependencyKind> kind) const;
611654

612655
/// Record dependencies for the given module.
613-
const ModuleDependencyInfo *recordDependencies(StringRef moduleName,
656+
const ModuleDependencyInfo *recordDependency(StringRef moduleName,
614657
ModuleDependencyInfo dependencies);
615658

616659
/// Update stored dependencies for the given module.
617-
const ModuleDependencyInfo *updateDependencies(ModuleDependencyID moduleID,
660+
const ModuleDependencyInfo *updateDependency(ModuleDependencyID moduleID,
618661
ModuleDependencyInfo dependencies);
619662

620663
/// Reference the list of all module dependencies that are not source-based
@@ -642,23 +685,14 @@ class SwiftDependencyScanningService {
642685
class ModuleDependenciesCache {
643686
private:
644687
SwiftDependencyScanningService &globalScanningService;
645-
646-
/// References to data in `globalCache` for Swift dependencies and
647-
/// `clangModuleDependencies` for Clang dependencies accimulated during
648-
/// the current scanning action.
688+
/// References to data in the `globalScanningService` for module dependencies
649689
ModuleDependenciesKindRefMap ModuleDependenciesMap;
650-
651690
/// Name of the module under scan
652691
std::string mainScanModuleName;
653692
/// The context hash of the current scanning invocation
654693
std::string scannerContextHash;
655-
656-
/// Set containing all of the Clang modules that have already been seen.
657-
llvm::StringSet<> alreadySeenClangModules;
658694
/// The Clang dependency scanner tool
659695
clang::tooling::dependencies::DependencyScanningTool clangScanningTool;
660-
/// Discovered Clang modules are only cached locally.
661-
llvm::StringMap<ModuleDependenciesVector> clangModuleDependencies;
662696

663697
/// Retrieve the dependencies map that corresponds to the given dependency
664698
/// kind.
@@ -667,17 +701,6 @@ class ModuleDependenciesCache {
667701
const llvm::StringMap<const ModuleDependencyInfo *> &
668702
getDependencyReferencesMap(ModuleDependencyKind kind) const;
669703

670-
/// Local cache results lookup, only for modules which were discovered during
671-
/// the current scanner invocation.
672-
bool hasDependenciesLocalOnly(StringRef moduleName,
673-
Optional<ModuleDependencyKind> kind) const;
674-
675-
/// Local cache results lookup, only for modules which were discovered during
676-
/// the current scanner invocation.
677-
Optional<const ModuleDependencyInfo *>
678-
findDependenciesLocalOnly(StringRef moduleName,
679-
Optional<ModuleDependencyKind> kind) const;
680-
681704
public:
682705
ModuleDependenciesCache(SwiftDependencyScanningService &globalScanningService,
683706
std::string mainScanModuleName,
@@ -687,31 +710,36 @@ class ModuleDependenciesCache {
687710

688711
public:
689712
/// Whether we have cached dependency information for the given module.
690-
bool hasDependencies(StringRef moduleName,
691-
Optional<ModuleDependencyKind> kind) const;
713+
bool hasDependency(StringRef moduleName,
714+
Optional<ModuleDependencyKind> kind) const;
692715

693716
/// Produce a reference to the Clang scanner tool associated with this cache
694717
clang::tooling::dependencies::DependencyScanningTool& getClangScannerTool() {
695718
return clangScanningTool;
696719
}
697720
llvm::StringSet<>& getAlreadySeenClangModules() {
698-
return alreadySeenClangModules;
721+
return globalScanningService.getAlreadySeenClangModules();
699722
}
700723

701724
/// Look for module dependencies for a module with the given name
702725
///
703726
/// \returns the cached result, or \c None if there is no cached entry.
704-
Optional<ModuleDependencyInfo>
705-
findDependencies(StringRef moduleName,
706-
Optional<ModuleDependencyKind> kind) const;
727+
Optional<const ModuleDependencyInfo*>
728+
findDependency(StringRef moduleName,
729+
Optional<ModuleDependencyKind> kind) const;
707730

708731
/// Record dependencies for the given module.
709-
void recordDependencies(StringRef moduleName,
710-
ModuleDependencyInfo dependencies);
732+
void recordDependency(StringRef moduleName,
733+
ModuleDependencyInfo dependencies);
711734

712735
/// Update stored dependencies for the given module.
713-
void updateDependencies(ModuleDependencyID moduleID,
714-
ModuleDependencyInfo dependencies);
736+
void updateDependency(ModuleDependencyID moduleID,
737+
ModuleDependencyInfo dependencies);
738+
739+
/// Resolve a dependency module's set of imports
740+
/// to a kind-qualified set of module IDs.
741+
void resolveDependencyImports(ModuleDependencyID moduleID,
742+
const std::vector<ModuleDependencyID> &dependencyIDs);
715743

716744
const std::vector<ModuleDependencyID> &getAllSourceModules() const {
717745
return globalScanningService.getAllSourceModules();

include/swift/AST/ModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ class ModuleLoader {
321321

322322
/// Retrieve the dependencies for the given, named module, or \c None
323323
/// if no such module exists.
324-
virtual Optional<ModuleDependencyInfo> getModuleDependencies(
324+
virtual Optional<const ModuleDependencyInfo*> getModuleDependencies(
325325
StringRef moduleName,
326326
ModuleDependenciesCache &cache,
327327
InterfaceSubContextDelegate &delegate) = 0;

include/swift/ClangImporter/ClangImporter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ class ClangImporter final : public ClangModuleLoader {
423423
ModuleDependenciesCache &cache,
424424
const clang::tooling::dependencies::FullDependenciesResult &clangDependencies);
425425

426-
Optional<ModuleDependencyInfo> getModuleDependencies(
426+
Optional<const ModuleDependencyInfo*> getModuleDependencies(
427427
StringRef moduleName, ModuleDependenciesCache &cache,
428428
InterfaceSubContextDelegate &delegate) override;
429429

0 commit comments

Comments
 (0)