Skip to content

Commit fc9ee1e

Browse files
authored
Merge pull request swiftlang#32956 from nkcsgexi/report-compiled-candidates
DependenciesScanner: include compiled module candidates for textual module interface in JSON output
2 parents 3181dd1 + b93ff79 commit fc9ee1e

File tree

8 files changed

+77
-48
lines changed

8 files changed

+77
-48
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
6969
/// The Swift interface file, if it can be used to generate the module file.
7070
const Optional<std::string> swiftInterfaceFile;
7171

72+
/// Potentially ready-to-use compiled modules for the interface file.
73+
const std::vector<std::string> compiledModuleCandidates;
74+
7275
/// The Swift frontend invocation arguments to build the Swift module from the
7376
/// interface.
7477
const std::vector<std::string> buildCommandLine;
@@ -96,11 +99,14 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
9699
SwiftModuleDependenciesStorage(
97100
const std::string &compiledModulePath,
98101
const Optional<std::string> &swiftInterfaceFile,
102+
ArrayRef<std::string> compiledModuleCandidates,
99103
ArrayRef<StringRef> buildCommandLine,
100104
ArrayRef<StringRef> extraPCMArgs,
101105
StringRef contextHash
102106
) : ModuleDependenciesStorageBase(/*isSwiftModule=*/true, compiledModulePath),
103107
swiftInterfaceFile(swiftInterfaceFile),
108+
compiledModuleCandidates(compiledModuleCandidates.begin(),
109+
compiledModuleCandidates.end()),
104110
buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()),
105111
extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()),
106112
contextHash(contextHash) { }
@@ -181,13 +187,14 @@ class ModuleDependencies {
181187
/// built from a Swift interface file (\c .swiftinterface).
182188
static ModuleDependencies forSwiftInterface(
183189
const std::string &swiftInterfaceFile,
190+
ArrayRef<std::string> compiledCandidates,
184191
ArrayRef<StringRef> buildCommands,
185192
ArrayRef<StringRef> extraPCMArgs,
186193
StringRef contextHash) {
187194
std::string compiledModulePath;
188195
return ModuleDependencies(
189196
std::make_unique<SwiftModuleDependenciesStorage>(
190-
compiledModulePath, swiftInterfaceFile, buildCommands,
197+
compiledModulePath, swiftInterfaceFile, compiledCandidates, buildCommands,
191198
extraPCMArgs, contextHash));
192199
}
193200

@@ -196,7 +203,7 @@ class ModuleDependencies {
196203
const std::string &compiledModulePath) {
197204
return ModuleDependencies(
198205
std::make_unique<SwiftModuleDependenciesStorage>(
199-
compiledModulePath, None, ArrayRef<StringRef>(),
206+
compiledModulePath, None, ArrayRef<std::string>(), ArrayRef<StringRef>(),
200207
ArrayRef<StringRef>(), StringRef()));
201208
}
202209

@@ -205,8 +212,8 @@ class ModuleDependencies {
205212
std::string compiledModulePath;
206213
return ModuleDependencies(
207214
std::make_unique<SwiftModuleDependenciesStorage>(
208-
compiledModulePath, None, ArrayRef<StringRef>(), extraPCMArgs,
209-
StringRef()));
215+
compiledModulePath, None, ArrayRef<std::string>(),
216+
ArrayRef<StringRef>(), extraPCMArgs, StringRef()));
210217
}
211218

212219
/// Describe the module dependencies for a Clang module that can be

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,9 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
237237
bool SerializeDependencyHashes, bool TrackSystemDependencies,
238238
ModuleInterfaceLoaderOptions Opts);
239239

240-
std::string getUpToDateCompiledModuleForInterface(StringRef moduleName,
241-
StringRef interfacePath) override;
240+
std::vector<std::string>
241+
getCompiledModuleCandidatesForInterface(StringRef moduleName,
242+
StringRef interfacePath) override;
242243
};
243244

244245
struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,10 @@ class SerializedModuleLoaderBase : public ModuleLoader {
201201
StringRef moduleName, ModuleDependenciesCache &cache,
202202
InterfaceSubContextDelegate &delegate) override;
203203

204-
virtual std::string getUpToDateCompiledModuleForInterface(StringRef moduleName,
205-
StringRef interfacePath) {
206-
return std::string();
204+
virtual std::vector<std::string>
205+
getCompiledModuleCandidatesForInterface(StringRef moduleName,
206+
StringRef interfacePath) {
207+
return std::vector<std::string>();
207208
}
208209
};
209210

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,9 +1015,9 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
10151015
return std::error_code();
10161016
}
10171017

1018-
std::string
1019-
ModuleInterfaceLoader::getUpToDateCompiledModuleForInterface(StringRef moduleName,
1020-
StringRef interfacePath) {
1018+
std::vector<std::string>
1019+
ModuleInterfaceLoader::getCompiledModuleCandidatesForInterface(StringRef moduleName,
1020+
StringRef interfacePath) {
10211021
// Derive .swiftmodule path from the .swiftinterface path.
10221022
auto newExt = file_types::getExtension(file_types::TY_SwiftModuleFile);
10231023
llvm::SmallString<32> modulePath = interfacePath;
@@ -1030,9 +1030,14 @@ ModuleInterfaceLoader::getUpToDateCompiledModuleForInterface(StringRef moduleNam
10301030
llvm::is_contained(PreferInterfaceForModules, moduleName) ?
10311031
ModuleLoadingMode::PreferInterface : LoadMode);
10321032
SmallVector<FileDependency, 16> allDeps;
1033-
std::string usableModulePath;
1034-
Impl.discoverUpToDateCompiledModuleForInterface(allDeps, usableModulePath);
1035-
return usableModulePath;
1033+
std::vector<std::string> results;
1034+
auto pair = Impl.getCompiledModuleCandidates();
1035+
// Add compiled module candidates only when they are non-empty.
1036+
if (!pair.first.empty())
1037+
results.push_back(pair.first);
1038+
if (!pair.second.empty())
1039+
results.push_back(pair.second);
1040+
return results;
10361041
}
10371042

10381043
bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(

lib/FrontendTool/ScanDependencies.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,17 @@ static void writeJSON(llvm::raw_ostream &out,
339339
}
340340
out.indent(5 * 2);
341341
out << "],\n";
342+
out.indent(5 * 2);
343+
out << "\"compiledModuleCandidates\": [\n";
344+
for (auto &candidate: swiftDeps->compiledModuleCandidates) {
345+
out.indent(6 * 2);
346+
out << "\"" << candidate << "\"";
347+
if (&candidate != &swiftDeps->compiledModuleCandidates.back())
348+
out << ",";
349+
out << "\n";
350+
}
351+
out.indent(5 * 2);
352+
out << "],\n";
342353
} else if (!swiftDeps->compiledModulePath.empty()) {
343354
writeJSONSingleField(
344355
out, "compiledModulePath",

lib/Serialization/ModuleDependencyScanner.cpp

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,6 @@ class ModuleDependencyScanner : public SerializedModuleLoaderBase {
4444
/*IgnoreSwiftSourceInfoFile=*/true),
4545
moduleName(moduleName), astDelegate(astDelegate) { }
4646

47-
std::string getCompiledModulePath(const SerializedModuleBaseName &BaseName) {
48-
if (LoadMode == ModuleLoadingMode::OnlySerialized) {
49-
return BaseName.getName(file_types::TY_SwiftModuleFile);
50-
}
51-
return static_cast<SerializedModuleLoaderBase*>(Ctx
52-
.getModuleInterfaceLoader())->getUpToDateCompiledModuleForInterface(
53-
moduleName.str(),
54-
BaseName.getName(file_types::TY_SwiftModuleInterfaceFile));
55-
}
56-
5747
virtual std::error_code findModuleFilesInDirectory(
5848
AccessPathElem ModuleID,
5949
const SerializedModuleBaseName &BaseName,
@@ -65,26 +55,23 @@ class ModuleDependencyScanner : public SerializedModuleLoaderBase {
6555

6656
auto &fs = *Ctx.SourceMgr.getFileSystem();
6757

68-
// Compute the full path of the module we're looking for.
69-
auto ModPath = getCompiledModulePath(BaseName);
58+
auto ModPath = BaseName.getName(file_types::TY_SwiftModuleFile);
59+
auto InPath = BaseName.getName(file_types::TY_SwiftModuleInterfaceFile);
7060

71-
if (fs.exists(ModPath)) {
72-
// The module file will be loaded directly.
73-
auto dependencies = scanModuleFile(ModPath);
74-
if (dependencies) {
75-
this->dependencies = std::move(dependencies.get());
76-
return std::error_code();
61+
if (LoadMode == ModuleLoadingMode::OnlySerialized || !fs.exists(InPath)) {
62+
if (fs.exists(ModPath)) {
63+
// The module file will be loaded directly.
64+
auto dependencies = scanModuleFile(ModPath);
65+
if (dependencies) {
66+
this->dependencies = std::move(dependencies.get());
67+
return std::error_code();
68+
}
69+
return dependencies.getError();
70+
} else {
71+
return std::make_error_code(std::errc::no_such_file_or_directory);
7772
}
78-
79-
return dependencies.getError();
8073
}
81-
82-
// Check whether the .swiftinterface exists.
83-
auto InPath = BaseName.getName(file_types::TY_SwiftModuleInterfaceFile);
84-
85-
if (!fs.exists(InPath))
86-
return std::make_error_code(std::errc::no_such_file_or_directory);
87-
74+
assert(fs.exists(InPath));
8875
auto dependencies = scanInterfaceFile(InPath);
8976
if (dependencies) {
9077
this->dependencies = std::move(dependencies.get());
@@ -101,6 +88,14 @@ class ModuleDependencyScanner : public SerializedModuleLoaderBase {
10188
};
10289
}
10390

91+
static std::vector<std::string> getCompiledCandidates(ASTContext &ctx,
92+
StringRef moduleName,
93+
StringRef interfacePath) {
94+
return static_cast<SerializedModuleLoaderBase*>(ctx
95+
.getModuleInterfaceLoader())->getCompiledModuleCandidatesForInterface(
96+
moduleName.str(), interfacePath);
97+
}
98+
10499
ErrorOr<ModuleDependencies> ModuleDependencyScanner::scanInterfaceFile(
105100
Twine moduleInterfacePath) {
106101
// Create a module filename.
@@ -117,7 +112,11 @@ ErrorOr<ModuleDependencies> ModuleDependencyScanner::scanInterfaceFile(
117112
SourceLoc(),
118113
[&](ASTContext &Ctx, ArrayRef<StringRef> Args,
119114
ArrayRef<StringRef> PCMArgs, StringRef Hash) {
120-
Result = ModuleDependencies::forSwiftInterface(moduleInterfacePath.str(),
115+
std::string InPath = moduleInterfacePath.str();
116+
auto compiledCandidates = getCompiledCandidates(Ctx, moduleName.str(),
117+
InPath);
118+
Result = ModuleDependencies::forSwiftInterface(InPath,
119+
compiledCandidates,
121120
Args,
122121
PCMArgs,
123122
Hash);

test/ScanDependencies/Inputs/ModuleDependencyGraph.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ struct SwiftModuleDetails: Codable {
6363
/// The module interface from which this module was built, if any.
6464
var moduleInterfacePath: String?
6565

66+
/// The paths of potentially ready-to-use compiled modules for the interface.
67+
var compiledModuleCandidates: [String]?
68+
6669
/// The compiled Swift module to use.
6770
var compiledModulePath: String?
6871

test/ScanDependencies/compiled_swift_modules.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55

66
import Foo
77

8-
// HAS_COMPILED: "compiledModulePath": "{{.*}}Foo.swiftmodule{{.*}}.swiftmodule"
9-
// HAS_NO_COMPILED-NOT: "compiledModulePath": "{{.*}}Foo.swiftmodule{{.*}}.swiftmodule"
8+
// HAS_COMPILED: "compiledModuleCandidates": [
9+
// HAS_COMPILED-NEXT: "{{.*}}Foo.swiftmodule{{.*}}.swiftmodule"
10+
11+
// HAS_NO_COMPILED-NOT: "{{.*}}Foo.swiftmodule{{.*}}.swiftmodule"
1012

1113
// Step 1: build swift interface and swift module side by side
1214
// RUN: %target-swift-frontend -emit-module %t/Foo.swift -emit-module-path %t/Foo.swiftmodule/%target-swiftmodule-name -module-name Foo -emit-module-interface-path %t/Foo.swiftmodule/%target-swiftinterface-name
@@ -32,6 +34,6 @@ import Foo
3234
// Step 6: update the interface file from where the prebuilt module cache was built.
3335
// RUN: touch %t/Foo.swiftmodule/%target-swiftinterface-name
3436

35-
// Step 4: scan dependency should give us the interface file.
36-
// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d
37-
// RUN: %FileCheck %s -check-prefix=HAS_NO_COMPILED < %t/deps.json
37+
// Step 7: scan dependency should give us the prebuilt module file even though it's out-of-date.
38+
// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules
39+
// RUN: %FileCheck %s -check-prefix=HAS_COMPILED < %t/deps.json

0 commit comments

Comments
 (0)