mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Dependency Scanner] Refactor ModuleDependencies to represent binary-only Swift modules explicitly
This matches the behavior of the current client (`swift-driver`) and reduces ambiguity in how the nodes in the graph are to be treated. Swift dependencies with a textual interface, for example, must be built into a binary module by clients. Swift dependencies without a textual interface, with only a binary module, are to be used directly, without any up-to-date checks. Note, this is distinct from Swift dependencies that have a textual interface, for which we also detect potential pre-build binary module candidates. Those are still reported in the `details` field of textual Swift dependencies as `prebuiltModuleCandidates`.
This commit is contained in:
@@ -34,7 +34,8 @@ class Identifier;
|
||||
|
||||
/// Which kind of module dependencies we are looking for.
|
||||
enum class ModuleDependenciesKind : int8_t {
|
||||
Swift,
|
||||
SwiftTextual,
|
||||
SwiftBinary,
|
||||
// Placeholder dependencies are a kind of dependencies used only by the
|
||||
// dependency scanner. They are swift modules that the scanner will not be
|
||||
// able to locate in its search paths and which are the responsibility of the
|
||||
@@ -68,18 +69,13 @@ class ModuleDependenciesStorageBase {
|
||||
public:
|
||||
const ModuleDependenciesKind dependencyKind;
|
||||
|
||||
ModuleDependenciesStorageBase(ModuleDependenciesKind dependencyKind,
|
||||
const std::string &compiledModulePath)
|
||||
: dependencyKind(dependencyKind),
|
||||
compiledModulePath(compiledModulePath) { }
|
||||
ModuleDependenciesStorageBase(ModuleDependenciesKind dependencyKind)
|
||||
: dependencyKind(dependencyKind) { }
|
||||
|
||||
virtual ModuleDependenciesStorageBase *clone() const = 0;
|
||||
|
||||
virtual ~ModuleDependenciesStorageBase();
|
||||
|
||||
/// The path to the compiled module file.
|
||||
const std::string compiledModulePath;
|
||||
|
||||
/// The set of modules on which this module depends.
|
||||
std::vector<std::string> moduleDependencies;
|
||||
};
|
||||
@@ -87,7 +83,8 @@ public:
|
||||
/// Describes the dependencies of a Swift module.
|
||||
///
|
||||
/// This class is mostly an implementation detail for \c ModuleDependencies.
|
||||
class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
|
||||
class SwiftTextualModuleDependenciesStorage :
|
||||
public ModuleDependenciesStorageBase {
|
||||
public:
|
||||
/// The Swift interface file, if it can be used to generate the module file.
|
||||
const Optional<std::string> swiftInterfaceFile;
|
||||
@@ -122,16 +119,14 @@ public:
|
||||
/// (Clang) modules on which the bridging header depends.
|
||||
std::vector<std::string> bridgingModuleDependencies;
|
||||
|
||||
SwiftModuleDependenciesStorage(
|
||||
const std::string &compiledModulePath,
|
||||
SwiftTextualModuleDependenciesStorage(
|
||||
const Optional<std::string> &swiftInterfaceFile,
|
||||
ArrayRef<std::string> compiledModuleCandidates,
|
||||
ArrayRef<StringRef> buildCommandLine,
|
||||
ArrayRef<StringRef> extraPCMArgs,
|
||||
StringRef contextHash,
|
||||
bool isFramework
|
||||
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Swift,
|
||||
compiledModulePath),
|
||||
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftTextual),
|
||||
swiftInterfaceFile(swiftInterfaceFile),
|
||||
compiledModuleCandidates(compiledModuleCandidates.begin(),
|
||||
compiledModuleCandidates.end()),
|
||||
@@ -140,11 +135,47 @@ public:
|
||||
contextHash(contextHash), isFramework(isFramework) { }
|
||||
|
||||
ModuleDependenciesStorageBase *clone() const override {
|
||||
return new SwiftModuleDependenciesStorage(*this);
|
||||
return new SwiftTextualModuleDependenciesStorage(*this);
|
||||
}
|
||||
|
||||
static bool classof(const ModuleDependenciesStorageBase *base) {
|
||||
return base->dependencyKind == ModuleDependenciesKind::Swift;
|
||||
return base->dependencyKind == ModuleDependenciesKind::SwiftTextual;
|
||||
}
|
||||
};
|
||||
|
||||
/// Describes the dependencies of a pre-built Swift module (with no .swiftinterface).
|
||||
///
|
||||
/// This class is mostly an implementation detail for \c ModuleDependencies.
|
||||
class SwiftBinaryModuleDependencyStorage : public ModuleDependenciesStorageBase {
|
||||
public:
|
||||
SwiftBinaryModuleDependencyStorage(const std::string &compiledModulePath,
|
||||
const std::string &moduleDocPath,
|
||||
const std::string &sourceInfoPath,
|
||||
const bool isFramework)
|
||||
: ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftBinary),
|
||||
compiledModulePath(compiledModulePath),
|
||||
moduleDocPath(moduleDocPath),
|
||||
sourceInfoPath(sourceInfoPath),
|
||||
isFramework(isFramework) {}
|
||||
|
||||
ModuleDependenciesStorageBase *clone() const override {
|
||||
return new SwiftBinaryModuleDependencyStorage(*this);
|
||||
}
|
||||
|
||||
/// The path to the .swiftmodule file.
|
||||
const std::string compiledModulePath;
|
||||
|
||||
/// The path to the .swiftModuleDoc file.
|
||||
const std::string moduleDocPath;
|
||||
|
||||
/// The path to the .swiftSourceInfo file.
|
||||
const std::string sourceInfoPath;
|
||||
|
||||
/// A flag that indicates this dependency is a framework
|
||||
const bool isFramework;
|
||||
|
||||
static bool classof(const ModuleDependenciesStorageBase *base) {
|
||||
return base->dependencyKind == ModuleDependenciesKind::SwiftBinary;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -166,13 +197,11 @@ public:
|
||||
const std::vector<std::string> fileDependencies;
|
||||
|
||||
ClangModuleDependenciesStorage(
|
||||
const std::string &compiledModulePath,
|
||||
const std::string &moduleMapFile,
|
||||
const std::string &contextHash,
|
||||
const std::vector<std::string> &nonPathCommandLine,
|
||||
const std::vector<std::string> &fileDependencies
|
||||
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Clang,
|
||||
compiledModulePath),
|
||||
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Clang),
|
||||
moduleMapFile(moduleMapFile),
|
||||
contextHash(contextHash),
|
||||
nonPathCommandLine(nonPathCommandLine),
|
||||
@@ -190,20 +219,24 @@ public:
|
||||
/// Describes an placeholder Swift module dependency module stub.
|
||||
///
|
||||
/// This class is mostly an implementation detail for \c ModuleDependencies.
|
||||
class PlaceholderSwiftModuleDependencyStorage : public ModuleDependenciesStorageBase {
|
||||
|
||||
class SwiftPlaceholderModuleDependencyStorage : public ModuleDependenciesStorageBase {
|
||||
public:
|
||||
PlaceholderSwiftModuleDependencyStorage(const std::string &compiledModulePath,
|
||||
const std::string &moduleDocPath,
|
||||
const std::string &sourceInfoPath)
|
||||
: ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftPlaceholder,
|
||||
compiledModulePath),
|
||||
SwiftPlaceholderModuleDependencyStorage(const std::string &compiledModulePath,
|
||||
const std::string &moduleDocPath,
|
||||
const std::string &sourceInfoPath)
|
||||
: ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftPlaceholder),
|
||||
compiledModulePath(compiledModulePath),
|
||||
moduleDocPath(moduleDocPath),
|
||||
sourceInfoPath(sourceInfoPath) {}
|
||||
|
||||
ModuleDependenciesStorageBase *clone() const override {
|
||||
return new PlaceholderSwiftModuleDependencyStorage(*this);
|
||||
return new SwiftPlaceholderModuleDependencyStorage(*this);
|
||||
}
|
||||
|
||||
/// The path to the .swiftmodule file.
|
||||
const std::string compiledModulePath;
|
||||
|
||||
/// The path to the .swiftModuleDoc file.
|
||||
const std::string moduleDocPath;
|
||||
|
||||
@@ -248,43 +281,41 @@ public:
|
||||
ArrayRef<StringRef> extraPCMArgs,
|
||||
StringRef contextHash,
|
||||
bool isFramework) {
|
||||
std::string compiledModulePath;
|
||||
return ModuleDependencies(
|
||||
std::make_unique<SwiftModuleDependenciesStorage>(
|
||||
compiledModulePath, swiftInterfaceFile, compiledCandidates, buildCommands,
|
||||
std::make_unique<SwiftTextualModuleDependenciesStorage>(
|
||||
swiftInterfaceFile, compiledCandidates, buildCommands,
|
||||
extraPCMArgs, contextHash, isFramework));
|
||||
}
|
||||
|
||||
/// Describe the module dependencies for a serialized or parsed Swift module.
|
||||
static ModuleDependencies forSwiftModule(
|
||||
const std::string &compiledModulePath, bool isFramework) {
|
||||
static ModuleDependencies forSwiftBinaryModule(
|
||||
const std::string &compiledModulePath,
|
||||
const std::string &moduleDocPath,
|
||||
const std::string &sourceInfoPath,
|
||||
bool isFramework) {
|
||||
return ModuleDependencies(
|
||||
std::make_unique<SwiftModuleDependenciesStorage>(
|
||||
compiledModulePath, None, ArrayRef<std::string>(), ArrayRef<StringRef>(),
|
||||
ArrayRef<StringRef>(), StringRef(), isFramework));
|
||||
std::make_unique<SwiftBinaryModuleDependencyStorage>(
|
||||
compiledModulePath, moduleDocPath, sourceInfoPath, isFramework));
|
||||
}
|
||||
|
||||
/// Describe the main Swift module.
|
||||
static ModuleDependencies forMainSwiftModule(ArrayRef<StringRef> extraPCMArgs) {
|
||||
std::string compiledModulePath;
|
||||
return ModuleDependencies(
|
||||
std::make_unique<SwiftModuleDependenciesStorage>(
|
||||
compiledModulePath, None, ArrayRef<std::string>(),
|
||||
ArrayRef<StringRef>(), extraPCMArgs, StringRef(), false));
|
||||
std::make_unique<SwiftTextualModuleDependenciesStorage>(
|
||||
None, ArrayRef<std::string>(), ArrayRef<StringRef>(),
|
||||
extraPCMArgs, StringRef(), false));
|
||||
}
|
||||
|
||||
/// Describe the module dependencies for a Clang module that can be
|
||||
/// built from a module map and headers.
|
||||
static ModuleDependencies forClangModule(
|
||||
const std::string &compiledModulePath,
|
||||
const std::string &moduleMapFile,
|
||||
const std::string &contextHash,
|
||||
const std::vector<std::string> &nonPathCommandLine,
|
||||
const std::vector<std::string> &fileDependencies) {
|
||||
return ModuleDependencies(
|
||||
std::make_unique<ClangModuleDependenciesStorage>(
|
||||
compiledModulePath, moduleMapFile, contextHash, nonPathCommandLine,
|
||||
fileDependencies));
|
||||
moduleMapFile, contextHash, nonPathCommandLine, fileDependencies));
|
||||
}
|
||||
|
||||
/// Describe a placeholder dependency swift module.
|
||||
@@ -293,38 +324,45 @@ public:
|
||||
const std::string &moduleDocPath,
|
||||
const std::string &sourceInfoPath) {
|
||||
return ModuleDependencies(
|
||||
std::make_unique<PlaceholderSwiftModuleDependencyStorage>(
|
||||
std::make_unique<SwiftPlaceholderModuleDependencyStorage>(
|
||||
compiledModulePath, moduleDocPath, sourceInfoPath));
|
||||
}
|
||||
|
||||
/// Retrieve the path to the compiled module.
|
||||
const std::string getCompiledModulePath() const {
|
||||
return storage->compiledModulePath;
|
||||
}
|
||||
|
||||
/// Retrieve the module-level dependencies.
|
||||
ArrayRef<std::string> getModuleDependencies() const {
|
||||
return storage->moduleDependencies;
|
||||
}
|
||||
|
||||
/// Whether the dependencies are for a Swift module.
|
||||
/// Whether the dependencies are for a Swift module: either Textual, Binary, or Placeholder.
|
||||
bool isSwiftModule() const;
|
||||
|
||||
/// Whether the dependencies are for a textual Swift module.
|
||||
bool isSwiftTextualModule() const;
|
||||
|
||||
/// Whether the dependencies are for a binary Swift module.
|
||||
bool isSwiftBinaryModule() const;
|
||||
|
||||
/// Whether this represents a placeholder module stub
|
||||
bool isPlaceholderSwiftModule() const;
|
||||
bool isSwiftPlaceholderModule() const;
|
||||
|
||||
/// Whether the dependencies are for a Clang module.
|
||||
bool isClangModule() const;
|
||||
|
||||
ModuleDependenciesKind getKind() const {
|
||||
return storage->dependencyKind;
|
||||
}
|
||||
/// Retrieve the dependencies for a Swift module.
|
||||
const SwiftModuleDependenciesStorage *getAsSwiftModule() const;
|
||||
const SwiftTextualModuleDependenciesStorage *getAsSwiftTextualModule() const;
|
||||
|
||||
/// Retrieve the dependencies for a binary Swift module.
|
||||
const SwiftBinaryModuleDependencyStorage *getAsSwiftBinaryModule() const;
|
||||
|
||||
/// Retrieve the dependencies for a Clang module.
|
||||
const ClangModuleDependenciesStorage *getAsClangModule() const;
|
||||
|
||||
/// Retrieve the dependencies for a placeholder dependency module stub.
|
||||
const PlaceholderSwiftModuleDependencyStorage *
|
||||
getAsPlaceholderDependencyModule() const;
|
||||
const SwiftPlaceholderModuleDependencyStorage *
|
||||
getAsPlaceholderDependencyModule() const;
|
||||
|
||||
/// Add a dependency on the given module, if it was not already in the set.
|
||||
void addModuleDependency(StringRef module,
|
||||
@@ -363,11 +401,14 @@ class ModuleDependenciesCache {
|
||||
/// encountered.
|
||||
std::vector<ModuleDependencyID> AllModules;
|
||||
|
||||
/// Dependencies for Swift modules that have already been computed.
|
||||
llvm::StringMap<ModuleDependencies> SwiftModuleDependencies;
|
||||
/// Dependencies for Textual Swift modules that have already been computed.
|
||||
llvm::StringMap<ModuleDependencies> SwiftTextualModuleDependencies;
|
||||
|
||||
/// Dependencies for Swift placeholder dependency modules.
|
||||
llvm::StringMap<ModuleDependencies> PlaceholderSwiftModuleDependencies;
|
||||
/// Dependencies for Binary Swift modules that have already been computed.
|
||||
llvm::StringMap<ModuleDependencies> SwiftBinaryModuleDependencies;
|
||||
|
||||
/// Dependencies for Swift placeholder dependency modules that have already been computed.
|
||||
llvm::StringMap<ModuleDependencies> SwiftPlaceholderModuleDependencies;
|
||||
|
||||
/// Dependencies for Clang modules that have already been computed.
|
||||
llvm::StringMap<ModuleDependencies> ClangModuleDependencies;
|
||||
@@ -429,8 +470,7 @@ public:
|
||||
|
||||
/// Record dependencies for the given module.
|
||||
void recordDependencies(StringRef moduleName,
|
||||
ModuleDependencies dependencies,
|
||||
ModuleDependenciesKind kind);
|
||||
ModuleDependencies dependencies);
|
||||
|
||||
/// Update stored dependencies for the given module.
|
||||
void updateDependencies(ModuleDependencyID moduleID,
|
||||
|
||||
Reference in New Issue
Block a user