mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add @_implementationOnly
This is an attribute that gets put on an import in library FooKit to keep it from being a requirement to import FooKit. It's not checked at all, meaning that in this form it is up to the author of FooKit to make sure nothing in its API or ABI depends on the implementation-only dependency. There's also no debugging support here (debugging FooKit /should/ import the implementation-only dependency if it's present). The goal is to get to a point where it /can/ be checked, i.e. FooKit developers are prevented from writing code that would rely on FooKit's implementation-only dependency being present when compiling clients of FooKit. But right now it's not. rdar://problem/48985979
This commit is contained in:
@@ -1040,6 +1040,17 @@ uint64_t getRawModTimeOrHash(const SerializationOptions::FileDependency &dep) {
|
||||
return dep.getModificationTime();
|
||||
}
|
||||
|
||||
using ImportSet = llvm::SmallSet<ModuleDecl::ImportedModule, 8,
|
||||
ModuleDecl::OrderImportedModules>;
|
||||
static ImportSet getImportsAsSet(const ModuleDecl *M,
|
||||
ModuleDecl::ImportFilter filter) {
|
||||
SmallVector<ModuleDecl::ImportedModule, 8> imports;
|
||||
M->getImportedModules(imports, filter);
|
||||
ImportSet importSet;
|
||||
importSet.insert(imports.begin(), imports.end());
|
||||
return importSet;
|
||||
}
|
||||
|
||||
void Serializer::writeInputBlock(const SerializationOptions &options) {
|
||||
BCBlockRAII restoreBlock(Out, INPUT_BLOCK_ID, 4);
|
||||
input_block::ImportedModuleLayout ImportedModule(Out);
|
||||
@@ -1071,17 +1082,17 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
|
||||
ModuleDecl::ImportFilter allImportFilter;
|
||||
allImportFilter |= ModuleDecl::ImportFilterKind::Public;
|
||||
allImportFilter |= ModuleDecl::ImportFilterKind::Private;
|
||||
allImportFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
|
||||
SmallVector<ModuleDecl::ImportedModule, 8> allImports;
|
||||
M->getImportedModules(allImports, allImportFilter);
|
||||
ModuleDecl::removeDuplicateImports(allImports);
|
||||
|
||||
// Collect the public imports as a subset so that we can mark them with an
|
||||
// extra flag.
|
||||
SmallVector<ModuleDecl::ImportedModule, 8> publicImports;
|
||||
M->getImportedModules(publicImports, ModuleDecl::ImportFilterKind::Public);
|
||||
llvm::SmallSet<ModuleDecl::ImportedModule, 8,
|
||||
ModuleDecl::OrderImportedModules> publicImportSet;
|
||||
publicImportSet.insert(publicImports.begin(), publicImports.end());
|
||||
// Collect the public and private imports as a subset so that we can
|
||||
// distinguish them.
|
||||
ImportSet publicImportSet =
|
||||
getImportsAsSet(M, ModuleDecl::ImportFilterKind::Public);
|
||||
ImportSet privateImportSet =
|
||||
getImportsAsSet(M, ModuleDecl::ImportFilterKind::Private);
|
||||
|
||||
auto clangImporter =
|
||||
static_cast<ClangImporter *>(M->getASTContext().getClangModuleLoader());
|
||||
@@ -1119,7 +1130,20 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
|
||||
|
||||
ImportPathBlob importPath;
|
||||
flattenImportPath(import, importPath);
|
||||
ImportedModule.emit(ScratchRecord, publicImportSet.count(import),
|
||||
|
||||
serialization::ImportControl stableImportControl;
|
||||
// The order of checks here is important, since a module can be imported
|
||||
// differently in different files, and we need to record the "most visible"
|
||||
// form here.
|
||||
if (publicImportSet.count(import))
|
||||
stableImportControl = ImportControl::Exported;
|
||||
else if (privateImportSet.count(import))
|
||||
stableImportControl = ImportControl::Normal;
|
||||
else
|
||||
stableImportControl = ImportControl::ImplementationOnly;
|
||||
|
||||
ImportedModule.emit(ScratchRecord,
|
||||
static_cast<uint8_t>(stableImportControl),
|
||||
!import.first.empty(), importPath);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user