mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Load modules using real names if module aliases are used
rdar://83591943
This commit is contained in:
@@ -1848,12 +1848,27 @@ ASTContext::getLoadedModules() const {
|
||||
}
|
||||
|
||||
ModuleDecl *ASTContext::getLoadedModule(Identifier ModuleName) const {
|
||||
return getImpl().LoadedModules.lookup(ModuleName);
|
||||
// Look up a loaded module using an actual module name (physical name
|
||||
// on disk). If the -module-alias option is used, the module name that
|
||||
// appears in source code will be different from the real module name
|
||||
// on disk, otherwise the same.
|
||||
//
|
||||
// For example, if '-module-alias Foo=Bar' is passed in to the frontend,
|
||||
// and a source file has 'import Foo', a module called Bar (real name)
|
||||
// will be loaded and returned.
|
||||
auto realName = getRealModuleName(ModuleName);
|
||||
return getImpl().LoadedModules.lookup(realName);
|
||||
}
|
||||
|
||||
void ASTContext::addLoadedModule(ModuleDecl *M) {
|
||||
assert(M);
|
||||
getImpl().LoadedModules[M->getName()] = M;
|
||||
// Add a loaded module using an actual module name (physical name
|
||||
// on disk), in case -module-alias is used (otherwise same).
|
||||
//
|
||||
// For example, if '-module-alias Foo=Bar' is passed in to the frontend,
|
||||
// and a source file has 'import Foo', a module called Bar (real name)
|
||||
// will be loaded and added to the map.
|
||||
getImpl().LoadedModules[M->getRealName()] = M;
|
||||
}
|
||||
|
||||
void ASTContext::registerGenericSignatureBuilder(
|
||||
|
||||
@@ -1739,7 +1739,13 @@ bool ExplicitSwiftModuleLoader::findModule(ImportPath::Element ModuleID,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
|
||||
bool skipBuildingInterface, bool &IsFramework, bool &IsSystemModule) {
|
||||
StringRef moduleName = ModuleID.Item.str();
|
||||
// Find a module with an actual, physical name on disk, in case
|
||||
// -module-alias is used (otherwise same).
|
||||
//
|
||||
// For example, if '-module-alias Foo=Bar' is passed in to the frontend, and an
|
||||
// input file has 'import Foo', a module called Bar (real name) should be searched.
|
||||
StringRef moduleName = Ctx.getRealModuleName(ModuleID.Item).str();
|
||||
|
||||
auto it = Impl.ExplicitModuleMap.find(moduleName);
|
||||
// If no explicit module path is given matches the name, return with an
|
||||
// error code.
|
||||
|
||||
@@ -34,13 +34,20 @@ using namespace swift;
|
||||
// FIXME: Basically the same as SerializedModuleLoader.
|
||||
using FileOrError = llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>;
|
||||
|
||||
static FileOrError findModule(ASTContext &ctx, StringRef moduleID,
|
||||
static FileOrError findModule(ASTContext &ctx, Identifier moduleID,
|
||||
SourceLoc importLoc) {
|
||||
llvm::SmallString<128> inputFilename;
|
||||
// Find a module with an actual, physical name on disk, in case
|
||||
// -module-alias is used (otherwise same).
|
||||
//
|
||||
// For example, if '-module-alias Foo=Bar' is passed in to the frontend,
|
||||
// and a source file has 'import Foo', a module called Bar (real name)
|
||||
// should be searched.
|
||||
StringRef moduleNameRef = ctx.getRealModuleName(moduleID).str();
|
||||
|
||||
for (auto Path : ctx.SearchPathOpts.ImportSearchPaths) {
|
||||
inputFilename = Path;
|
||||
llvm::sys::path::append(inputFilename, moduleID);
|
||||
llvm::sys::path::append(inputFilename, moduleNameRef);
|
||||
inputFilename.append(".swift");
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
|
||||
ctx.SourceMgr.getFileSystem()->getBufferForFile(inputFilename.str());
|
||||
@@ -66,7 +73,7 @@ bool SourceLoader::canImportModule(ImportPath::Element ID,
|
||||
llvm::VersionTuple version,
|
||||
bool underlyingVersion) {
|
||||
// Search the memory buffers to see if we can find this file on disk.
|
||||
FileOrError inputFileOrError = findModule(Ctx, ID.Item.str(),
|
||||
FileOrError inputFileOrError = findModule(Ctx, ID.Item,
|
||||
ID.Loc);
|
||||
if (!inputFileOrError) {
|
||||
auto err = inputFileOrError.getError();
|
||||
@@ -88,7 +95,7 @@ ModuleDecl *SourceLoader::loadModule(SourceLoc importLoc,
|
||||
|
||||
auto moduleID = path[0];
|
||||
|
||||
FileOrError inputFileOrError = findModule(Ctx, moduleID.Item.str(),
|
||||
FileOrError inputFileOrError = findModule(Ctx, moduleID.Item,
|
||||
moduleID.Loc);
|
||||
if (!inputFileOrError) {
|
||||
auto err = inputFileOrError.getError();
|
||||
|
||||
@@ -533,7 +533,14 @@ SerializedModuleLoaderBase::findModule(ImportPath::Element moduleID,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
|
||||
bool skipBuildingInterface, bool &isFramework, bool &isSystemModule) {
|
||||
SmallString<32> moduleName(moduleID.Item.str());
|
||||
// Find a module with an actual, physical name on disk, in case
|
||||
// -module-alias is used (otherwise same).
|
||||
//
|
||||
// For example, if '-module-alias Foo=Bar' is passed in to the frontend,
|
||||
// and a source file has 'import Foo', a module called Bar (real name)
|
||||
// should be searched.
|
||||
StringRef moduleNameRef = Ctx.getRealModuleName(moduleID.Item).str();
|
||||
SmallString<32> moduleName(moduleNameRef);
|
||||
SerializedModuleBaseName genericBaseName(moduleName);
|
||||
|
||||
auto genericModuleFileName =
|
||||
@@ -1156,7 +1163,6 @@ bool MemoryBufferSerializedModuleLoader::canImportModule(
|
||||
assert(!(mIt->second.userVersion.empty()));
|
||||
return mIt->second.userVersion >= version;
|
||||
}
|
||||
|
||||
ModuleDecl *
|
||||
SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
|
||||
ImportPath::Module path) {
|
||||
@@ -1220,13 +1226,14 @@ MemoryBufferSerializedModuleLoader::loadModule(SourceLoc importLoc,
|
||||
return nullptr;
|
||||
|
||||
auto moduleID = path[0];
|
||||
auto moduleName = Ctx.getRealModuleName(moduleID.Item).str();
|
||||
|
||||
// See if we find it in the registered memory buffers.
|
||||
|
||||
// FIXME: Right now this works only with access paths of length 1.
|
||||
// Once submodules are designed, this needs to support suffix
|
||||
// matching and a search path.
|
||||
auto bufIter = MemoryBuffers.find(moduleID.Item.str());
|
||||
auto bufIter = MemoryBuffers.find(moduleName);
|
||||
if (bufIter == MemoryBuffers.end())
|
||||
return nullptr;
|
||||
|
||||
|
||||
20
test/Frontend/load-module-with-alias.swift
Normal file
20
test/Frontend/load-module-with-alias.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
/// Test the -module-alias flag.
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
/// Create a module Bar
|
||||
// RUN: echo 'public func bar() {}' > %t/FileBar.swift
|
||||
// RUN: %target-swift-frontend -module-name Bar %t/FileBar.swift -emit-module -emit-module-path %t/Bar.swiftmodule
|
||||
|
||||
/// Check if Bar.swiftmodule is created
|
||||
// RUN: test -f %t/Bar.swiftmodule
|
||||
// RUN: not test -f %t/Cat.swiftmodule
|
||||
|
||||
/// Create a module Foo that imports Cat with -module-alias Cat=Bar
|
||||
// RUN: echo 'import Cat' > %t/FileFoo.swift
|
||||
// RUN: %target-swift-frontend -module-name Foo -module-alias Cat=Bar %t/FileFoo.swift -emit-module -emit-module-path %t/Foo.swiftmodule -I %t
|
||||
|
||||
/// Check if Foo.swiftmodule is created without an error
|
||||
// RUN: test -f %t/Foo.swiftmodule
|
||||
// RUN: test -f %t/Bar.swiftmodule
|
||||
// RUN: not test -f %t/Cat.swiftmodule
|
||||
Reference in New Issue
Block a user