mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Fast dependency scanning for Swift
Implement a new "fast" dependency scanning option, `-scan-dependencies`, in the Swift frontend that determines all of the source file and module dependencies for a given set of Swift sources. It covers four forms of modules: 1) Swift (serialized) module files, by reading the module header 2) Swift interface files, by parsing the source code to find imports 3) Swift source modules, by parsing the source code to find imports 4) Clang modules, using Clang's fast dependency scanning tool A single `-scan-dependencies` operation maps out the full dependency graph for the given Swift source files, including all of the Swift and Clang modules that may need to be built, such that all of the work can be scheduled up front by the Swift driver or any other build system that understands this option. The dependency graph is emitted as JSON, which can be consumed by these other tools.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include "ModuleFile.h"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/DiagnosticsSema.h"
|
||||
#include "swift/AST/ModuleDependencies.h"
|
||||
#include "swift/Basic/Defer.h"
|
||||
#include "swift/Basic/FileTypes.h"
|
||||
#include "swift/Basic/Platform.h"
|
||||
@@ -346,6 +347,46 @@ std::error_code SerializedModuleLoaderBase::openModuleFile(
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
llvm::ErrorOr<ModuleDependencies> SerializedModuleLoaderBase::scanModuleFile(
|
||||
Twine modulePath) {
|
||||
// Open the module file
|
||||
auto &fs = *Ctx.SourceMgr.getFileSystem();
|
||||
auto moduleBuf = fs.getBufferForFile(modulePath);
|
||||
if (!moduleBuf)
|
||||
return moduleBuf.getError();
|
||||
|
||||
// Load the module file without validation.
|
||||
std::unique_ptr<ModuleFile> loadedModuleFile;
|
||||
bool isFramework = false;
|
||||
serialization::ValidationInfo loadInfo =
|
||||
ModuleFile::load(modulePath.str(),
|
||||
std::move(moduleBuf.get()),
|
||||
nullptr,
|
||||
nullptr,
|
||||
isFramework, loadedModuleFile,
|
||||
nullptr);
|
||||
|
||||
// Map the set of dependencies over to the "module dependencies".
|
||||
auto dependencies = ModuleDependencies::forSwiftModule(modulePath.str());
|
||||
llvm::StringSet<> addedModuleNames;
|
||||
for (const auto &dependency : loadedModuleFile->getDependencies()) {
|
||||
// FIXME: Record header dependency?
|
||||
if (dependency.isHeader())
|
||||
continue;
|
||||
|
||||
// Find the top-level module name.
|
||||
auto modulePathStr = dependency.getPrettyPrintedPath();
|
||||
StringRef moduleName = modulePathStr;
|
||||
auto dotPos = moduleName.find('.');
|
||||
if (dotPos != std::string::npos)
|
||||
moduleName = moduleName.slice(0, dotPos);
|
||||
|
||||
dependencies.addModuleDependency(moduleName, addedModuleNames);
|
||||
}
|
||||
|
||||
return std::move(dependencies);
|
||||
}
|
||||
|
||||
std::error_code SerializedModuleLoader::findModuleFilesInDirectory(
|
||||
AccessPathElem ModuleID,
|
||||
const SerializedModuleBaseName &BaseName,
|
||||
|
||||
Reference in New Issue
Block a user