Skip to content

Commit f9d6c6a

Browse files
committed
[Dependency Scanner] Refactor ModuleDependencies to represent binary-only Swift modules explicitly
This matches the behavior of the current client (`swift-driver`) and reduces ambiguity in how the nodes in the graph are to be treated. Swift dependencies with a textual interface, for example, must be built into a binary module by clients. Swift dependencies without a textual interface, with only a binary module, are to be used directly, without any up-to-date checks. Note, this is distinct from Swift dependencies that have a textual interface, for which we also detect potential pre-build binary module candidates. Those are still reported in the `details` field of textual Swift dependencies as `prebuiltModuleCandidates`.
1 parent 6651f6e commit f9d6c6a

File tree

11 files changed

+358
-191
lines changed

11 files changed

+358
-191
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 97 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class Identifier;
3434

3535
/// Which kind of module dependencies we are looking for.
3636
enum class ModuleDependenciesKind : int8_t {
37-
Swift,
37+
SwiftTextual,
38+
SwiftBinary,
3839
// Placeholder dependencies are a kind of dependencies used only by the
3940
// dependency scanner. They are swift modules that the scanner will not be
4041
// able to locate in its search paths and which are the responsibility of the
@@ -68,26 +69,22 @@ class ModuleDependenciesStorageBase {
6869
public:
6970
const ModuleDependenciesKind dependencyKind;
7071

71-
ModuleDependenciesStorageBase(ModuleDependenciesKind dependencyKind,
72-
const std::string &compiledModulePath)
73-
: dependencyKind(dependencyKind),
74-
compiledModulePath(compiledModulePath) { }
72+
ModuleDependenciesStorageBase(ModuleDependenciesKind dependencyKind)
73+
: dependencyKind(dependencyKind) { }
7574

7675
virtual ModuleDependenciesStorageBase *clone() const = 0;
7776

7877
virtual ~ModuleDependenciesStorageBase();
7978

80-
/// The path to the compiled module file.
81-
const std::string compiledModulePath;
82-
8379
/// The set of modules on which this module depends.
8480
std::vector<std::string> moduleDependencies;
8581
};
8682

8783
/// Describes the dependencies of a Swift module.
8884
///
8985
/// This class is mostly an implementation detail for \c ModuleDependencies.
90-
class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
86+
class SwiftTextualModuleDependenciesStorage :
87+
public ModuleDependenciesStorageBase {
9188
public:
9289
/// The Swift interface file, if it can be used to generate the module file.
9390
const Optional<std::string> swiftInterfaceFile;
@@ -122,16 +119,14 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
122119
/// (Clang) modules on which the bridging header depends.
123120
std::vector<std::string> bridgingModuleDependencies;
124121

125-
SwiftModuleDependenciesStorage(
126-
const std::string &compiledModulePath,
122+
SwiftTextualModuleDependenciesStorage(
127123
const Optional<std::string> &swiftInterfaceFile,
128124
ArrayRef<std::string> compiledModuleCandidates,
129125
ArrayRef<StringRef> buildCommandLine,
130126
ArrayRef<StringRef> extraPCMArgs,
131127
StringRef contextHash,
132128
bool isFramework
133-
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Swift,
134-
compiledModulePath),
129+
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftTextual),
135130
swiftInterfaceFile(swiftInterfaceFile),
136131
compiledModuleCandidates(compiledModuleCandidates.begin(),
137132
compiledModuleCandidates.end()),
@@ -140,11 +135,47 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
140135
contextHash(contextHash), isFramework(isFramework) { }
141136

142137
ModuleDependenciesStorageBase *clone() const override {
143-
return new SwiftModuleDependenciesStorage(*this);
138+
return new SwiftTextualModuleDependenciesStorage(*this);
139+
}
140+
141+
static bool classof(const ModuleDependenciesStorageBase *base) {
142+
return base->dependencyKind == ModuleDependenciesKind::SwiftTextual;
144143
}
144+
};
145+
146+
/// Describes the dependencies of a pre-built Swift module (with no .swiftinterface).
147+
///
148+
/// This class is mostly an implementation detail for \c ModuleDependencies.
149+
class SwiftBinaryModuleDependencyStorage : public ModuleDependenciesStorageBase {
150+
public:
151+
SwiftBinaryModuleDependencyStorage(const std::string &compiledModulePath,
152+
const std::string &moduleDocPath,
153+
const std::string &sourceInfoPath,
154+
const bool isFramework)
155+
: ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftBinary),
156+
compiledModulePath(compiledModulePath),
157+
moduleDocPath(moduleDocPath),
158+
sourceInfoPath(sourceInfoPath),
159+
isFramework(isFramework) {}
160+
161+
ModuleDependenciesStorageBase *clone() const override {
162+
return new SwiftBinaryModuleDependencyStorage(*this);
163+
}
164+
165+
/// The path to the .swiftmodule file.
166+
const std::string compiledModulePath;
167+
168+
/// The path to the .swiftModuleDoc file.
169+
const std::string moduleDocPath;
170+
171+
/// The path to the .swiftSourceInfo file.
172+
const std::string sourceInfoPath;
173+
174+
/// A flag that indicates this dependency is a framework
175+
const bool isFramework;
145176

146177
static bool classof(const ModuleDependenciesStorageBase *base) {
147-
return base->dependencyKind == ModuleDependenciesKind::Swift;
178+
return base->dependencyKind == ModuleDependenciesKind::SwiftBinary;
148179
}
149180
};
150181

@@ -166,13 +197,11 @@ class ClangModuleDependenciesStorage : public ModuleDependenciesStorageBase {
166197
const std::vector<std::string> fileDependencies;
167198

168199
ClangModuleDependenciesStorage(
169-
const std::string &compiledModulePath,
170200
const std::string &moduleMapFile,
171201
const std::string &contextHash,
172202
const std::vector<std::string> &nonPathCommandLine,
173203
const std::vector<std::string> &fileDependencies
174-
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Clang,
175-
compiledModulePath),
204+
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Clang),
176205
moduleMapFile(moduleMapFile),
177206
contextHash(contextHash),
178207
nonPathCommandLine(nonPathCommandLine),
@@ -190,20 +219,24 @@ class ClangModuleDependenciesStorage : public ModuleDependenciesStorageBase {
190219
/// Describes an placeholder Swift module dependency module stub.
191220
///
192221
/// This class is mostly an implementation detail for \c ModuleDependencies.
193-
class PlaceholderSwiftModuleDependencyStorage : public ModuleDependenciesStorageBase {
222+
223+
class SwiftPlaceholderModuleDependencyStorage : public ModuleDependenciesStorageBase {
194224
public:
195-
PlaceholderSwiftModuleDependencyStorage(const std::string &compiledModulePath,
196-
const std::string &moduleDocPath,
197-
const std::string &sourceInfoPath)
198-
: ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftPlaceholder,
199-
compiledModulePath),
225+
SwiftPlaceholderModuleDependencyStorage(const std::string &compiledModulePath,
226+
const std::string &moduleDocPath,
227+
const std::string &sourceInfoPath)
228+
: ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftPlaceholder),
229+
compiledModulePath(compiledModulePath),
200230
moduleDocPath(moduleDocPath),
201231
sourceInfoPath(sourceInfoPath) {}
202232

203233
ModuleDependenciesStorageBase *clone() const override {
204-
return new PlaceholderSwiftModuleDependencyStorage(*this);
234+
return new SwiftPlaceholderModuleDependencyStorage(*this);
205235
}
206236

237+
/// The path to the .swiftmodule file.
238+
const std::string compiledModulePath;
239+
207240
/// The path to the .swiftModuleDoc file.
208241
const std::string moduleDocPath;
209242

@@ -248,43 +281,41 @@ class ModuleDependencies {
248281
ArrayRef<StringRef> extraPCMArgs,
249282
StringRef contextHash,
250283
bool isFramework) {
251-
std::string compiledModulePath;
252284
return ModuleDependencies(
253-
std::make_unique<SwiftModuleDependenciesStorage>(
254-
compiledModulePath, swiftInterfaceFile, compiledCandidates, buildCommands,
285+
std::make_unique<SwiftTextualModuleDependenciesStorage>(
286+
swiftInterfaceFile, compiledCandidates, buildCommands,
255287
extraPCMArgs, contextHash, isFramework));
256288
}
257289

258290
/// Describe the module dependencies for a serialized or parsed Swift module.
259-
static ModuleDependencies forSwiftModule(
260-
const std::string &compiledModulePath, bool isFramework) {
291+
static ModuleDependencies forSwiftBinaryModule(
292+
const std::string &compiledModulePath,
293+
const std::string &moduleDocPath,
294+
const std::string &sourceInfoPath,
295+
bool isFramework) {
261296
return ModuleDependencies(
262-
std::make_unique<SwiftModuleDependenciesStorage>(
263-
compiledModulePath, None, ArrayRef<std::string>(), ArrayRef<StringRef>(),
264-
ArrayRef<StringRef>(), StringRef(), isFramework));
297+
std::make_unique<SwiftBinaryModuleDependencyStorage>(
298+
compiledModulePath, moduleDocPath, sourceInfoPath, isFramework));
265299
}
266300

267301
/// Describe the main Swift module.
268302
static ModuleDependencies forMainSwiftModule(ArrayRef<StringRef> extraPCMArgs) {
269-
std::string compiledModulePath;
270303
return ModuleDependencies(
271-
std::make_unique<SwiftModuleDependenciesStorage>(
272-
compiledModulePath, None, ArrayRef<std::string>(),
273-
ArrayRef<StringRef>(), extraPCMArgs, StringRef(), false));
304+
std::make_unique<SwiftTextualModuleDependenciesStorage>(
305+
None, ArrayRef<std::string>(), ArrayRef<StringRef>(),
306+
extraPCMArgs, StringRef(), false));
274307
}
275308

276309
/// Describe the module dependencies for a Clang module that can be
277310
/// built from a module map and headers.
278311
static ModuleDependencies forClangModule(
279-
const std::string &compiledModulePath,
280312
const std::string &moduleMapFile,
281313
const std::string &contextHash,
282314
const std::vector<std::string> &nonPathCommandLine,
283315
const std::vector<std::string> &fileDependencies) {
284316
return ModuleDependencies(
285317
std::make_unique<ClangModuleDependenciesStorage>(
286-
compiledModulePath, moduleMapFile, contextHash, nonPathCommandLine,
287-
fileDependencies));
318+
moduleMapFile, contextHash, nonPathCommandLine, fileDependencies));
288319
}
289320

290321
/// Describe a placeholder dependency swift module.
@@ -293,38 +324,45 @@ class ModuleDependencies {
293324
const std::string &moduleDocPath,
294325
const std::string &sourceInfoPath) {
295326
return ModuleDependencies(
296-
std::make_unique<PlaceholderSwiftModuleDependencyStorage>(
327+
std::make_unique<SwiftPlaceholderModuleDependencyStorage>(
297328
compiledModulePath, moduleDocPath, sourceInfoPath));
298329
}
299330

300-
/// Retrieve the path to the compiled module.
301-
const std::string getCompiledModulePath() const {
302-
return storage->compiledModulePath;
303-
}
304-
305331
/// Retrieve the module-level dependencies.
306332
ArrayRef<std::string> getModuleDependencies() const {
307333
return storage->moduleDependencies;
308334
}
309335

310-
/// Whether the dependencies are for a Swift module.
336+
/// Whether the dependencies are for a Swift module: either Textual, Binary, or Placeholder.
311337
bool isSwiftModule() const;
312338

339+
/// Whether the dependencies are for a textual Swift module.
340+
bool isSwiftTextualModule() const;
341+
342+
/// Whether the dependencies are for a binary Swift module.
343+
bool isSwiftBinaryModule() const;
344+
313345
/// Whether this represents a placeholder module stub
314-
bool isPlaceholderSwiftModule() const;
346+
bool isSwiftPlaceholderModule() const;
347+
348+
/// Whether the dependencies are for a Clang module.
349+
bool isClangModule() const;
315350

316351
ModuleDependenciesKind getKind() const {
317352
return storage->dependencyKind;
318353
}
319354
/// Retrieve the dependencies for a Swift module.
320-
const SwiftModuleDependenciesStorage *getAsSwiftModule() const;
355+
const SwiftTextualModuleDependenciesStorage *getAsSwiftTextualModule() const;
356+
357+
/// Retrieve the dependencies for a binary Swift module.
358+
const SwiftBinaryModuleDependencyStorage *getAsSwiftBinaryModule() const;
321359

322360
/// Retrieve the dependencies for a Clang module.
323361
const ClangModuleDependenciesStorage *getAsClangModule() const;
324362

325363
/// Retrieve the dependencies for a placeholder dependency module stub.
326-
const PlaceholderSwiftModuleDependencyStorage *
327-
getAsPlaceholderDependencyModule() const;
364+
const SwiftPlaceholderModuleDependencyStorage *
365+
getAsPlaceholderDependencyModule() const;
328366

329367
/// Add a dependency on the given module, if it was not already in the set.
330368
void addModuleDependency(StringRef module,
@@ -363,11 +401,14 @@ class ModuleDependenciesCache {
363401
/// encountered.
364402
std::vector<ModuleDependencyID> AllModules;
365403

366-
/// Dependencies for Swift modules that have already been computed.
367-
llvm::StringMap<ModuleDependencies> SwiftModuleDependencies;
404+
/// Dependencies for Textual Swift modules that have already been computed.
405+
llvm::StringMap<ModuleDependencies> SwiftTextualModuleDependencies;
368406

369-
/// Dependencies for Swift placeholder dependency modules.
370-
llvm::StringMap<ModuleDependencies> PlaceholderSwiftModuleDependencies;
407+
/// Dependencies for Binary Swift modules that have already been computed.
408+
llvm::StringMap<ModuleDependencies> SwiftBinaryModuleDependencies;
409+
410+
/// Dependencies for Swift placeholder dependency modules that have already been computed.
411+
llvm::StringMap<ModuleDependencies> SwiftPlaceholderModuleDependencies;
371412

372413
/// Dependencies for Clang modules that have already been computed.
373414
llvm::StringMap<ModuleDependencies> ClangModuleDependencies;
@@ -429,8 +470,7 @@ class ModuleDependenciesCache {
429470

430471
/// Record dependencies for the given module.
431472
void recordDependencies(StringRef moduleName,
432-
ModuleDependencies dependencies,
433-
ModuleDependenciesKind kind);
473+
ModuleDependencies dependencies);
434474

435475
/// Update stored dependencies for the given module.
436476
void updateDependencies(ModuleDependencyID moduleID,

include/swift/Serialization/ModuleDependencyScanner.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,13 @@ namespace swift {
4040
public:
4141
Optional<ModuleDependencies> dependencies;
4242

43-
/// Describes the kind of dependencies this scanner is able to identify
44-
ModuleDependenciesKind dependencyKind;
45-
4643
ModuleDependencyScanner(
4744
ASTContext &ctx, ModuleLoadingMode LoadMode, Identifier moduleName,
4845
InterfaceSubContextDelegate &astDelegate,
49-
ModuleDependenciesKind dependencyKind = ModuleDependenciesKind::Swift,
5046
ScannerKind kind = MDS_plain)
5147
: SerializedModuleLoaderBase(ctx, nullptr, LoadMode,
5248
/*IgnoreSwiftSourceInfoFile=*/true),
53-
kind(kind), moduleName(moduleName), astDelegate(astDelegate),
54-
dependencyKind(dependencyKind) {}
49+
kind(kind), moduleName(moduleName), astDelegate(astDelegate) {}
5550

5651
std::error_code findModuleFilesInDirectory(
5752
ImportPath::Element ModuleID,
@@ -60,7 +55,7 @@ namespace swift {
6055
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
6156
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
6257
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
63-
bool IsFramework) override;
58+
bool IsFramework) override;
6459

6560
virtual void collectVisibleTopLevelModuleNames(
6661
SmallVectorImpl<Identifier> &names) const override {
@@ -106,7 +101,6 @@ namespace swift {
106101
StringRef PlaceholderDependencyModuleMap,
107102
InterfaceSubContextDelegate &astDelegate)
108103
: ModuleDependencyScanner(ctx, LoadMode, moduleName, astDelegate,
109-
ModuleDependenciesKind::SwiftPlaceholder,
110104
MDS_placeholder) {
111105

112106
// FIXME: Find a better place for this map to live, to avoid

0 commit comments

Comments
 (0)