Add implicit SPI import feature

API development sometimes requires a redesign while supporting early
adopters. Currently this is done by adding @_spi(name) to the API but
that requires adding the attribute in import statements as well, causing
manual overhead of adding and then removing when the redesign is done.

This PR introduces a special spi group name '_' and allows an implicit
spi import of a module containing API attributed with '@_spi(_)'

Resolves rdar://109797632
This commit is contained in:
Ellie Shin
2023-05-31 17:28:19 -07:00
parent c2c24145bf
commit 32f53d1eb8
5 changed files with 140 additions and 6 deletions

View File

@@ -3304,6 +3304,14 @@ void SourceFile::lookupImportedSPIGroups(
}
}
bool shouldImplicitImportAsSPI(ArrayRef<Identifier> spiGroups) {
for (auto group : spiGroups) {
if (group.empty())
return true;
}
return false;
}
bool SourceFile::isImportedAsSPI(const ValueDecl *targetDecl) const {
auto targetModule = targetDecl->getModuleContext();
llvm::SmallSetVector<Identifier, 4> importedSPIGroups;
@@ -3311,6 +3319,8 @@ bool SourceFile::isImportedAsSPI(const ValueDecl *targetDecl) const {
// Objective-C SPIs are always imported implicitly.
if (targetDecl->hasClangNode())
return !targetDecl->getSPIGroups().empty();
if (shouldImplicitImportAsSPI(targetDecl->getSPIGroups()))
return true;
lookupImportedSPIGroups(targetModule, importedSPIGroups);
if (importedSPIGroups.empty())
@@ -3345,13 +3355,15 @@ bool SourceFile::importsModuleAsWeakLinked(const ModuleDecl *module) const {
bool ModuleDecl::isImportedAsSPI(const SpecializeAttr *attr,
const ValueDecl *targetDecl) const {
auto declSPIGroups = attr->getSPIGroups();
if (shouldImplicitImportAsSPI(declSPIGroups))
return true;
auto targetModule = targetDecl->getModuleContext();
llvm::SmallSetVector<Identifier, 4> importedSPIGroups;
lookupImportedSPIGroups(targetModule, importedSPIGroups);
if (importedSPIGroups.empty()) return false;
auto declSPIGroups = attr->getSPIGroups();
for (auto declSPI : declSPIGroups)
if (importedSPIGroups.count(declSPI))
return true;
@@ -3361,6 +3373,9 @@ bool ModuleDecl::isImportedAsSPI(const SpecializeAttr *attr,
bool ModuleDecl::isImportedAsSPI(Identifier spiGroup,
const ModuleDecl *fromModule) const {
if (shouldImplicitImportAsSPI({spiGroup}))
return true;
llvm::SmallSetVector<Identifier, 4> importedSPIGroups;
lookupImportedSPIGroups(fromModule, importedSPIGroups);
if (importedSPIGroups.empty())