From 6d59868a1d4506dad7b247bc49ca984a445944a2 Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Thu, 16 Feb 2023 14:52:21 -0800 Subject: [PATCH] [Dependency Scanning] Detect candidate files for `.private` interface files also --- lib/Frontend/ModuleInterfaceLoader.cpp | 18 ++++++++++--- .../private_interface_candidate_module.swift | 27 +++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 test/ScanDependencies/private_interface_candidate_module.swift diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp index f674d76cc06a7..6e397b16611e7 100644 --- a/lib/Frontend/ModuleInterfaceLoader.cpp +++ b/lib/Frontend/ModuleInterfaceLoader.cpp @@ -1185,12 +1185,22 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory( } std::vector -ModuleInterfaceCheckerImpl::getCompiledModuleCandidatesForInterface( - StringRef moduleName, StringRef interfacePath) { +ModuleInterfaceCheckerImpl::getCompiledModuleCandidatesForInterface(StringRef moduleName, StringRef interfacePath) { // Derive .swiftmodule path from the .swiftinterface path. + auto interfaceExt = file_types::getExtension(file_types::TY_SwiftModuleInterfaceFile); auto newExt = file_types::getExtension(file_types::TY_SwiftModuleFile); - llvm::SmallString<32> modulePath = interfacePath; - llvm::sys::path::replace_extension(modulePath, newExt); + llvm::SmallString<32> modulePath; + + // When looking up the module for a private interface, strip the '.private.' section of the base name + if (interfacePath.endswith(".private." + interfaceExt.str())) { + auto newBaseName = llvm::sys::path::stem(llvm::sys::path::stem(interfacePath)); + modulePath = llvm::sys::path::parent_path(interfacePath); + llvm::sys::path::append(modulePath, newBaseName + "." + newExt.str()); + } else { + modulePath = interfacePath; + llvm::sys::path::replace_extension(modulePath, newExt); + } + ModuleInterfaceLoaderImpl Impl(Ctx, modulePath, interfacePath, moduleName, CacheDir, PrebuiltCacheDir, BackupInterfaceDir, SourceLoc(), Opts, diff --git a/test/ScanDependencies/private_interface_candidate_module.swift b/test/ScanDependencies/private_interface_candidate_module.swift new file mode 100644 index 0000000000000..f99a6d1fb9c96 --- /dev/null +++ b/test/ScanDependencies/private_interface_candidate_module.swift @@ -0,0 +1,27 @@ +// REQUIRES: objc_interop +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/clang-module-cache +// RUN: mkdir -p %t/Frameworks +// RUN: mkdir -p %t/Frameworks/E.framework/ +// RUN: mkdir -p %t/Frameworks/E.framework/Modules +// RUN: mkdir -p %t/Frameworks/E.framework/Modules/E.swiftmodule + +// Copy over the interface +// RUN: cp %S/Inputs/Swift/E.swiftinterface %t/Frameworks/E.framework/Modules/E.swiftmodule/%module-target-triple.private.swiftinterface +// RUN: cp %S/Inputs/Swift/E.swiftinterface %t/Frameworks/E.framework/Modules/E.swiftmodule/%module-target-triple.swiftinterface + +// Build a dependency into a binary module +// RUN: echo "public func foo() {}" >> %t/foo.swift +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Frameworks/E.framework/Modules/E.swiftmodule/%module-target-triple.swiftmodule -module-cache-path %t.module-cache %t/foo.swift -module-name E + +// Run the scan +// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -F %t/Frameworks/ -sdk %t +// RUN: %FileCheck %s < %t/deps.json + +import E + +// Ensure the private interface is the canonical one +// CHECK: "moduleInterfacePath": {{.*}}{{/|\\}}E.framework{{/|\\}}Modules{{/|\\}}E.swiftmodule{{/|\\}}{{.*}}.private.swiftinterface +// Ensure the adjacent binary module is a candidate +// CHECK: "compiledModuleCandidates": [ +// CHECK-NEXT: {{.*}}{{/|\\}}E.framework{{/|\\}}Modules{{/|\\}}E.swiftmodule{{/|\\}}{{.*}}.swiftmodule