Skip to content

Commit e0eeb63

Browse files
committed
[Dependency Scanning] Teach dependency scanner to resolve optional dependencies of a module
1 parent 0067c41 commit e0eeb63

File tree

6 files changed

+53
-20
lines changed

6 files changed

+53
-20
lines changed

include/swift/AST/ASTContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,7 @@ class ASTContext final {
10321032
StringRef moduleName,
10331033
ModuleDependenciesCache &cache,
10341034
InterfaceSubContextDelegate &delegate,
1035+
bool optionalDependencyLookup = false,
10351036
llvm::Optional<std::pair<std::string, swift::ModuleDependencyKind>> dependencyOf = None);
10361037

10371038
/// Retrieve the module dependencies for the Clang module with the given name.

include/swift/AST/ModuleDependencies.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ class ModuleDependencyInfoStorageBase {
109109
/// The set of modules on which this module depends.
110110
std::vector<std::string> moduleImports;
111111

112+
/// The set of modules which constitute optional module
113+
/// dependencies for this module, such as `@_implementationOnly`
114+
/// or `internal` imports.
115+
std::vector<std::string> optionalModuleImports;
116+
112117
/// The set of modules on which this module depends, resolved
113118
/// to Module IDs, qualified by module kind: Swift, Clang, etc.
114119
std::vector<ModuleDependencyID> resolvedModuleDependencies;
@@ -425,6 +430,11 @@ class ModuleDependencyInfo {
425430
return storage->moduleImports;
426431
}
427432

433+
/// Retrieve the module-level optional imports.
434+
ArrayRef<std::string> getOptionalModuleImports() const {
435+
return storage->optionalModuleImports;
436+
}
437+
428438
/// Retreive the module-level dependencies.
429439
const ArrayRef<ModuleDependencyID> getModuleDependencies() const {
430440
assert(storage->resolved);
@@ -488,6 +498,11 @@ class ModuleDependencyInfo {
488498
const SwiftPlaceholderModuleDependencyStorage *
489499
getAsPlaceholderDependencyModule() const;
490500

501+
/// Add a dependency on the given module, if it was not already in the set.
502+
void addOptionalModuleImport(StringRef module,
503+
llvm::StringSet<> *alreadyAddedModules = nullptr);
504+
505+
491506
/// Add a dependency on the given module, if it was not already in the set.
492507
void addModuleImport(StringRef module,
493508
llvm::StringSet<> *alreadyAddedModules = nullptr);

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,7 @@ static void diagnoseScannerFailure(StringRef moduleName,
20232023
Optional<const ModuleDependencyInfo*> ASTContext::getModuleDependencies(
20242024
StringRef moduleName, ModuleDependenciesCache &cache,
20252025
InterfaceSubContextDelegate &delegate,
2026+
bool optionalDependencyLookup,
20262027
llvm::Optional<ModuleDependencyID> dependencyOf) {
20272028
// Retrieve the dependencies for this module.
20282029
// Check whether we've cached this result.
@@ -2048,8 +2049,9 @@ Optional<const ModuleDependencyInfo*> ASTContext::getModuleDependencies(
20482049
return dependencies;
20492050
}
20502051

2051-
diagnoseScannerFailure(moduleName, Diags, cache,
2052-
dependencyOf);
2052+
if (!optionalDependencyLookup)
2053+
diagnoseScannerFailure(moduleName, Diags, cache,
2054+
dependencyOf);
20532055
return None;
20542056
}
20552057

lib/AST/ModuleDependencies.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ void ModuleDependencyInfo::addModuleDependency(ModuleDependencyID dependencyID)
8989
storage->resolvedModuleDependencies.push_back(dependencyID);
9090
}
9191

92+
void ModuleDependencyInfo::addOptionalModuleImport(
93+
StringRef module, llvm::StringSet<> *alreadyAddedModules) {
94+
if (!alreadyAddedModules || alreadyAddedModules->insert(module).second)
95+
storage->optionalModuleImports.push_back(module.str());
96+
}
97+
9298
void ModuleDependencyInfo::addModuleImport(
9399
StringRef module, llvm::StringSet<> *alreadyAddedModules) {
94100
if (!alreadyAddedModules || alreadyAddedModules->insert(module).second)

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -307,12 +307,12 @@ resolveExplicitModuleInputs(ModuleDependencyID moduleID,
307307

308308
/// Resolve the direct dependencies of the given module.
309309
static ArrayRef<ModuleDependencyID>
310-
resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID module,
310+
resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID moduleID,
311311
ModuleDependenciesCache &cache,
312312
InterfaceSubContextDelegate &ASTDelegate) {
313-
PrettyStackTraceStringAction trace("Resolving direct dependencies of: ", module.first);
313+
PrettyStackTraceStringAction trace("Resolving direct dependencies of: ", moduleID.first);
314314
auto &ctx = instance.getASTContext();
315-
auto optionalKnownDependencies = cache.findDependency(module.first, module.second);
315+
auto optionalKnownDependencies = cache.findDependency(moduleID.first, moduleID.second);
316316
assert(optionalKnownDependencies.has_value());
317317
auto knownDependencies = optionalKnownDependencies.value();
318318

@@ -329,18 +329,31 @@ resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID module,
329329
ModuleDependencyIDSetVector result;
330330
for (auto dependsOn : knownDependencies->getModuleImports()) {
331331
// Figure out what kind of module we need.
332-
bool onlyClangModule = !isSwift || module.first == dependsOn;
332+
bool onlyClangModule = !isSwift || moduleID.first == dependsOn;
333333
if (onlyClangModule) {
334334
if (auto found =
335335
ctx.getClangModuleDependencies(dependsOn, cache, ASTDelegate))
336336
result.insert({dependsOn, ModuleDependencyKind::Clang});
337337
} else {
338338
if (auto found =
339-
ctx.getModuleDependencies(dependsOn, cache, ASTDelegate, module))
339+
ctx.getModuleDependencies(dependsOn, cache, ASTDelegate,
340+
/* optionalDependencyLookup */ false,
341+
moduleID))
340342
result.insert({dependsOn, found.value()->getKind()});
341343
}
342344
}
343345

346+
// We may have a set of optional dependencies for this module, such as `@_implementationOnly`
347+
// imports of a `@Testable` import. Attempt to locate those, but do not fail if they
348+
// cannot be found.
349+
for (auto optionallyDependsOn : knownDependencies->getOptionalModuleImports()) {
350+
if (auto found =
351+
ctx.getModuleDependencies(optionallyDependsOn, cache, ASTDelegate,
352+
/* optionalDependencyLookup */ true,
353+
moduleID))
354+
result.insert({optionallyDependsOn, found.value()->getKind()});
355+
}
356+
344357
if (isSwiftInterfaceOrSource) {
345358
// A record of all of the Clang modules referenced from this Swift module.
346359
std::vector<std::string> allClangModules;
@@ -350,11 +363,11 @@ resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID module,
350363
if (knownDependencies->getBridgingHeader()) {
351364
auto clangImporter =
352365
static_cast<ClangImporter *>(ctx.getClangModuleLoader());
353-
if (!clangImporter->addBridgingHeaderDependencies(module.first,
354-
module.second, cache)) {
366+
if (!clangImporter->addBridgingHeaderDependencies(moduleID.first,
367+
moduleID.second, cache)) {
355368
// Grab the updated module dependencies.
356369
// FIXME: This is such a hack.
357-
knownDependencies = *cache.findDependency(module.first, module.second);
370+
knownDependencies = *cache.findDependency(moduleID.first, moduleID.second);
358371

359372
// Add the Clang modules referenced from the bridging header to the
360373
// set of Clang modules we know about.
@@ -389,15 +402,15 @@ resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID module,
389402
for (const auto &clangDep : allClangModules) {
390403
if (auto found =
391404
ctx.getSwiftModuleDependencies(clangDep, cache, ASTDelegate)) {
392-
if (clangDep != module.first)
405+
if (clangDep != moduleID.first)
393406
result.insert({clangDep, found.value()->getKind()});
394407
}
395408
}
396409
}
397410

398411
// Resolve the dependnecy info
399-
cache.resolveDependencyImports(module, result.takeVector());
400-
return cache.findDependency(module.first, module.second).value()->getModuleDependencies();
412+
cache.resolveDependencyImports(moduleID, result.takeVector());
413+
return cache.findDependency(moduleID.first, moduleID.second).value()->getModuleDependencies();
401414
}
402415

403416
static void discoverCrossImportOverlayDependencies(

test/ScanDependencies/bin_mod_import.swift

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,8 @@ import EWrapper
1717
// CHECK: "modulePath": "{{.*}}EWrapper.swiftmodule"
1818
// CHECK-NEXT: "directDependencies": [
1919
// CHECK-NEXT: {
20-
// CHECK-NEXT: "swift": "E"
21-
// CHECK-NEXT: },
22-
// CHECK-NEXT: {
23-
// CHECK-NEXT: "swift": "Swift"
24-
// CHECK-NEXT: },
25-
// CHECK-NEXT: {
26-
// CHECK-NEXT: "swift": "SwiftOnoneSupport"
20+
// CHECK-DAG: "swift": "E"
21+
// CHECK-DAG: "swift": "Swift"
22+
// CHECK-DAG: "swift": "SwiftOnoneSupport"
2723
// CHECK-NEXT: }
2824
// CHECK-NEXT: ],

0 commit comments

Comments
 (0)