Skip to content

Commit 1c1a263

Browse files
committed
Factor out Explicit Module Map parsing into a standalone utility.
1 parent 8a45c9c commit 1c1a263

File tree

2 files changed

+154
-87
lines changed

2 files changed

+154
-87
lines changed

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,90 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
162162
~ExplicitSwiftModuleLoader();
163163
};
164164

165+
/// Information about explicitly specified Swift module files.
166+
struct ExplicitModuleInfo {
167+
// Path of the .swiftmodule file.
168+
StringRef modulePath;
169+
// Path of the .swiftmoduledoc file.
170+
StringRef moduleDocPath;
171+
// Path of the .swiftsourceinfo file.
172+
StringRef moduleSourceInfoPath;
173+
// Opened buffer for the .swiftmodule file.
174+
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
175+
};
176+
177+
/// Parser of explicit module maps passed into the compiler.
178+
// [
179+
// {
180+
// "moduleName": "A",
181+
// "modulePath": "A.swiftmodule",
182+
// "docPath": "A.swiftdoc",
183+
// "sourceInfoPath": "A.swiftsourceinfo"
184+
// },
185+
// {
186+
// "moduleName": "B",
187+
// "modulePath": "B.swiftmodule",
188+
// "docPath": "B.swiftdoc",
189+
// "sourceInfoPath": "B.swiftsourceinfo"
190+
// }
191+
// ]
192+
class ExplicitModuleMapParser {
193+
public:
194+
ExplicitModuleMapParser(ASTContext &Ctx) : Ctx(Ctx), Saver(Allocator) {}
195+
196+
std::error_code
197+
parseSwiftExplicitModuleMap(const StringRef fileName,
198+
llvm::StringMap<ExplicitModuleInfo> &moduleMap);
199+
200+
private:
201+
StringRef getScalaNodeText(llvm::yaml::Node *N);
202+
bool parseSingleModuleEntry(llvm::yaml::Node &node,
203+
llvm::StringMap<ExplicitModuleInfo> &moduleMap);
204+
205+
ASTContext &Ctx;
206+
llvm::BumpPtrAllocator Allocator;
207+
llvm::StringSaver Saver;
208+
};
209+
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+
165249
struct ModuleInterfaceLoaderOptions {
166250
bool remarkOnRebuildFromInterface = false;
167251
bool disableInterfaceLock = false;

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 70 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,105 +1512,88 @@ bool InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleN
15121512
}
15131513

15141514
struct ExplicitSwiftModuleLoader::Implementation {
1515-
// Information about explicitly specified Swift module files.
1516-
struct ExplicitModuleInfo {
1517-
// Path of the .swiftmodule file.
1518-
StringRef modulePath;
1519-
// Path of the .swiftmoduledoc file.
1520-
StringRef moduleDocPath;
1521-
// Path of the .swiftsourceinfo file.
1522-
StringRef moduleSourceInfoPath;
1523-
// Opened buffer for the .swiftmodule file.
1524-
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
1525-
};
15261515
ASTContext &Ctx;
1527-
llvm::BumpPtrAllocator Allocator;
1528-
llvm::StringSaver Saver;
15291516
llvm::StringMap<ExplicitModuleInfo> ExplicitModuleMap;
1530-
Implementation(ASTContext &Ctx): Ctx(Ctx), Saver(Allocator) {}
1517+
Implementation(ASTContext &Ctx) : Ctx(Ctx) {}
15311518

1532-
StringRef getScalaNodeText(llvm::yaml::Node *N) {
1533-
SmallString<32> Buffer;
1534-
return Saver.save(cast<llvm::yaml::ScalarNode>(N)->getValue(Buffer));
1519+
void parseSwiftExplicitModuleMap(StringRef fileName) {
1520+
ExplicitModuleMapParser parser(Ctx);
1521+
auto result =
1522+
parser.parseSwiftExplicitModuleMap(fileName, ExplicitModuleMap);
1523+
if (result == std::errc::invalid_argument)
1524+
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
1525+
fileName);
1526+
else if (result == std::errc::no_such_file_or_directory)
1527+
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_missing,
1528+
fileName);
15351529
}
1530+
};
15361531

1537-
bool parseSingleModuleEntry(llvm::yaml::Node &node) {
1538-
using namespace llvm::yaml;
1539-
auto *mapNode = dyn_cast<MappingNode>(&node);
1540-
if (!mapNode)
1541-
return true;
1542-
StringRef moduleName;
1543-
ExplicitModuleInfo result;
1544-
for (auto &entry: *mapNode) {
1545-
auto key = getScalaNodeText(entry.getKey());
1546-
auto val = getScalaNodeText(entry.getValue());
1547-
if (key == "moduleName") {
1548-
moduleName = val;
1549-
} else if (key == "modulePath") {
1550-
result.modulePath = val;
1551-
} else if (key == "docPath") {
1552-
result.moduleDocPath = val;
1553-
} else if (key == "sourceInfoPath") {
1554-
result.moduleSourceInfoPath = val;
1555-
} else {
1556-
// Being forgiving for future fields.
1557-
continue;
1558-
}
1532+
StringRef ExplicitModuleMapParser::getScalaNodeText(llvm::yaml::Node *N) {
1533+
SmallString<32> Buffer;
1534+
return Saver.save(cast<llvm::yaml::ScalarNode>(N)->getValue(Buffer));
1535+
}
1536+
1537+
bool ExplicitModuleMapParser::parseSingleModuleEntry(
1538+
llvm::yaml::Node &node, llvm::StringMap<ExplicitModuleInfo> &moduleMap) {
1539+
using namespace llvm::yaml;
1540+
auto *mapNode = dyn_cast<MappingNode>(&node);
1541+
if (!mapNode)
1542+
return true;
1543+
StringRef moduleName;
1544+
ExplicitModuleInfo result;
1545+
for (auto &entry : *mapNode) {
1546+
auto key = getScalaNodeText(entry.getKey());
1547+
auto val = getScalaNodeText(entry.getValue());
1548+
if (key == "moduleName") {
1549+
moduleName = val;
1550+
} else if (key == "modulePath") {
1551+
result.modulePath = val;
1552+
} else if (key == "docPath") {
1553+
result.moduleDocPath = val;
1554+
} else if (key == "sourceInfoPath") {
1555+
result.moduleSourceInfoPath = val;
1556+
} else {
1557+
// Being forgiving for future fields.
1558+
continue;
15591559
}
1560-
if (moduleName.empty())
1561-
return true;
1562-
ExplicitModuleMap[moduleName] = std::move(result);
1563-
return false;
15641560
}
1565-
// [
1566-
// {
1567-
// "moduleName": "A",
1568-
// "modulePath": "A.swiftmodule",
1569-
// "docPath": "A.swiftdoc",
1570-
// "sourceInfoPath": "A.swiftsourceinfo"
1571-
// },
1572-
// {
1573-
// "moduleName": "B",
1574-
// "modulePath": "B.swiftmodule",
1575-
// "docPath": "B.swiftdoc",
1576-
// "sourceInfoPath": "B.swiftsourceinfo"
1577-
// }
1578-
// ]
1579-
void parseSwiftExplicitModuleMap(StringRef fileName) {
1580-
using namespace llvm::yaml;
1581-
// Load the input file.
1582-
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
1561+
if (moduleName.empty())
1562+
return true;
1563+
moduleMap[moduleName] = std::move(result);
1564+
return false;
1565+
}
1566+
1567+
std::error_code ExplicitModuleMapParser::parseSwiftExplicitModuleMap(
1568+
const StringRef fileName, llvm::StringMap<ExplicitModuleInfo> &moduleMap) {
1569+
using namespace llvm::yaml;
1570+
// Load the input file.
1571+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
15831572
llvm::MemoryBuffer::getFile(fileName);
1584-
if (!fileBufOrErr) {
1585-
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_missing,
1586-
fileName);
1587-
return;
1588-
}
1589-
StringRef Buffer = fileBufOrErr->get()->getBuffer();
1590-
// Use a new source manager instead of the one from ASTContext because we
1591-
// don't want the JSON file to be persistent.
1592-
llvm::SourceMgr SM;
1593-
Stream Stream(llvm::MemoryBufferRef(Buffer, fileName), SM);
1594-
for (auto DI = Stream.begin(); DI != Stream.end(); ++ DI) {
1595-
assert(DI != Stream.end() && "Failed to read a document");
1596-
if (auto *MN = dyn_cast_or_null<SequenceNode>(DI->getRoot())) {
1597-
for (auto &entry: *MN) {
1598-
if (parseSingleModuleEntry(entry)) {
1599-
Ctx.Diags.diagnose(SourceLoc(),
1600-
diag::explicit_swift_module_map_corrupted,
1601-
fileName);
1602-
return;
1603-
}
1573+
if (!fileBufOrErr) {
1574+
return std::make_error_code(std::errc::no_such_file_or_directory);
1575+
}
1576+
StringRef Buffer = fileBufOrErr->get()->getBuffer();
1577+
// Use a new source manager instead of the one from ASTContext because we
1578+
// don't want the JSON file to be persistent.
1579+
llvm::SourceMgr SM;
1580+
Stream Stream(llvm::MemoryBufferRef(Buffer, fileName), SM);
1581+
for (auto DI = Stream.begin(); DI != Stream.end(); ++DI) {
1582+
assert(DI != Stream.end() && "Failed to read a document");
1583+
if (auto *MN = dyn_cast_or_null<SequenceNode>(DI->getRoot())) {
1584+
for (auto &entry : *MN) {
1585+
if (parseSingleModuleEntry(entry, moduleMap)) {
1586+
return std::make_error_code(std::errc::invalid_argument);
16041587
}
1605-
} else {
1606-
Ctx.Diags.diagnose(SourceLoc(),
1607-
diag::explicit_swift_module_map_corrupted,
1608-
fileName);
1609-
return;
16101588
}
1589+
} else {
1590+
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
1591+
fileName);
1592+
return std::make_error_code(std::errc::invalid_argument);
16111593
}
16121594
}
1613-
};
1595+
return std::error_code{}; // success
1596+
}
16141597

16151598
ExplicitSwiftModuleLoader::ExplicitSwiftModuleLoader(
16161599
ASTContext &ctx,

0 commit comments

Comments
 (0)