mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Introduce a package interface.
It has an extension .package.swiftinterface and contains package decls as well as SPIs and public/inlinable decls. When a module is loaded from interface, it now looks up the package-name in the interface and checks if the importer is in the same package. If so, it uses that package interface found to load the module. If not, uses the existing logic to load modules. Resolves rdar://104617854
This commit is contained in:
@@ -524,7 +524,7 @@ std::error_code ImplicitSerializedModuleLoader::findModuleFilesInDirectory(
|
||||
|
||||
if (ModuleInterfaceSourcePath) {
|
||||
if (auto InterfacePath =
|
||||
BaseName.findInterfacePath(*Ctx.SourceMgr.getFileSystem()))
|
||||
BaseName.findInterfacePath(*Ctx.SourceMgr.getFileSystem(), Ctx))
|
||||
ModuleInterfaceSourcePath->assign(InterfacePath->begin(),
|
||||
InterfacePath->end());
|
||||
}
|
||||
@@ -596,17 +596,56 @@ std::string SerializedModuleBaseName::getName(file_types::ID fileTy) const {
|
||||
return std::string(result.str());
|
||||
}
|
||||
|
||||
llvm::Optional<std::string> SerializedModuleLoaderBase::getPackageInterfacePathIfInSamePackage(llvm::vfs::FileSystem &fs, ASTContext &ctx) {
|
||||
std::string packagePath{
|
||||
getName(file_types::TY_PackageSwiftModuleInterfaceFile)};
|
||||
|
||||
if (fs.exists(packagePath)) {
|
||||
// Read the interface file and extract its package-name argument value
|
||||
StringRef result;
|
||||
if (auto packageFile = llvm::MemoryBuffer::getFile(packagePath)) {
|
||||
llvm::BumpPtrAllocator alloc;
|
||||
llvm::StringSaver argSaver(alloc);
|
||||
SmallVector<const char*, 8> args;
|
||||
(void)extractCompilerFlagsFromInterface(packagePath,
|
||||
(*packageFile)->getBuffer(), argSaver, args);
|
||||
for (unsigned I = 0, N = args.size(); I + 1 < N; I++) {
|
||||
StringRef current(args[I]), next(args[I + 1]);
|
||||
if (current == "-package-name") {
|
||||
result = next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return the .package.swiftinterface path if the package name applies to
|
||||
// the importer module.
|
||||
if (!result.empty() && result == ctx.LangOpts.PackageName)
|
||||
return packagePath;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
llvm::Optional<std::string>
|
||||
SerializedModuleBaseName::findInterfacePath(llvm::vfs::FileSystem &fs) const {
|
||||
SerializedModuleBaseName::findInterfacePath(llvm::vfs::FileSystem &fs, ASTContext &ctx) const {
|
||||
std::string interfacePath{getName(file_types::TY_SwiftModuleInterfaceFile)};
|
||||
// Ensure the public swiftinterface already exists, otherwise bail early.
|
||||
if (!fs.exists(interfacePath))
|
||||
return {};
|
||||
|
||||
// Check if a package interface exists and if the package name applies to
|
||||
// the importer module.
|
||||
auto packagePath = getPackageInterfacePathIfInSamePackage(fs, ctx);
|
||||
if (fs.exists(packagePath))
|
||||
return packagePath;
|
||||
|
||||
// If above fails, use the existing logic.
|
||||
// If present, use the private interface instead of the public one.
|
||||
std::string privatePath{
|
||||
getName(file_types::TY_PrivateSwiftModuleInterfaceFile)};
|
||||
if (fs.exists(privatePath))
|
||||
return privatePath;
|
||||
|
||||
// Otherwise return the public .swiftinterface path
|
||||
return interfacePath;
|
||||
}
|
||||
|
||||
@@ -688,6 +727,7 @@ bool SerializedModuleLoaderBase::findModule(
|
||||
(moduleName + ".framework").str(),
|
||||
genericBaseName.getName(file_types::TY_SwiftModuleInterfaceFile),
|
||||
genericBaseName.getName(file_types::TY_PrivateSwiftModuleInterfaceFile),
|
||||
genericBaseName.getName(file_types::TY_PackageSwiftModuleInterfaceFile),
|
||||
genericBaseName.getName(file_types::TY_SwiftModuleFile)};
|
||||
|
||||
auto searchPaths = Ctx.SearchPathOpts.moduleSearchPathsContainingFile(
|
||||
|
||||
Reference in New Issue
Block a user