Skip to content

Commit ed488eb

Browse files
committed
[Dependency Scanning] Teach dependency scanner to resolve optional dependencies of a module
1 parent 1456daa commit ed488eb

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
@@ -1020,6 +1020,7 @@ class ASTContext final {
10201020
StringRef moduleName,
10211021
ModuleDependenciesCache &cache,
10221022
InterfaceSubContextDelegate &delegate,
1023+
bool optionalDependencyLookup = false,
10231024
llvm::Optional<std::pair<std::string, swift::ModuleDependencyKind>> dependencyOf = None);
10241025

10251026
/// 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
@@ -2009,6 +2009,7 @@ static void diagnoseScannerFailure(StringRef moduleName,
20092009
Optional<const ModuleDependencyInfo*> ASTContext::getModuleDependencies(
20102010
StringRef moduleName, ModuleDependenciesCache &cache,
20112011
InterfaceSubContextDelegate &delegate,
2012+
bool optionalDependencyLookup,
20122013
llvm::Optional<ModuleDependencyID> dependencyOf) {
20132014
// Retrieve the dependencies for this module.
20142015
// Check whether we've cached this result.
@@ -2034,8 +2035,9 @@ Optional<const ModuleDependencyInfo*> ASTContext::getModuleDependencies(
20342035
return dependencies;
20352036
}
20362037

2037-
diagnoseScannerFailure(moduleName, Diags, cache,
2038-
dependencyOf);
2038+
if (!optionalDependencyLookup)
2039+
diagnoseScannerFailure(moduleName, Diags, cache,
2040+
dependencyOf);
20392041
return None;
20402042
}
20412043

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
@@ -304,12 +304,12 @@ resolveExplicitModuleInputs(ModuleDependencyID moduleID,
304304

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

@@ -326,18 +326,31 @@ resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID module,
326326
ModuleDependencyIDSetVector result;
327327
for (auto dependsOn : knownDependencies->getModuleImports()) {
328328
// Figure out what kind of module we need.
329-
bool onlyClangModule = !isSwift || module.first == dependsOn;
329+
bool onlyClangModule = !isSwift || moduleID.first == dependsOn;
330330
if (onlyClangModule) {
331331
if (auto found =
332332
ctx.getClangModuleDependencies(dependsOn, cache, ASTDelegate))
333333
result.insert({dependsOn, ModuleDependencyKind::Clang});
334334
} else {
335335
if (auto found =
336-
ctx.getModuleDependencies(dependsOn, cache, ASTDelegate, module))
336+
ctx.getModuleDependencies(dependsOn, cache, ASTDelegate,
337+
/* optionalDependencyLookup */ false,
338+
moduleID))
337339
result.insert({dependsOn, found.value()->getKind()});
338340
}
339341
}
340342

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

356369
// Add the Clang modules referenced from the bridging header to the
357370
// set of Clang modules we know about.
@@ -386,15 +399,15 @@ resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID module,
386399
for (const auto &clangDep : allClangModules) {
387400
if (auto found =
388401
ctx.getSwiftModuleDependencies(clangDep, cache, ASTDelegate)) {
389-
if (clangDep != module.first)
402+
if (clangDep != moduleID.first)
390403
result.insert({clangDep, found.value()->getKind()});
391404
}
392405
}
393406
}
394407

395408
// Resolve the dependnecy info
396-
cache.resolveDependencyImports(module, result.takeVector());
397-
return cache.findDependency(module.first, module.second).value()->getModuleDependencies();
409+
cache.resolveDependencyImports(moduleID, result.takeVector());
410+
return cache.findDependency(moduleID.first, moduleID.second).value()->getModuleDependencies();
398411
}
399412

400413
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)