mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[NFC] Add @objc to imported ObjC categories
This contains the category name, if there is one.
This commit is contained in:
@@ -3707,6 +3707,29 @@ void ValueDecl::setIsObjC(bool value) {
|
||||
LazySemanticInfo.isObjC = value;
|
||||
}
|
||||
|
||||
Identifier ExtensionDecl::getObjCCategoryName() const {
|
||||
// If there's an @objc attribute, it's authoritative. (ClangImporter
|
||||
// attaches one automatically.)
|
||||
if (auto objcAttr = getAttrs().getAttribute<ObjCAttr>(/*AllowInvalid*/true)) {
|
||||
if (objcAttr->hasName() && objcAttr->getName()->getNumArgs() == 0)
|
||||
return objcAttr->getName()->getSimpleName();
|
||||
|
||||
return Identifier();
|
||||
}
|
||||
|
||||
// Fall back to @_objcImplementation attribute.
|
||||
if (auto attr =
|
||||
getAttrs().getAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true)) {
|
||||
if (!attr->isCategoryNameInvalid())
|
||||
return attr->CategoryName;
|
||||
|
||||
return Identifier();
|
||||
}
|
||||
|
||||
// Not a category, evidently.
|
||||
return Identifier();
|
||||
}
|
||||
|
||||
bool ValueDecl::isSemanticallyFinal() const {
|
||||
// Actor types are semantically final.
|
||||
if (auto classDecl = dyn_cast<ClassDecl>(this)) {
|
||||
|
||||
@@ -5969,32 +5969,6 @@ struct OrderDecls {
|
||||
};
|
||||
}
|
||||
|
||||
Identifier ExtensionDecl::getObjCCategoryName() const {
|
||||
// Could it be an imported category?
|
||||
if (!hasClangNode()) {
|
||||
// Nope, not imported. Is it an @implementation extension?
|
||||
auto attr = getAttrs()
|
||||
.getAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true);
|
||||
if (attr && !attr->isCategoryNameInvalid())
|
||||
return attr->CategoryName;
|
||||
|
||||
return Identifier();
|
||||
}
|
||||
|
||||
auto category = dyn_cast<clang::ObjCCategoryDecl>(getClangDecl());
|
||||
if (!category)
|
||||
// Nope, not a category.
|
||||
return Identifier();
|
||||
|
||||
// We'll look for an implementation with this category name.
|
||||
auto clangCategoryName = category->getName();
|
||||
if (clangCategoryName.empty())
|
||||
// Class extension (has an empty name).
|
||||
return Identifier();
|
||||
|
||||
return getASTContext().getIdentifier(clangCategoryName);
|
||||
}
|
||||
|
||||
static ObjCInterfaceAndImplementation
|
||||
constructResult(const llvm::TinyPtrVector<Decl *> &interfaces,
|
||||
llvm::TinyPtrVector<Decl *> &impls,
|
||||
|
||||
@@ -4132,14 +4132,16 @@ namespace {
|
||||
/// selector.
|
||||
///
|
||||
/// The importer should use this rather than adding the attribute directly.
|
||||
void addObjCAttribute(ValueDecl *decl, std::optional<ObjCSelector> name) {
|
||||
void addObjCAttribute(Decl *decl, std::optional<ObjCSelector> name) {
|
||||
auto &ctx = Impl.SwiftContext;
|
||||
if (name) {
|
||||
decl->getAttrs().add(ObjCAttr::create(ctx, name,
|
||||
/*implicitName=*/true));
|
||||
}
|
||||
decl->setIsObjC(true);
|
||||
decl->setIsDynamic(true);
|
||||
if (auto VD = dyn_cast<ValueDecl>(decl)) {
|
||||
VD->setIsObjC(true);
|
||||
VD->setIsDynamic(true);
|
||||
}
|
||||
|
||||
// If the declaration we attached the 'objc' attribute to is within a
|
||||
// type, record it in the type.
|
||||
@@ -4157,7 +4159,7 @@ namespace {
|
||||
/// selector.
|
||||
///
|
||||
/// The importer should use this rather than adding the attribute directly.
|
||||
void addObjCAttribute(ValueDecl *decl, Identifier name) {
|
||||
void addObjCAttribute(Decl *decl, Identifier name) {
|
||||
addObjCAttribute(decl, ObjCSelector(Impl.SwiftContext, 0, name));
|
||||
}
|
||||
|
||||
@@ -4778,6 +4780,11 @@ namespace {
|
||||
objcClass->getDeclaredType());
|
||||
Impl.SwiftContext.evaluator.cacheOutput(ExtendedNominalRequest{result},
|
||||
std::move(objcClass));
|
||||
|
||||
Identifier categoryName;
|
||||
if (!decl->getName().empty())
|
||||
categoryName = Impl.SwiftContext.getIdentifier(decl->getName());
|
||||
addObjCAttribute(result, categoryName);
|
||||
|
||||
// Create the extension declaration and record it.
|
||||
objcClass->addExtension(result);
|
||||
|
||||
Reference in New Issue
Block a user