Skip to content

Commit 6fcd8be

Browse files
committed
[Dependency Scanning] Pull optional dependencies from the adjacent binary module for direct interface dependencies
For a `@Testable` import in program source, if a Swift interface dependency is discovered, and has an adjacent binary `.swiftmodule`, open up the module, and pull in its optional dependencies. If an optional dependency cannot be resolved on the filesystem, fail silently without raising a diagnostic.
1 parent 10fb324 commit 6fcd8be

17 files changed

+140
-48
lines changed

include/swift/AST/ASTContext.h

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

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

include/swift/AST/ModuleLoader.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ class ModuleLoader {
245245
/// If a non-null \p versionInfo is provided, the module version will be
246246
/// parsed and populated.
247247
virtual bool canImportModule(ImportPath::Module named,
248-
ModuleVersionInfo *versionInfo) = 0;
248+
ModuleVersionInfo *versionInfo,
249+
bool isTestableImport = false) = 0;
249250

250251
/// Import a module with the given module path.
251252
///
@@ -328,7 +329,8 @@ class ModuleLoader {
328329
virtual Optional<const ModuleDependencyInfo*> getModuleDependencies(
329330
StringRef moduleName,
330331
ModuleDependenciesCache &cache,
331-
InterfaceSubContextDelegate &delegate) = 0;
332+
InterfaceSubContextDelegate &delegate,
333+
bool isTestableImport = false) = 0;
332334
};
333335

334336
} // namespace swift

include/swift/ClangImporter/ClangImporter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ class ClangImporter final : public ClangModuleLoader {
213213
/// If a non-null \p versionInfo is provided, the module version will be
214214
/// parsed and populated.
215215
virtual bool canImportModule(ImportPath::Module named,
216-
ModuleVersionInfo *versionInfo) override;
216+
ModuleVersionInfo *versionInfo,
217+
bool isTestableImport = false) override;
217218

218219
/// Import a module with the given module path.
219220
///
@@ -427,7 +428,8 @@ class ClangImporter final : public ClangModuleLoader {
427428

428429
Optional<const ModuleDependencyInfo*> getModuleDependencies(
429430
StringRef moduleName, ModuleDependenciesCache &cache,
430-
InterfaceSubContextDelegate &delegate) override;
431+
InterfaceSubContextDelegate &delegate,
432+
bool isTestableImport = false) override;
431433

432434
/// Add dependency information for the bridging header.
433435
///

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
142142
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
143143
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
144144
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
145-
bool skipBuildingInterface, bool &isFramework,
146-
bool &isSystemModule) override;
145+
bool skipBuildingInterface, bool isTestableDependencyLookup,
146+
bool &isFramework, bool &isSystemModule) override;
147147

148148
std::error_code findModuleFilesInDirectory(
149149
ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName,
@@ -152,10 +152,12 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
152152
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
153153
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
154154
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
155-
bool skipBuildingInterface, bool IsFramework) override;
155+
bool SkipBuildingInterface, bool IsFramework,
156+
bool IsTestableDependencyLookup = false) override;
156157

157158
bool canImportModule(ImportPath::Module named,
158-
ModuleVersionInfo *versionInfo) override;
159+
ModuleVersionInfo *versionInfo,
160+
bool isTestableDependencyLookup = false) override;
159161

160162
bool isCached(StringRef DepPath) override { return false; };
161163

@@ -477,7 +479,8 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
477479
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
478480
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
479481
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
480-
bool skipBuildingInterface, bool IsFramework) override;
482+
bool SkipBuildingInterface, bool IsFramework,
483+
bool IsTestableDependencyLookup = false) override;
481484

482485
bool isCached(StringRef DepPath) override;
483486
public:

include/swift/Sema/SourceLoader.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ class SourceLoader : public ModuleLoader {
6060
/// If a non-null \p versionInfo is provided, the module version will be
6161
/// parsed and populated.
6262
virtual bool canImportModule(ImportPath::Module named,
63-
ModuleVersionInfo *versionInfo) override;
63+
ModuleVersionInfo *versionInfo,
64+
bool isTestableDependencyLookup = false) override;
6465

6566
/// Import a module with the given module path.
6667
///
@@ -98,7 +99,8 @@ class SourceLoader : public ModuleLoader {
9899

99100
Optional<const ModuleDependencyInfo*>
100101
getModuleDependencies(StringRef moduleName, ModuleDependenciesCache &cache,
101-
InterfaceSubContextDelegate &delegate) override;
102+
InterfaceSubContextDelegate &delegate,
103+
bool isTestableImport) override;
102104
};
103105
}
104106

include/swift/Serialization/ModuleDependencyScanner.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ namespace swift {
3434

3535
/// Scan the given interface file to determine dependencies.
3636
llvm::ErrorOr<ModuleDependencyInfo> scanInterfaceFile(
37-
Twine moduleInterfacePath, bool isFramework);
37+
Twine moduleInterfacePath, bool isFramework,
38+
bool isTestableImport);
3839

3940
InterfaceSubContextDelegate &astDelegate;
4041

@@ -61,7 +62,8 @@ namespace swift {
6162
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
6263
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
6364
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
64-
bool skipBuildingInterface, bool IsFramework) override;
65+
bool SkipBuildingInterface, bool IsFramework,
66+
bool IsTestableDependencyLookup) override;
6567

6668
virtual void collectVisibleTopLevelModuleNames(
6769
SmallVectorImpl<Identifier> &names) const override {
@@ -125,8 +127,8 @@ namespace swift {
125127
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
126128
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
127129
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
128-
bool skipBuildingInterface, bool &isFramework,
129-
bool &isSystemModule) override;
130+
bool skipBuildingInterface, bool isTestableDependencyLookup,
131+
bool &isFramework, bool &isSystemModule) override;
130132

131133
static bool classof(const ModuleDependencyScanner *MDS) {
132134
return MDS->getKind() == MDS_placeholder;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
8686
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
8787
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
8888
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
89-
bool skipBuildingInterface, bool &isFramework, bool &isSystemModule);
89+
bool skipBuildingInterface, bool isTestableDependencyLookup,
90+
bool &isFramework, bool &isSystemModule);
9091

9192
/// Attempts to search the provided directory for a loadable serialized
9293
/// .swiftmodule with the provided `ModuleFilename`. Subclasses must
@@ -107,7 +108,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
107108
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
108109
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
109110
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
110-
bool skipBuildingInterface, bool IsFramework) = 0;
111+
bool SkipBuildingInterface, bool IsFramework,
112+
bool isTestableDependencyLookup = false) = 0;
111113

112114
std::error_code
113115
openModuleFile(
@@ -191,7 +193,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
191193
/// If a non-null \p versionInfo is provided, the module version will be
192194
/// parsed and populated.
193195
virtual bool canImportModule(ImportPath::Module named,
194-
ModuleVersionInfo *versionInfo) override;
196+
ModuleVersionInfo *versionInfo,
197+
bool isTestableDependencyLookup = false) override;
195198

196199
/// Import a module with the given module path.
197200
///
@@ -226,7 +229,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
226229

227230
virtual Optional<const ModuleDependencyInfo*> getModuleDependencies(
228231
StringRef moduleName, ModuleDependenciesCache &cache,
229-
InterfaceSubContextDelegate &delegate) override;
232+
InterfaceSubContextDelegate &delegate,
233+
bool isTestableImport) override;
230234
};
231235

232236
/// Imports serialized Swift modules into an ASTContext.
@@ -244,7 +248,8 @@ class ImplicitSerializedModuleLoader : public SerializedModuleLoaderBase {
244248
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
245249
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
246250
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
247-
bool skipBuildingInterface, bool IsFramework) override;
251+
bool SkipBuildingInterface, bool IsFramework,
252+
bool isTestableDependencyLookup = false) override;
248253

249254
bool maybeDiagnoseTargetMismatch(
250255
SourceLoc sourceLocation,
@@ -298,7 +303,8 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
298303
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
299304
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
300305
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
301-
bool skipBuildingInterface, bool IsFramework) override;
306+
bool SkipBuildingInterface, bool IsFramework,
307+
bool IsTestableDependencyLookup = false) override;
302308

303309
bool maybeDiagnoseTargetMismatch(
304310
SourceLoc sourceLocation,
@@ -310,7 +316,8 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
310316
virtual ~MemoryBufferSerializedModuleLoader();
311317

312318
bool canImportModule(ImportPath::Module named,
313-
ModuleVersionInfo *versionInfo) override;
319+
ModuleVersionInfo *versionInfo,
320+
bool isTestableDependencyLookup = false) override;
314321

315322
ModuleDecl *
316323
loadModule(SourceLoc importLoc,

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,7 @@ Optional<const ModuleDependencyInfo*> ASTContext::getModuleDependencies(
20242024
StringRef moduleName, ModuleDependenciesCache &cache,
20252025
InterfaceSubContextDelegate &delegate,
20262026
bool optionalDependencyLookup,
2027+
bool isTestableImport,
20272028
llvm::Optional<ModuleDependencyID> dependencyOf) {
20282029
// Retrieve the dependencies for this module.
20292030
// Check whether we've cached this result.
@@ -2045,7 +2046,8 @@ Optional<const ModuleDependencyInfo*> ASTContext::getModuleDependencies(
20452046

20462047
for (auto &loader : getImpl().ModuleLoaders) {
20472048
if (auto dependencies =
2048-
loader->getModuleDependencies(moduleName, cache, delegate))
2049+
loader->getModuleDependencies(moduleName, cache, delegate,
2050+
isTestableImport))
20492051
return dependencies;
20502052
}
20512053

lib/AST/ModuleDependencies.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ void ModuleDependencyInfo::addModuleImport(
127127
auto realPath = importDecl->getRealModulePath(scratch);
128128
addModuleImport(realPath, &alreadyAddedModules);
129129

130+
// Additionally, keep track of which dependencies of a Source
131+
// module are `@Testable`.
130132
if (getKind() == swift::ModuleDependencyKind::SwiftSource &&
131133
importDecl->isTestable())
132134
addTestableImport(realPath);
@@ -140,9 +142,8 @@ void ModuleDependencyInfo::addModuleImport(
140142
case swift::ModuleDependencyKind::SwiftInterface: {
141143
// If the storage is for an interface file, the only source file we
142144
// should see is that interface file.
143-
auto swiftInterfaceStorage =
144-
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
145-
assert(fileName == swiftInterfaceStorage->swiftInterfaceFile);
145+
assert(fileName ==
146+
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get())->swiftInterfaceFile);
146147
break;
147148
}
148149
case swift::ModuleDependencyKind::SwiftSource: {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1855,7 +1855,8 @@ static std::string getScalaNodeText(llvm::yaml::Node *N) {
18551855
}
18561856

18571857
bool ClangImporter::canImportModule(ImportPath::Module modulePath,
1858-
ModuleVersionInfo *versionInfo) {
1858+
ModuleVersionInfo *versionInfo,
1859+
bool isTestableDependencyLookup) {
18591860
// Look up the top-level module to see if it exists.
18601861
auto &clangHeaderSearch = Impl.getClangPreprocessor().getHeaderSearchInfo();
18611862
auto topModule = modulePath.front();

0 commit comments

Comments
 (0)