Skip to content

Commit b85f547

Browse files
committed
Add an external module dependency test
1 parent b5af62f commit b85f547

File tree

5 files changed

+156
-51
lines changed

5 files changed

+156
-51
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,16 @@ class ModuleDependencies {
230230
fileDependencies));
231231
}
232232

233+
/// Describe an external dependency swift module.
234+
static ModuleDependencies forExternalSwiftModuleStub(
235+
const std::string &compiledModulePath,
236+
const std::string &moduleDocPath,
237+
const std::string &sourceInfoPath) {
238+
return ModuleDependencies(
239+
std::make_unique<ExternalSwiftModuleDependencyStorage>(
240+
compiledModulePath, moduleDocPath, sourceInfoPath));
241+
}
242+
233243
/// Retrieve the path to the compiled module.
234244
const std::string getCompiledModulePath() const {
235245
return storage->compiledModulePath;

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -207,45 +207,6 @@ class ExplicitModuleMapParser {
207207
llvm::StringSaver Saver;
208208
};
209209

210-
///// A ModuleLoader that loads external dependency module stubs specified in
211-
///// -external-dependency-module-map-file
212-
///// This loader is used only in dependency scanning to inform the scanner that a set of modules
213-
///// constitute external dependencies that are not visible to the scanner but will nevertheless be
214-
///// taken care of by the scanner's clients. This "loader" will not attempt to load any module files.
215-
//class ExternalSwiftModuleStubLoader: public SerializedModuleLoaderBase {
216-
// explicit ExternalSwiftModuleStubLoader(ASTContext &ctx, DependencyTracker *tracker,
217-
// ModuleLoadingMode loadMode,
218-
// bool IgnoreSwiftSourceInfoFile);
219-
// std::error_code findModuleFilesInDirectory(
220-
// AccessPathElem ModuleID,
221-
// const SerializedModuleBaseName &BaseName,
222-
// SmallVectorImpl<char> *ModuleInterfacePath,
223-
// std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
224-
// std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
225-
// std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) override;
226-
//
227-
// bool canImportModule(Located<Identifier> mID) override;
228-
//
229-
// bool isCached(StringRef DepPath) override { return false; };
230-
//
231-
// struct Implementation;
232-
// Implementation &Impl;
233-
//public:
234-
// static std::unique_ptr<ExternalSwiftModuleStubLoader>
235-
// create(ASTContext &ctx,
236-
// DependencyTracker *tracker, ModuleLoadingMode loadMode,
237-
// StringRef ExternalDependencyModuleMap,
238-
// bool IgnoreSwiftSourceInfoFile);
239-
//
240-
// /// Append visible module names to \p names. Note that names are possibly
241-
// /// duplicated, and not guaranteed to be ordered in any way.
242-
// void collectVisibleTopLevelModuleNames(
243-
// SmallVectorImpl<Identifier> &names) const override;
244-
//
245-
// /// Actual record of the decoded stub.
246-
// Optional<ModuleDependencies> dependencies;
247-
//};
248-
249210
struct ModuleInterfaceLoaderOptions {
250211
bool remarkOnRebuildFromInterface = false;
251212
bool disableInterfaceLock = false;

lib/Serialization/ModuleDependencyScanner.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ class ModuleDependencyScanner : public SerializedModuleLoaderBase {
9898
/// set of modules constitute external dependencies that are not visible to the
9999
/// scanner but will nevertheless be provided by the scanner's clients.
100100
/// This "loader" will not attempt to load any module files.
101-
class ExternalSwiftModuleStubLoader : public ModuleDependencyScanner {
101+
class ExternalSwiftModuleStubScanner : public ModuleDependencyScanner {
102102
/// Scan the given external module map
103103
void parseExternalModuleMap(StringRef fileName);
104104
llvm::StringMap<ExplicitModuleInfo> ExternalDependencyModuleMap;
105105

106106
public:
107-
ExternalSwiftModuleStubLoader(ASTContext &ctx, ModuleLoadingMode LoadMode,
107+
ExternalSwiftModuleStubScanner(ASTContext &ctx, ModuleLoadingMode LoadMode,
108108
Identifier moduleName,
109109
StringRef ExternalDependencyModuleMap,
110110
InterfaceSubContextDelegate &astDelegate)
@@ -141,14 +141,14 @@ class ExternalSwiftModuleStubLoader : public ModuleDependencyScanner {
141141
}
142142

143143
public:
144-
static std::unique_ptr<ExternalSwiftModuleStubLoader>
144+
static std::unique_ptr<ExternalSwiftModuleStubScanner>
145145
create(ASTContext &ctx, DependencyTracker *tracker,
146146
ModuleLoadingMode loadMode, StringRef ExternalDependencyModuleMap,
147147
bool IgnoreSwiftSourceInfoFile);
148148
};
149149
} // namespace
150150

151-
void ExternalSwiftModuleStubLoader::parseExternalModuleMap(StringRef fileName) {
151+
void ExternalSwiftModuleStubScanner::parseExternalModuleMap(StringRef fileName) {
152152
ExplicitModuleMapParser parser(Ctx);
153153
auto result =
154154
parser.parseSwiftExplicitModuleMap(fileName, ExternalDependencyModuleMap);
@@ -229,6 +229,15 @@ Optional<ModuleDependencies> SerializedModuleLoaderBase::getModuleDependencies(
229229
cache.findDependencies(moduleName, ModuleDependenciesKind::SwiftExternal))
230230
return found;
231231

232+
auto moduleId = Ctx.getIdentifier(moduleName);
233+
// Instantiate dependency scanning "loaders".
234+
SmallVector<std::unique_ptr<ModuleDependencyScanner>, 2> scanners;
235+
scanners.push_back(std::make_unique<ModuleDependencyScanner>(
236+
Ctx, LoadMode, moduleId, delegate));
237+
scanners.push_back(std::make_unique<ExternalSwiftModuleStubScanner>(
238+
Ctx, LoadMode, moduleId, Ctx.SearchPathOpts.ExternalDependencyModuleMap,
239+
delegate));
240+
232241
// Check whether there is a module with this name that we can import.
233242
for (auto &scanner : scanners) {
234243
if (scanner->canImportModule({moduleId, SourceLoc()})) {

test/ScanDependencies/Inputs/ModuleDependencyGraph.swift

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,22 @@ import Foundation
1313

1414
enum ModuleDependencyId: Hashable {
1515
case swift(String)
16+
case swiftExternal(String)
1617
case clang(String)
1718

1819
var moduleName: String {
1920
switch self {
20-
case .swift(let name): return name
21-
case .clang(let name): return name
21+
case .swift(let name): return name
22+
case .swiftExternal(let name): return name
23+
case .clang(let name): return name
2224
}
2325
}
2426
}
2527

2628
extension ModuleDependencyId: Codable {
2729
enum CodingKeys: CodingKey {
2830
case swift
31+
case swiftExternal
2932
case clang
3033
}
3134

@@ -35,8 +38,13 @@ extension ModuleDependencyId: Codable {
3538
let moduleName = try container.decode(String.self, forKey: .swift)
3639
self = .swift(moduleName)
3740
} catch {
38-
let moduleName = try container.decode(String.self, forKey: .clang)
39-
self = .clang(moduleName)
41+
do {
42+
let moduleName = try container.decode(String.self, forKey: .swiftExternal)
43+
self = .swiftExternal(moduleName)
44+
} catch {
45+
let moduleName = try container.decode(String.self, forKey: .clang)
46+
self = .clang(moduleName)
47+
}
4048
}
4149
}
4250

@@ -45,6 +53,8 @@ extension ModuleDependencyId: Codable {
4553
switch self {
4654
case .swift(let moduleName):
4755
try container.encode(moduleName, forKey: .swift)
56+
case .swiftExternal(let moduleName):
57+
try container.encode(moduleName, forKey: .swift)
4858
case .clang(let moduleName):
4959
try container.encode(moduleName, forKey: .clang)
5060
}
@@ -82,6 +92,15 @@ struct SwiftModuleDetails: Codable {
8292
var extraPcmArgs: [String]?
8393
}
8494

95+
/// Details specific to Swift external modules.
96+
struct SwiftExternalModuleDetails: Codable {
97+
/// The path to the .swiftModuleDoc file.
98+
var moduleDocPath: String?
99+
100+
/// The path to the .swiftSourceInfo file.
101+
var moduleSourceInfoPath: String?
102+
}
103+
85104
/// Details specific to Clang modules.
86105
struct ClangModuleDetails: Codable {
87106
/// The path to the module map used to build this module.
@@ -100,10 +119,10 @@ struct ModuleDependencies: Codable {
100119
var modulePath: String
101120

102121
/// The source files used to build this module.
103-
var sourceFiles: [String] = []
122+
var sourceFiles: [String]? = []
104123

105124
/// The set of direct module dependencies of this module.
106-
var directDependencies: [ModuleDependencyId] = []
125+
var directDependencies: [ModuleDependencyId]? = []
107126

108127
/// Specific details of a particular kind of module.
109128
var details: Details
@@ -114,6 +133,10 @@ struct ModuleDependencies: Codable {
114133
/// a bridging header.
115134
case swift(SwiftModuleDetails)
116135

136+
/// Swift external modules carry additional details that specify their
137+
/// module doc path and source info paths.
138+
case swiftExternal(SwiftExternalModuleDetails)
139+
117140
/// Clang modules are built from a module map file.
118141
case clang(ClangModuleDetails)
119142
}
@@ -122,6 +145,7 @@ struct ModuleDependencies: Codable {
122145
extension ModuleDependencies.Details: Codable {
123146
enum CodingKeys: CodingKey {
124147
case swift
148+
case swiftExternal
125149
case clang
126150
}
127151

@@ -131,8 +155,13 @@ extension ModuleDependencies.Details: Codable {
131155
let details = try container.decode(SwiftModuleDetails.self, forKey: .swift)
132156
self = .swift(details)
133157
} catch {
134-
let details = try container.decode(ClangModuleDetails.self, forKey: .clang)
135-
self = .clang(details)
158+
do {
159+
let details = try container.decode(SwiftExternalModuleDetails.self, forKey: .swiftExternal)
160+
self = .swiftExternal(details)
161+
} catch {
162+
let details = try container.decode(ClangModuleDetails.self, forKey: .clang)
163+
self = .clang(details)
164+
}
136165
}
137166
}
138167

@@ -141,6 +170,8 @@ extension ModuleDependencies.Details: Codable {
141170
switch self {
142171
case .swift(let details):
143172
try container.encode(details, forKey: .swift)
173+
case .swiftExternal(let details):
174+
try container.encode(details, forKey: .swiftExternal)
144175
case .clang(let details):
145176
try container.encode(details, forKey: .clang)
146177
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: mkdir -p %t/clang-module-cache
3+
// RUN: mkdir -p %t/inputs
4+
5+
// RUN: echo "[{" > %/t/inputs/map.json
6+
// RUN: echo "\"moduleName\": \"SomeExternalModule\"," >> %/t/inputs/map.json
7+
// RUN: echo "\"modulePath\": \"%/t/inputs/SomeExternalModule.swiftmodule\"," >> %/t/inputs/map.json
8+
// RUN: echo "\"docPath\": \"%/t/inputs/SomeExternalModule.swiftdoc\"," >> %/t/inputs/map.json
9+
// RUN: echo "\"sourceInfoPath\": \"%/t/inputs/SomeExternalModule.swiftsourceinfo\"" >> %/t/inputs/map.json
10+
// RUN: echo "}]" >> %/t/inputs/map.json
11+
12+
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -external-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -disable-implicit-swift-modules -Xcc -Xclang -Xcc -fno-implicit-modules
13+
14+
// Check the contents of the JSON output
15+
// RUN: %FileCheck %s < %t/deps.json
16+
17+
// Check the make-style dependencies file
18+
// RUN: %FileCheck %s -check-prefix CHECK-MAKE-DEPS < %t/deps.d
19+
20+
// Check that the JSON parses correctly into the canonical Swift data
21+
// structures.
22+
23+
// RUN: mkdir -p %t/PrintGraph
24+
// RUN: cp %S/Inputs/PrintGraph.swift %t/main.swift
25+
// RUN: %target-build-swift %S/Inputs/ModuleDependencyGraph.swift %t/main.swift -o %t/main
26+
// RUN: %target-codesign %t/main
27+
// RUN: %target-run %t/main %t/deps.json
28+
29+
// REQUIRES: executable_test
30+
// REQUIRES: objc_interop
31+
import SomeExternalModule
32+
33+
// CHECK: "mainModuleName": "deps"
34+
35+
/// --------Main module
36+
// CHECK-LABEL: "modulePath": "deps.swiftmodule",
37+
// CHECK-NEXT: sourceFiles
38+
// CHECK-NEXT: module_deps_external.swift
39+
40+
// CHECK: directDependencies
41+
// CHECK-NEXT: {
42+
// CHECK-NEXT: "swiftExternal": "SomeExternalModule"
43+
// CHECK-NEXT: }
44+
// CHECK-NEXT: {
45+
// CHECK-NEXT: "swift": "Swift"
46+
// CHECK-NEXT: }
47+
// CHECK-NEXT: {
48+
// CHECK-NEXT: "swift": "SwiftOnoneSupport"
49+
// CHECK-NEXT: }
50+
// CHECK-NEXT: {
51+
// CHECK-NEXT: "swift": "F"
52+
// CHECK-NEXT: }
53+
// CHECK-NEXT: ],
54+
55+
// CHECK: "extraPcmArgs": [
56+
// CHECK-NEXT: "-Xcc",
57+
// CHECK-NEXT: "-target",
58+
// CHECK-NEXT: "-Xcc",
59+
// CHECK: "-fapinotes-swift-version=4"
60+
61+
// CHECK: "bridgingHeader":
62+
// CHECK-NEXT: "path":
63+
// CHECK-SAME: Bridging.h
64+
65+
// CHECK-NEXT: "sourceFiles":
66+
// CHECK-NEXT: Bridging.h
67+
// CHECK-NEXT: BridgingOther.h
68+
69+
// CHECK: "moduleDependencies": [
70+
// CHECK-NEXT: "F"
71+
// CHECK-NEXT: ]
72+
73+
/// --------Swift external module SomeExternalModule
74+
// CHECK-LABEL: "modulePath": "BUILD_DIR/test-macosx-x86_64/ScanDependencies/Output/module_deps_external.swift.tmp/inputs/SomeExternalModule.swiftmodule",
75+
// CHECK-NEXT: "details": {
76+
// CHECK-NEXT: "swiftExternal": {
77+
// CHECK-NEXT: "moduleDocPath": "BUILD_DIR/test-macosx-x86_64/ScanDependencies/Output/module_deps_external.swift.tmp/inputs/SomeExternalModule.swiftdoc",
78+
// CHECK-NEXT: "moduleSourceInfoPath": "BUILD_DIR/test-macosx-x86_64/ScanDependencies/Output/module_deps_external.swift.tmp/inputs/SomeExternalModule.swiftsourceinfo",
79+
80+
/// --------Swift module Swift
81+
// CHECK-LABEL: "modulePath": "Swift.swiftmodule",
82+
83+
// CHECK: directDependencies
84+
// CHECK-NEXT: {
85+
// CHECK-NEXT: "clang": "SwiftShims"
86+
87+
/// --------Clang module SwiftShims
88+
// CHECK-LABEL: "modulePath": "SwiftShims.pcm",
89+
90+
// Check make-style dependencies
91+
// CHECK-MAKE-DEPS: module_deps_external.swift
92+
// CHECK-MAKE-DEPS-SAME: Bridging.h
93+
// CHECK-MAKE-DEPS-SAME: BridgingOther.h
94+
// CHECK-MAKE-DEPS-SAME: module.modulemap

0 commit comments

Comments
 (0)