Skip to content

Commit e08b782

Browse files
committed
[Dependency Scanning] Consider '-swift-module-file' inputs when looking for dependencies
Previously this flag was only used to pass explicit dependencies to compilation tasks. This change adds support for the dependency scanner to also consider these inputs when resolving dependencies. Resolves swiftlang/swift-driver#1951
1 parent f3fa225 commit e08b782

File tree

8 files changed

+77
-24
lines changed

8 files changed

+77
-24
lines changed

include/swift/AST/SearchPathOptions.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -518,11 +518,8 @@ class SearchPathOptions {
518518
std::string ExplicitSwiftModuleMapPath;
519519

520520
/// Module inputs specified with -swift-module-input,
521-
/// <ModuleName, Path to .swiftmodule file>
522-
std::vector<std::pair<std::string, std::string>> ExplicitSwiftModuleInputs;
523-
524-
/// A map of placeholder Swift module dependency information.
525-
std::string PlaceholderDependencyModuleMap;
521+
/// ModuleName: Path to .swiftmodule file
522+
llvm::StringMap<std::string> ExplicitSwiftModuleInputs;
526523

527524
/// A file containing a list of protocols whose conformances require const value extraction.
528525
std::string ConstGatherProtocolListFilePath;

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
176176
create(ASTContext &ctx,
177177
DependencyTracker *tracker, ModuleLoadingMode loadMode,
178178
StringRef ExplicitSwiftModuleMap,
179-
const std::vector<std::pair<std::string, std::string>> &ExplicitSwiftModuleInputs,
179+
const llvm::StringMap<std::string> &ExplicitSwiftModuleInputs,
180180
bool IgnoreSwiftSourceInfoFile);
181181

182182
/// Append visible module names to \p names. Note that names are possibly
@@ -224,8 +224,7 @@ class ExplicitCASModuleLoader : public SerializedModuleLoaderBase {
224224
create(ASTContext &ctx, llvm::cas::ObjectStore &CAS,
225225
llvm::cas::ActionCache &cache, DependencyTracker *tracker,
226226
ModuleLoadingMode loadMode, StringRef ExplicitSwiftModuleMap,
227-
const std::vector<std::pair<std::string, std::string>>
228-
&ExplicitSwiftModuleInputs,
227+
const llvm::StringMap<std::string> &ExplicitSwiftModuleInputs,
229228
bool IgnoreSwiftSourceInfoFile);
230229

231230
/// Append visible module names to \p names. Note that names are possibly

include/swift/Serialization/ScanningLoaders.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ class SwiftModuleScanner : public SerializedModuleLoaderBase {
6666
bool SkipBuildingInterface, bool IsFramework,
6767
bool IsTestableDependencyLookup) override;
6868

69+
bool canImportModule(ImportPath::Module named, SourceLoc loc,
70+
ModuleVersionInfo *versionInfo,
71+
bool isTestableImport) override;
72+
6973
virtual void collectVisibleTopLevelModuleNames(
7074
SmallVectorImpl<Identifier> &names) const override {
7175
llvm_unreachable("Not used");
@@ -80,6 +84,9 @@ class SwiftModuleScanner : public SerializedModuleLoaderBase {
8084
/// Clang-specific (-Xcc) command-line flags to include on
8185
/// Swift module compilation commands
8286
std::vector<std::string> swiftModuleClangCC1CommandLineArgs;
87+
/// Module inputs specified with -swift-module-input,
88+
/// <ModuleName, Path to .swiftmodule file>
89+
llvm::StringMap<std::string> explicitSwiftModuleInputs;
8390

8491
/// Constituents of a result of a given Swift module query,
8592
/// reset at the end of every query.
@@ -91,12 +98,14 @@ class SwiftModuleScanner : public SerializedModuleLoaderBase {
9198
ASTContext &ctx, ModuleLoadingMode LoadMode,
9299
InterfaceSubContextDelegate &astDelegate, StringRef moduleOutputPath,
93100
StringRef sdkModuleOutputPath,
94-
std::vector<std::string> swiftModuleClangCC1CommandLineArgs)
101+
std::vector<std::string> swiftModuleClangCC1CommandLineArgs,
102+
llvm::StringMap<std::string> &explicitSwiftModuleInputs)
95103
: SerializedModuleLoaderBase(ctx, nullptr, LoadMode,
96104
/*IgnoreSwiftSourceInfoFile=*/true),
97105
astDelegate(astDelegate), moduleOutputPath(moduleOutputPath),
98106
sdkModuleOutputPath(sdkModuleOutputPath),
99-
swiftModuleClangCC1CommandLineArgs(swiftModuleClangCC1CommandLineArgs) {
107+
swiftModuleClangCC1CommandLineArgs(swiftModuleClangCC1CommandLineArgs),
108+
explicitSwiftModuleInputs(explicitSwiftModuleInputs) {
100109
}
101110

102111
/// Perform a filesystem search for a Swift module with a given name

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
294294
*workerASTContext,
295295
workerCompilerInvocation->getSearchPathOptions().ModuleLoadMode,
296296
*scanningASTDelegate, moduleOutputPath, sdkModuleOutputPath,
297-
swiftModuleClangCC1CommandLineArgs);
297+
swiftModuleClangCC1CommandLineArgs,
298+
workerCompilerInvocation->getSearchPathOptions().ExplicitSwiftModuleInputs);
298299
}
299300

300301
SwiftModuleScannerQueryResult

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,7 +2297,7 @@ static void ParseSymbolGraphArgs(symbolgraphgen::SymbolGraphOptions &Opts,
22972297

22982298
static bool validateSwiftModuleFileArgumentAndAdd(const std::string &swiftModuleArgument,
22992299
DiagnosticEngine &Diags,
2300-
std::vector<std::pair<std::string, std::string>> &ExplicitSwiftModuleInputs) {
2300+
llvm::StringMap<std::string> &ExplicitSwiftModuleInputs) {
23012301
std::size_t foundDelimeterPos = swiftModuleArgument.find_first_of("=");
23022302
if (foundDelimeterPos == std::string::npos) {
23032303
Diags.diagnose(SourceLoc(), diag::error_swift_module_file_requires_delimeter,
@@ -2310,7 +2310,7 @@ static bool validateSwiftModuleFileArgumentAndAdd(const std::string &swiftModule
23102310
Diags.diagnose(SourceLoc(), diag::error_bad_module_name, moduleName, false);
23112311
return true;
23122312
}
2313-
ExplicitSwiftModuleInputs.emplace_back(std::make_pair(moduleName, modulePath));
2313+
ExplicitSwiftModuleInputs.insert(std::make_pair(moduleName, modulePath));
23142314
return false;
23152315
}
23162316

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,11 +2246,10 @@ struct ExplicitSwiftModuleLoader::Implementation {
22462246
}
22472247

22482248
void addCommandLineExplicitInputs(
2249-
const std::vector<std::pair<std::string, std::string>>
2250-
&commandLineExplicitInputs) {
2249+
const llvm::StringMap<std::string> &commandLineExplicitInputs) {
22512250
for (const auto &moduleInput : commandLineExplicitInputs) {
2252-
ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {}, {});
2253-
ExplicitModuleMap.try_emplace(moduleInput.first, std::move(entry));
2251+
ExplicitSwiftModuleInputInfo entry(moduleInput.getValue(), {}, {}, {});
2252+
ExplicitModuleMap.try_emplace(moduleInput.first(), std::move(entry));
22542253
}
22552254
}
22562255
};
@@ -2422,7 +2421,7 @@ std::unique_ptr<ExplicitSwiftModuleLoader>
24222421
ExplicitSwiftModuleLoader::create(ASTContext &ctx,
24232422
DependencyTracker *tracker, ModuleLoadingMode loadMode,
24242423
StringRef ExplicitSwiftModuleMap,
2425-
const std::vector<std::pair<std::string, std::string>> &ExplicitSwiftModuleInputs,
2424+
const llvm::StringMap<std::string> &ExplicitSwiftModuleInputs,
24262425
bool IgnoreSwiftSourceInfoFile) {
24272426
auto result = std::unique_ptr<ExplicitSwiftModuleLoader>(
24282427
new ExplicitSwiftModuleLoader(ctx, tracker, loadMode,
@@ -2536,11 +2535,10 @@ struct ExplicitCASModuleLoader::Implementation {
25362535
}
25372536

25382537
void addCommandLineExplicitInputs(
2539-
const std::vector<std::pair<std::string, std::string>>
2540-
&commandLineExplicitInputs) {
2538+
const llvm::StringMap<std::string> &commandLineExplicitInputs) {
25412539
for (const auto &moduleInput : commandLineExplicitInputs) {
2542-
ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {}, {});
2543-
ExplicitModuleMap.try_emplace(moduleInput.first, std::move(entry));
2540+
ExplicitSwiftModuleInputInfo entry(moduleInput.getValue(), {}, {}, {});
2541+
ExplicitModuleMap.try_emplace(moduleInput.getKey(), std::move(entry));
25442542
}
25452543
}
25462544

@@ -2777,8 +2775,7 @@ std::unique_ptr<ExplicitCASModuleLoader> ExplicitCASModuleLoader::create(
27772775
ASTContext &ctx, llvm::cas::ObjectStore &CAS, llvm::cas::ActionCache &cache,
27782776
DependencyTracker *tracker, ModuleLoadingMode loadMode,
27792777
StringRef ExplicitSwiftModuleMap,
2780-
const std::vector<std::pair<std::string, std::string>>
2781-
&ExplicitSwiftModuleInputs,
2778+
const llvm::StringMap<std::string> &ExplicitSwiftModuleInputs,
27822779
bool IgnoreSwiftSourceInfoFile) {
27832780
auto result =
27842781
std::unique_ptr<ExplicitCASModuleLoader>(new ExplicitCASModuleLoader(

lib/Serialization/ScanningLoaders.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,30 @@ std::error_code SwiftModuleScanner::findModuleFilesInDirectory(
8383
return dependencyInfo.getError();
8484
}
8585

86+
bool SwiftModuleScanner::canImportModule(
87+
ImportPath::Module path, SourceLoc loc, ModuleVersionInfo *versionInfo,
88+
bool isTestableDependencyLookup) {
89+
if (path.hasSubmodule())
90+
return false;
91+
92+
// Check explicitly-provided Swift modules with '-swift-module-file'
93+
ImportPath::Element mID = path.front();
94+
auto it =
95+
explicitSwiftModuleInputs.find(Ctx.getRealModuleName(mID.Item).str());
96+
if (it != explicitSwiftModuleInputs.end()) {
97+
auto dependencyInfo = scanBinaryModuleFile(
98+
mID.Item, it->getValue(), /* isFramework */ false,
99+
isTestableDependencyLookup, /* isCandidateForTextualModule */ false);
100+
if (dependencyInfo) {
101+
this->foundDependencyInfo = std::move(dependencyInfo.get());
102+
return true;
103+
}
104+
}
105+
106+
return SerializedModuleLoaderBase::canImportModule(
107+
path, loc, versionInfo, isTestableDependencyLookup);
108+
}
109+
86110
static std::vector<std::string> getCompiledCandidates(ASTContext &ctx,
87111
StringRef moduleName,
88112
StringRef interfacePath) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/module-cache)
3+
// RUN: %empty-directory(%t/Inputs/Foo.swiftmodule)
4+
// RUN: split-file %s %t
5+
6+
// Step 1: build swift interface and swift module side by side
7+
// RUN: %target-swift-frontend -emit-module %t/Foo.swift -emit-module-path %t/Inputs/Foo.swiftmodule/%target-swiftmodule-name -module-name Foo
8+
9+
// Step 2: scan dependency should give us the binary module we specify with 'swift-module-file'
10+
// RUN: %target-swift-frontend -scan-dependencies %t/test.swift -o %t/deps.json -scanner-module-validation -swift-module-file=Foo=%t/Inputs/Foo.swiftmodule/%target-swiftmodule-name
11+
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=CHECK-INPUT
12+
// CHECK-INPUT: "swiftPrebuiltExternal": "Foo"
13+
14+
// Step 3: verify that the usual invalid module candidate diagnostics apply
15+
// RUN: echo "Not Really a module" > %t/Inputs/Foo.swiftmodule/%target-swiftmodule-name
16+
// RUN: %target-swift-frontend -scan-dependencies %t/test.swift -o %t/deps.json -scanner-module-validation -swift-module-file=Foo=%t/Inputs/Foo.swiftmodule/%target-swiftmodule-name -diagnostic-style llvm 2>&1 | %FileCheck %s -check-prefix=CHECK-INVALID-MODULE-DIAG
17+
// CHECK-INVALID-MODULE-DIAG: error: unable to resolve Swift module dependency to a compatible module: 'Foo'
18+
// CHECK-INVALID-MODULE-DIAG: note: found incompatible module '{{.*}}': malformed
19+
20+
//--- Foo.swift
21+
public func foo() {}
22+
23+
//--- test.swift
24+
#if canImport(Foo)
25+
import Foo
26+
#endif

0 commit comments

Comments
 (0)