mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Allow module aliases to be expressed in the explicit Swift module map JSON file.
For build systems that already generate these files, it makes sense to include the aliases so that the map file serves as a comprehensive index of how the module inputs are referenced.
This commit is contained in:
committed by
Tony Allevato
parent
2b0f9aa765
commit
8752920875
@@ -615,6 +615,10 @@ public:
|
|||||||
/// are the real (physical) module names on disk.
|
/// are the real (physical) module names on disk.
|
||||||
void setModuleAliases(const llvm::StringMap<StringRef> &aliasMap);
|
void setModuleAliases(const llvm::StringMap<StringRef> &aliasMap);
|
||||||
|
|
||||||
|
/// Adds a given alias to the map of Identifiers between module aliases and
|
||||||
|
/// their actual names.
|
||||||
|
void addModuleAlias(StringRef moduleAlias, StringRef realName);
|
||||||
|
|
||||||
/// Look up option used in \c getRealModuleName when module aliasing is applied.
|
/// Look up option used in \c getRealModuleName when module aliasing is applied.
|
||||||
enum class ModuleAliasLookupOption {
|
enum class ModuleAliasLookupOption {
|
||||||
alwaysRealName,
|
alwaysRealName,
|
||||||
|
|||||||
@@ -318,10 +318,11 @@ class ExplicitModuleMapParser {
|
|||||||
public:
|
public:
|
||||||
ExplicitModuleMapParser(llvm::BumpPtrAllocator &Allocator) : Saver(Allocator) {}
|
ExplicitModuleMapParser(llvm::BumpPtrAllocator &Allocator) : Saver(Allocator) {}
|
||||||
|
|
||||||
std::error_code
|
std::error_code parseSwiftExplicitModuleMap(
|
||||||
parseSwiftExplicitModuleMap(llvm::MemoryBufferRef BufferRef,
|
llvm::MemoryBufferRef BufferRef,
|
||||||
llvm::StringMap<ExplicitSwiftModuleInputInfo> &swiftModuleMap,
|
llvm::StringMap<ExplicitSwiftModuleInputInfo> &swiftModuleMap,
|
||||||
llvm::StringMap<ExplicitClangModuleInputInfo> &clangModuleMap) {
|
llvm::StringMap<ExplicitClangModuleInputInfo> &clangModuleMap,
|
||||||
|
llvm::StringMap<std::string> &moduleAliases) {
|
||||||
using namespace llvm::yaml;
|
using namespace llvm::yaml;
|
||||||
// Use a new source manager instead of the one from ASTContext because we
|
// Use a new source manager instead of the one from ASTContext because we
|
||||||
// don't want the JSON file to be persistent.
|
// don't want the JSON file to be persistent.
|
||||||
@@ -331,7 +332,8 @@ public:
|
|||||||
assert(DI != Stream.end() && "Failed to read a document");
|
assert(DI != Stream.end() && "Failed to read a document");
|
||||||
if (auto *MN = dyn_cast_or_null<SequenceNode>(DI->getRoot())) {
|
if (auto *MN = dyn_cast_or_null<SequenceNode>(DI->getRoot())) {
|
||||||
for (auto &entry : *MN) {
|
for (auto &entry : *MN) {
|
||||||
if (parseSingleModuleEntry(entry, swiftModuleMap, clangModuleMap)) {
|
if (parseSingleModuleEntry(entry, swiftModuleMap, clangModuleMap,
|
||||||
|
moduleAliases)) {
|
||||||
return std::make_error_code(std::errc::invalid_argument);
|
return std::make_error_code(std::errc::invalid_argument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -359,16 +361,19 @@ private:
|
|||||||
llvm_unreachable("Unexpected JSON value for isFramework");
|
llvm_unreachable("Unexpected JSON value for isFramework");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseSingleModuleEntry(llvm::yaml::Node &node,
|
bool parseSingleModuleEntry(
|
||||||
|
llvm::yaml::Node &node,
|
||||||
llvm::StringMap<ExplicitSwiftModuleInputInfo> &swiftModuleMap,
|
llvm::StringMap<ExplicitSwiftModuleInputInfo> &swiftModuleMap,
|
||||||
llvm::StringMap<ExplicitClangModuleInputInfo> &clangModuleMap) {
|
llvm::StringMap<ExplicitClangModuleInputInfo> &clangModuleMap,
|
||||||
|
llvm::StringMap<std::string> &moduleAliases) {
|
||||||
using namespace llvm::yaml;
|
using namespace llvm::yaml;
|
||||||
auto *mapNode = dyn_cast<MappingNode>(&node);
|
auto *mapNode = dyn_cast<MappingNode>(&node);
|
||||||
if (!mapNode)
|
if (!mapNode)
|
||||||
return true;
|
return true;
|
||||||
StringRef moduleName;
|
StringRef moduleName;
|
||||||
std::optional<std::string> swiftModulePath, swiftModuleDocPath,
|
std::optional<std::string> swiftModulePath, swiftModuleDocPath,
|
||||||
swiftModuleSourceInfoPath, swiftModuleCacheKey, clangModuleCacheKey;
|
swiftModuleSourceInfoPath, swiftModuleCacheKey, clangModuleCacheKey,
|
||||||
|
moduleAlias;
|
||||||
std::optional<std::vector<std::string>> headerDependencyPaths;
|
std::optional<std::vector<std::string>> headerDependencyPaths;
|
||||||
std::string clangModuleMapPath = "", clangModulePath = "";
|
std::string clangModuleMapPath = "", clangModulePath = "";
|
||||||
bool isFramework = false, isSystem = false,
|
bool isFramework = false, isSystem = false,
|
||||||
@@ -405,6 +410,8 @@ private:
|
|||||||
clangModuleCacheKey = val.str();
|
clangModuleCacheKey = val.str();
|
||||||
} else if (key == "isBridgingHeaderDependency") {
|
} else if (key == "isBridgingHeaderDependency") {
|
||||||
isBridgingHeaderDependency = parseBoolValue(val);
|
isBridgingHeaderDependency = parseBoolValue(val);
|
||||||
|
} else if (key == "moduleAlias") {
|
||||||
|
moduleAlias = val.str();
|
||||||
} else {
|
} else {
|
||||||
// Being forgiving for future fields.
|
// Being forgiving for future fields.
|
||||||
continue;
|
continue;
|
||||||
@@ -439,6 +446,9 @@ private:
|
|||||||
clangModuleCacheKey);
|
clangModuleCacheKey);
|
||||||
didInsert = clangModuleMap.try_emplace(moduleName, std::move(entry)).second;
|
didInsert = clangModuleMap.try_emplace(moduleName, std::move(entry)).second;
|
||||||
}
|
}
|
||||||
|
if (didInsert && moduleAlias.has_value()) {
|
||||||
|
moduleAliases[*moduleAlias] = moduleName;
|
||||||
|
}
|
||||||
// Prevent duplicate module names.
|
// Prevent duplicate module names.
|
||||||
return !didInsert;
|
return !didInsert;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2136,14 +2136,18 @@ void ASTContext::setModuleAliases(const llvm::StringMap<StringRef> &aliasMap) {
|
|||||||
for (auto k: aliasMap.keys()) {
|
for (auto k: aliasMap.keys()) {
|
||||||
auto v = aliasMap.lookup(k);
|
auto v = aliasMap.lookup(k);
|
||||||
if (!v.empty()) {
|
if (!v.empty()) {
|
||||||
auto key = getIdentifier(k);
|
addModuleAlias(k, v);
|
||||||
auto val = getIdentifier(v);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTContext::addModuleAlias(StringRef moduleAlias, StringRef realName) {
|
||||||
|
auto key = getIdentifier(moduleAlias);
|
||||||
|
auto val = getIdentifier(realName);
|
||||||
// key is a module alias, val is its corresponding real name
|
// key is a module alias, val is its corresponding real name
|
||||||
ModuleAliasMap[key] = std::make_pair(val, true);
|
ModuleAliasMap[key] = std::make_pair(val, true);
|
||||||
// add an entry with an alias as key for an easier lookup later
|
// add an entry with an alias as key for an easier lookup later
|
||||||
ModuleAliasMap[val] = std::make_pair(key, false);
|
ModuleAliasMap[val] = std::make_pair(key, false);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Identifier ASTContext::getRealModuleName(Identifier key, ModuleAliasLookupOption option) const {
|
Identifier ASTContext::getRealModuleName(Identifier key, ModuleAliasLookupOption option) const {
|
||||||
|
|||||||
@@ -2183,6 +2183,14 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
|
|||||||
return action(info);
|
return action(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void addModuleAliasesFromExplicitSwiftModuleMap(
|
||||||
|
ASTContext &Ctx, llvm::StringMap<std::string> ModuleAliases) {
|
||||||
|
for (auto &entry : ModuleAliases) {
|
||||||
|
Ctx.addModuleAlias(/*moduleAlias=*/entry.getKey(),
|
||||||
|
/*realModule=*/entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ExplicitSwiftModuleLoader::Implementation {
|
struct ExplicitSwiftModuleLoader::Implementation {
|
||||||
ASTContext &Ctx;
|
ASTContext &Ctx;
|
||||||
llvm::BumpPtrAllocator Allocator;
|
llvm::BumpPtrAllocator Allocator;
|
||||||
@@ -2192,6 +2200,7 @@ struct ExplicitSwiftModuleLoader::Implementation {
|
|||||||
void parseSwiftExplicitModuleMap(StringRef fileName) {
|
void parseSwiftExplicitModuleMap(StringRef fileName) {
|
||||||
ExplicitModuleMapParser parser(Allocator);
|
ExplicitModuleMapParser parser(Allocator);
|
||||||
llvm::StringMap<ExplicitClangModuleInputInfo> ExplicitClangModuleMap;
|
llvm::StringMap<ExplicitClangModuleInputInfo> ExplicitClangModuleMap;
|
||||||
|
llvm::StringMap<std::string> ModuleAliases;
|
||||||
// Load the input file.
|
// Load the input file.
|
||||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
|
||||||
llvm::MemoryBuffer::getFile(fileName);
|
llvm::MemoryBuffer::getFile(fileName);
|
||||||
@@ -2203,7 +2212,7 @@ struct ExplicitSwiftModuleLoader::Implementation {
|
|||||||
|
|
||||||
auto hasError = parser.parseSwiftExplicitModuleMap(
|
auto hasError = parser.parseSwiftExplicitModuleMap(
|
||||||
(*fileBufOrErr)->getMemBufferRef(), ExplicitModuleMap,
|
(*fileBufOrErr)->getMemBufferRef(), ExplicitModuleMap,
|
||||||
ExplicitClangModuleMap);
|
ExplicitClangModuleMap, ModuleAliases);
|
||||||
|
|
||||||
if (hasError)
|
if (hasError)
|
||||||
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
|
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
|
||||||
@@ -2230,6 +2239,7 @@ struct ExplicitSwiftModuleLoader::Implementation {
|
|||||||
.str());
|
.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addModuleAliasesFromExplicitSwiftModuleMap(Ctx, ModuleAliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addCommandLineExplicitInputs(
|
void addCommandLineExplicitInputs(
|
||||||
@@ -2462,6 +2472,7 @@ struct ExplicitCASModuleLoader::Implementation {
|
|||||||
void parseSwiftExplicitModuleMap(StringRef ID) {
|
void parseSwiftExplicitModuleMap(StringRef ID) {
|
||||||
ExplicitModuleMapParser parser(Allocator);
|
ExplicitModuleMapParser parser(Allocator);
|
||||||
llvm::StringMap<ExplicitClangModuleInputInfo> ExplicitClangModuleMap;
|
llvm::StringMap<ExplicitClangModuleInputInfo> ExplicitClangModuleMap;
|
||||||
|
llvm::StringMap<std::string> ModuleAliases;
|
||||||
auto buf = loadBuffer(ID);
|
auto buf = loadBuffer(ID);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
Ctx.Diags.diagnose(SourceLoc(), diag::error_cas,
|
Ctx.Diags.diagnose(SourceLoc(), diag::error_cas,
|
||||||
@@ -2477,7 +2488,8 @@ struct ExplicitCASModuleLoader::Implementation {
|
|||||||
llvm::MemoryBuffer::getFile(ID);
|
llvm::MemoryBuffer::getFile(ID);
|
||||||
|
|
||||||
auto hasError = parser.parseSwiftExplicitModuleMap(
|
auto hasError = parser.parseSwiftExplicitModuleMap(
|
||||||
(*buf)->getMemBufferRef(), ExplicitModuleMap, ExplicitClangModuleMap);
|
(*buf)->getMemBufferRef(), ExplicitModuleMap, ExplicitClangModuleMap,
|
||||||
|
ModuleAliases);
|
||||||
|
|
||||||
if (hasError)
|
if (hasError)
|
||||||
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
|
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
|
||||||
@@ -2516,6 +2528,7 @@ struct ExplicitCASModuleLoader::Implementation {
|
|||||||
extraClangArgs.push_back(*cachePath);
|
extraClangArgs.push_back(*cachePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addModuleAliasesFromExplicitSwiftModuleMap(Ctx, ModuleAliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addCommandLineExplicitInputs(
|
void addCommandLineExplicitInputs(
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ void PlaceholderSwiftModuleScanner::parsePlaceholderModuleMap(
|
|||||||
StringRef fileName) {
|
StringRef fileName) {
|
||||||
ExplicitModuleMapParser parser(Allocator);
|
ExplicitModuleMapParser parser(Allocator);
|
||||||
llvm::StringMap<ExplicitClangModuleInputInfo> ClangDependencyModuleMap;
|
llvm::StringMap<ExplicitClangModuleInputInfo> ClangDependencyModuleMap;
|
||||||
|
llvm::StringMap<std::string> ModuleAliases;
|
||||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
|
||||||
llvm::MemoryBuffer::getFile(fileName);
|
llvm::MemoryBuffer::getFile(fileName);
|
||||||
if (!fileBufOrErr) {
|
if (!fileBufOrErr) {
|
||||||
@@ -121,7 +122,7 @@ void PlaceholderSwiftModuleScanner::parsePlaceholderModuleMap(
|
|||||||
}
|
}
|
||||||
auto result = parser.parseSwiftExplicitModuleMap(
|
auto result = parser.parseSwiftExplicitModuleMap(
|
||||||
(*fileBufOrErr)->getMemBufferRef(), PlaceholderDependencyModuleMap,
|
(*fileBufOrErr)->getMemBufferRef(), PlaceholderDependencyModuleMap,
|
||||||
ClangDependencyModuleMap);
|
ClangDependencyModuleMap, ModuleAliases);
|
||||||
if (result == std::errc::invalid_argument) {
|
if (result == std::errc::invalid_argument) {
|
||||||
Ctx.Diags.diagnose(SourceLoc(),
|
Ctx.Diags.diagnose(SourceLoc(),
|
||||||
diag::placeholder_dependency_module_map_corrupted,
|
diag::placeholder_dependency_module_map_corrupted,
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/// Test setting a module alias in the explicit module loader's JSON directly.
|
||||||
|
// UNSUPPORTED: OS=windows-msvc
|
||||||
|
// RUN: %empty-directory(%t)
|
||||||
|
// RUN: mkdir -p %t/inputs
|
||||||
|
// RUN: mkdir -p %t/outputs
|
||||||
|
|
||||||
|
/// Create a module Bar
|
||||||
|
// RUN: echo 'public func bar() {}' > %t/inputs/FileBar.swift
|
||||||
|
// RUN: %target-swift-frontend -module-name Bar %t/inputs/FileBar.swift -emit-module -emit-module-path %t/inputs/Bar.swiftmodule
|
||||||
|
// RUN: %target-swift-emit-pcm -module-name SwiftShims %swift-lib-dir/swift/shims/module.modulemap -o %t/inputs/SwiftShims.pcm
|
||||||
|
// RUN: %target-swift-emit-pcm -module-name _SwiftConcurrencyShims %swift-lib-dir/swift/shims/module.modulemap -o %t/inputs/_SwiftConcurrencyShims.pcm
|
||||||
|
|
||||||
|
/// Check Bar.swiftmodule is created
|
||||||
|
// RUN: test -f %t/inputs/Bar.swiftmodule
|
||||||
|
|
||||||
|
/// Next create an explicit module dependency map to build module Foo
|
||||||
|
// RUN: echo 'import Cat' > %t/inputs/FileFoo.swift
|
||||||
|
|
||||||
|
// RUN: echo "[{" > %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"moduleName\": \"Bar\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"modulePath\": \"%/t/inputs/Bar.swiftmodule\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"moduleAlias\": \"Cat\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "}," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "{" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"moduleName\": \"Swift\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"modulePath\": \"%/stdlib_module\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "}," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "{" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"modulePath\": \"%/ononesupport_module\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "}," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "{" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"moduleName\": \"_Concurrency\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"modulePath\": \"%/concurrency_module\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "}," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "{" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"moduleName\": \"SwiftShims\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"isFramework\": false," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"clangModuleMapPath\": \"%swift-lib-dir/swift/shims/module.modulemap\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"clangModulePath\": \"%t/inputs/SwiftShims.pcm\"" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "}," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "{" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"moduleName\": \"_SwiftConcurrencyShims\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"isFramework\": false," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"clangModuleMapPath\": \"%swift-lib-dir/swift/shims/module.modulemap\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"clangModulePath\": \"%t/inputs/_SwiftConcurrencyShims.pcm\"" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "}," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "{" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"moduleName\": \"_StringProcessing\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"modulePath\": \"%/string_processing_module\"," >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
|
||||||
|
// RUN: echo "}]" >> %/t/inputs/map.json
|
||||||
|
|
||||||
|
/// Create a module Foo that imports Cat aliased to Bar in the JSON above
|
||||||
|
// RUN: %target-swift-frontend -module-name Foo %t/inputs/FileFoo.swift -I %t/inputs -emit-module -emit-module-path %t/outputs/Foo.swiftmodule -disable-implicit-swift-modules -explicit-swift-module-map-file %t/inputs/map.json -Rmodule-loading 2> %t/outputs/load-result.output
|
||||||
|
|
||||||
|
// RUN: test -f %t/outputs/Foo.swiftmodule
|
||||||
|
// RUN: test -f %t/inputs/Bar.swiftmodule
|
||||||
|
// RUN: not test -f %t/inputs/Cat.swiftmodule
|
||||||
|
|
||||||
|
// RUN: %FileCheck %s -input-file %t/outputs/load-result.output -check-prefix CHECK
|
||||||
|
// CHECK: remark: loaded module {{.*}}Bar.swiftmodule
|
||||||
Reference in New Issue
Block a user