[Dependency Scanning] Refactor Swift Scanner loader to be standalone

- 'SwiftModuleScanner' will now be owned directly by the 'ModuleDependencyScanningWorker' and will contain all the necessary custom logic, instead of being instantiated by the module interface loader for each query
- Moves ownership over module output path and sdk module output path directly into the scanning worker, instead of the cache
This commit is contained in:
Artem Chikin
2025-06-18 16:38:32 -07:00
parent 5eb85acad5
commit 68883a1014
16 changed files with 447 additions and 539 deletions

View File

@@ -543,106 +543,6 @@ SerializedModuleLoaderBase::resolveMacroPlugin(const ExternalMacroPlugin &macro,
entry.executablePath.str()};
}
llvm::ErrorOr<ModuleDependencyInfo>
SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework,
bool isTestableImport,
bool isCandidateForTextualModule) {
const std::string moduleDocPath;
const std::string sourceInfoPath;
// Read and valid module.
auto moduleBuf = Ctx.SourceMgr.getFileSystem()->getBufferForFile(modulePath);
if (!moduleBuf)
return moduleBuf.getError();
std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile;
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
"", "", std::move(moduleBuf.get()), nullptr, nullptr, isFramework,
isRequiredOSSAModules(), Ctx.LangOpts.SDKName,
Ctx.SearchPathOpts.DeserializedPathRecoverer, loadedModuleFile);
if (Ctx.SearchPathOpts.ScannerModuleValidation) {
// If failed to load, just ignore and return do not found.
if (auto loadFailureReason = invalidModuleReason(loadInfo.status)) {
// If no textual interface was found, then for this dependency
// scanning query this was *the* module discovered, which means
// it would be helpful to let the user know why the scanner
// was not able to use it because the scan will ultimately fail to
// resolve this dependency due to this incompatibility.
if (!isCandidateForTextualModule)
Ctx.Diags.diagnose(SourceLoc(), diag::dependency_scan_module_incompatible,
modulePath.str(), loadFailureReason.value());
if (Ctx.LangOpts.EnableModuleLoadingRemarks)
Ctx.Diags.diagnose(SourceLoc(), diag::dependency_scan_skip_module_invalid,
modulePath.str(), loadFailureReason.value());
return std::make_error_code(std::errc::no_such_file_or_directory);
}
if (isTestableImport && !loadedModuleFile->isTestable()) {
Ctx.Diags.diagnose(SourceLoc(), diag::skip_module_not_testable,
modulePath.str());
return std::make_error_code(std::errc::no_such_file_or_directory);
}
}
// Some transitive dependencies of binary modules are not required to be
// imported during normal builds.
// TODO: This is worth revisiting for debugger purposes where
// loading the module is optional, and implementation-only imports
// from modules with testing enabled where the dependency is
// optional.
auto binaryModuleImports =
getImportsOfModule(*loadedModuleFile, ModuleLoadingBehavior::Required,
Ctx.LangOpts.PackageName, isTestableImport);
// Lookup optional imports of this module also
auto binaryModuleOptionalImports =
getImportsOfModule(*loadedModuleFile, ModuleLoadingBehavior::Optional,
Ctx.LangOpts.PackageName, isTestableImport);
std::vector<LinkLibrary> linkLibraries;
{
linkLibraries.reserve(loadedModuleFile->getLinkLibraries().size());
llvm::copy(loadedModuleFile->getLinkLibraries(),
std::back_inserter(linkLibraries));
if (loadedModuleFile->isFramework())
linkLibraries.emplace_back(loadedModuleFile->getName(),
LibraryKind::Framework,
loadedModuleFile->isStaticLibrary());
}
// Attempt to resolve the module's defining .swiftinterface path
std::string definingModulePath =
loadedModuleFile->resolveModuleDefiningFilePath(
Ctx.SearchPathOpts.getSDKPath());
std::string userModuleVer =
loadedModuleFile->getUserModuleVersion().getAsString();
std::vector<serialization::SearchPath> serializedSearchPaths;
llvm::copy(loadedModuleFile->getSearchPaths(), std::back_inserter(serializedSearchPaths));
// Map the set of dependencies over to the "module dependencies".
auto dependencies = ModuleDependencyInfo::forSwiftBinaryModule(
modulePath.str(), moduleDocPath, sourceInfoPath,
binaryModuleImports->moduleImports,
binaryModuleOptionalImports->moduleImports, linkLibraries, serializedSearchPaths,
binaryModuleImports->headerImport, definingModulePath, isFramework,
loadedModuleFile->isStaticLibrary(),
/*module-cache-key*/ "", userModuleVer);
for (auto &macro : loadedModuleFile->getExternalMacros()) {
auto deps =
resolveMacroPlugin(macro, loadedModuleFile->getModulePackageName());
if (!deps)
continue;
dependencies.addMacroDependency(macro.ModuleName, deps->LibraryPath,
deps->ExecutablePath);
}
return std::move(dependencies);
}
std::error_code ImplicitSerializedModuleLoader::findModuleFilesInDirectory(
ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName,
SmallVectorImpl<char> *ModuleInterfacePath,