Skip to content

Commit 3946ef5

Browse files
authored
Merge pull request #65256 from artemcm/59TestableDependencyOptionalLookup
[5.9 🍒][Dependency Scanning] Consider optional dependencies of @testable textual dependencies with an adjacent binary module
2 parents ee61e11 + db6883e commit 3946ef5

21 files changed

+335
-98
lines changed

include/swift/AST/ASTContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,8 @@ class ASTContext final {
10201020
StringRef moduleName,
10211021
ModuleDependenciesCache &cache,
10221022
InterfaceSubContextDelegate &delegate,
1023+
bool optionalDependencyLookup = false,
1024+
bool isTestableImport = false,
10231025
llvm::Optional<std::pair<std::string, swift::ModuleDependencyKind>> dependencyOf = None);
10241026

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

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,10 @@ class ImportDecl final : public Decl,
14221422
return getAttrs().hasAttribute<ExportedAttr>();
14231423
}
14241424

1425+
bool isTestable() const {
1426+
return getAttrs().hasAttribute<TestableAttr>();
1427+
}
1428+
14251429
ModuleDecl *getModule() const { return Mod; }
14261430
void setModule(ModuleDecl *M) { Mod = M; }
14271431

include/swift/AST/ModuleDependencies.h

Lines changed: 31 additions & 1 deletion
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;
@@ -206,10 +211,14 @@ class SwiftSourceModuleDependenciesStorage :
206211
/// Details common to Swift textual (interface or source) modules
207212
CommonSwiftTextualModuleDependencyDetails textualModuleDetails;
208213

214+
/// Collection of module imports that were detected to be `@Testable`
215+
llvm::StringSet<> testableImports;
216+
209217
SwiftSourceModuleDependenciesStorage(
210218
ArrayRef<StringRef> extraPCMArgs
211219
) : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftSource),
212-
textualModuleDetails(extraPCMArgs) {}
220+
textualModuleDetails(extraPCMArgs),
221+
testableImports(llvm::StringSet<>()) {}
213222

214223
ModuleDependencyInfoStorageBase *clone() const override {
215224
return new SwiftSourceModuleDependenciesStorage(*this);
@@ -218,6 +227,10 @@ class SwiftSourceModuleDependenciesStorage :
218227
static bool classof(const ModuleDependencyInfoStorageBase *base) {
219228
return base->dependencyKind == ModuleDependencyKind::SwiftSource;
220229
}
230+
231+
void addTestableImport(ImportPath::Module module) {
232+
testableImports.insert(module.front().Item.str());
233+
}
221234
};
222235

223236
/// Describes the dependencies of a pre-built Swift module (with no .swiftinterface).
@@ -425,6 +438,11 @@ class ModuleDependencyInfo {
425438
return storage->moduleImports;
426439
}
427440

441+
/// Retrieve the module-level optional imports.
442+
ArrayRef<std::string> getOptionalModuleImports() const {
443+
return storage->optionalModuleImports;
444+
}
445+
428446
/// Retreive the module-level dependencies.
429447
const ArrayRef<ModuleDependencyID> getModuleDependencies() const {
430448
assert(storage->resolved);
@@ -450,6 +468,13 @@ class ModuleDependencyInfo {
450468
storage->resolved = isResolved;
451469
}
452470

471+
/// For a Source dependency, register a `Testable` import
472+
void addTestableImport(ImportPath::Module module);
473+
474+
/// Whether or not a queried module name is a `@Testable` import dependency
475+
/// of this module. Can only return `true` for Swift source modules.
476+
bool isTestableImport(StringRef moduleName) const;
477+
453478
/// Whether the dependencies are for a Swift module: either Textual, Source, Binary, or Placeholder.
454479
bool isSwiftModule() const;
455480

@@ -488,6 +513,11 @@ class ModuleDependencyInfo {
488513
const SwiftPlaceholderModuleDependencyStorage *
489514
getAsPlaceholderDependencyModule() const;
490515

516+
/// Add a dependency on the given module, if it was not already in the set.
517+
void addOptionalModuleImport(StringRef module,
518+
llvm::StringSet<> *alreadyAddedModules = nullptr);
519+
520+
491521
/// Add a dependency on the given module, if it was not already in the set.
492522
void addModuleImport(StringRef module,
493523
llvm::StringSet<> *alreadyAddedModules = nullptr);

include/swift/AST/ModuleLoader.h

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

246247
/// Import a module with the given module path.
247248
///
@@ -324,7 +325,8 @@ class ModuleLoader {
324325
virtual Optional<const ModuleDependencyInfo*> getModuleDependencies(
325326
StringRef moduleName,
326327
ModuleDependenciesCache &cache,
327-
InterfaceSubContextDelegate &delegate) = 0;
328+
InterfaceSubContextDelegate &delegate,
329+
bool isTestableImport = false) = 0;
328330
};
329331

330332
} // namespace swift

include/swift/ClangImporter/ClangImporter.h

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

217218
/// Import a module with the given module path.
218219
///
@@ -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

@@ -476,7 +478,8 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
476478
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
477479
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
478480
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
479-
bool skipBuildingInterface, bool IsFramework) override;
481+
bool SkipBuildingInterface, bool IsFramework,
482+
bool IsTestableDependencyLookup = false) override;
480483

481484
bool isCached(StringRef DepPath) override;
482485
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: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
namespace swift {
2222
class ModuleFile;
23+
class PathObfuscator;
24+
enum class ModuleLoadingBehavior;
2325
namespace file_types {
2426
enum ID : uint8_t;
2527
}
@@ -84,7 +86,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
8486
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
8587
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
8688
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
87-
bool skipBuildingInterface, bool &isFramework, bool &isSystemModule);
89+
bool skipBuildingInterface, bool isTestableDependencyLookup,
90+
bool &isFramework, bool &isSystemModule);
8891

8992
/// Attempts to search the provided directory for a loadable serialized
9093
/// .swiftmodule with the provided `ModuleFilename`. Subclasses must
@@ -105,7 +108,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
105108
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
106109
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
107110
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
108-
bool skipBuildingInterface, bool IsFramework) = 0;
111+
bool SkipBuildingInterface, bool IsFramework,
112+
bool isTestableDependencyLookup = false) = 0;
109113

110114
std::error_code
111115
openModuleFile(
@@ -146,6 +150,16 @@ class SerializedModuleLoaderBase : public ModuleLoader {
146150
/// Scan the given serialized module file to determine dependencies.
147151
llvm::ErrorOr<ModuleDependencyInfo> scanModuleFile(Twine modulePath, bool isFramework);
148152

153+
static llvm::ErrorOr<llvm::StringSet<>>
154+
getModuleImportsOfModule(Twine modulePath,
155+
ModuleLoadingBehavior transitiveBehavior,
156+
bool isFramework,
157+
bool isRequiredOSSAModules,
158+
StringRef SDKName,
159+
StringRef packageName,
160+
llvm::vfs::FileSystem *fileSystem,
161+
PathObfuscator &recoverer);
162+
149163
/// Load the module file into a buffer and also collect its module name.
150164
static std::unique_ptr<llvm::MemoryBuffer>
151165
getModuleName(ASTContext &Ctx, StringRef modulePath, std::string &Name);
@@ -179,7 +193,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
179193
/// If a non-null \p versionInfo is provided, the module version will be
180194
/// parsed and populated.
181195
virtual bool canImportModule(ImportPath::Module named,
182-
ModuleVersionInfo *versionInfo) override;
196+
ModuleVersionInfo *versionInfo,
197+
bool isTestableDependencyLookup = false) override;
183198

184199
/// Import a module with the given module path.
185200
///
@@ -214,7 +229,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
214229

215230
virtual Optional<const ModuleDependencyInfo*> getModuleDependencies(
216231
StringRef moduleName, ModuleDependenciesCache &cache,
217-
InterfaceSubContextDelegate &delegate) override;
232+
InterfaceSubContextDelegate &delegate,
233+
bool isTestableImport) override;
218234
};
219235

220236
/// Imports serialized Swift modules into an ASTContext.
@@ -232,7 +248,8 @@ class ImplicitSerializedModuleLoader : public SerializedModuleLoaderBase {
232248
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
233249
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
234250
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
235-
bool skipBuildingInterface, bool IsFramework) override;
251+
bool SkipBuildingInterface, bool IsFramework,
252+
bool isTestableDependencyLookup = false) override;
236253

237254
bool maybeDiagnoseTargetMismatch(
238255
SourceLoc sourceLocation,
@@ -286,7 +303,8 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
286303
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
287304
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
288305
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
289-
bool skipBuildingInterface, bool IsFramework) override;
306+
bool SkipBuildingInterface, bool IsFramework,
307+
bool IsTestableDependencyLookup = false) override;
290308

291309
bool maybeDiagnoseTargetMismatch(
292310
SourceLoc sourceLocation,
@@ -298,7 +316,8 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
298316
virtual ~MemoryBufferSerializedModuleLoader();
299317

300318
bool canImportModule(ImportPath::Module named,
301-
ModuleVersionInfo *versionInfo) override;
319+
ModuleVersionInfo *versionInfo,
320+
bool isTestableDependencyLookup = false) override;
302321

303322
ModuleDecl *
304323
loadModule(SourceLoc importLoc,

lib/AST/ASTContext.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,8 @@ static void diagnoseScannerFailure(StringRef moduleName,
20092009
Optional<const ModuleDependencyInfo*> ASTContext::getModuleDependencies(
20102010
StringRef moduleName, ModuleDependenciesCache &cache,
20112011
InterfaceSubContextDelegate &delegate,
2012+
bool optionalDependencyLookup,
2013+
bool isTestableImport,
20122014
llvm::Optional<ModuleDependencyID> dependencyOf) {
20132015
// Retrieve the dependencies for this module.
20142016
// Check whether we've cached this result.
@@ -2030,12 +2032,14 @@ Optional<const ModuleDependencyInfo*> ASTContext::getModuleDependencies(
20302032

20312033
for (auto &loader : getImpl().ModuleLoaders) {
20322034
if (auto dependencies =
2033-
loader->getModuleDependencies(moduleName, cache, delegate))
2035+
loader->getModuleDependencies(moduleName, cache, delegate,
2036+
isTestableImport))
20342037
return dependencies;
20352038
}
20362039

2037-
diagnoseScannerFailure(moduleName, Diags, cache,
2038-
dependencyOf);
2040+
if (!optionalDependencyLookup)
2041+
diagnoseScannerFailure(moduleName, Diags, cache,
2042+
dependencyOf);
20392043
return None;
20402044
}
20412045

0 commit comments

Comments
 (0)