Import Objective-C properties annotated with 'iboutletcollection' as typed collections.

This commit only covers semantic analysis. We're still not able to
IRgen a downcast from a concrete class to an archetype.


Swift SVN r3535
This commit is contained in:
Doug Gregor
2012-12-18 23:12:33 +00:00
parent 75c8591487
commit aaea6d94cf
6 changed files with 85 additions and 16 deletions

View File

@@ -28,6 +28,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/DeclVisitor.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
using namespace swift;
@@ -85,7 +86,8 @@ namespace {
// If this is the Objective-C BOOL type, map it to ObjCBool.
auto &clangContext = Impl.getClangASTContext();
if (name.str() == "BOOL" &&
if (clangContext.getLangOpts().ObjC1 &&
name.str() == "BOOL" &&
clangContext.hasSameType(decl->getUnderlyingType(),
clangContext.ObjCBuiltinBoolTy)) {
type = Impl.getNamedSwiftType(Impl.getNamedModule("objc"), "ObjCBool");
@@ -1485,6 +1487,37 @@ namespace {
return nullptr;
}
/// \brief Given an untyped collection and an element type,
/// produce the typed collection (if possible) or return the collection
/// itself (if there is no known corresponding typed collection).
Type getTypedCollection(Type collectionTy, Type elementTy) {
auto classTy = collectionTy->getAs<ClassType>();
if (!classTy) {
return collectionTy;
}
// Map known collections to their typed equivalents.
// FIXME: This is very hacky.
typedef std::pair<StringRef, StringRef> StringRefPair;
StringRefPair typedCollection
= llvm::StringSwitch<StringRefPair>(classTy->getDecl()->getName().str())
.Case("NSArray", StringRefPair("Foundation", "NSTypedArray"))
.Default(StringRefPair(StringRef(), StringRef()));
if (typedCollection.first.empty()) {
return collectionTy;
}
// Form the specialization.
if (auto typed = Impl.getNamedSwiftTypeSpecialization(
Impl.getNamedModule(typedCollection.first),
typedCollection.second,
elementTy)) {
return typed;
}
return collectionTy;
}
Decl *VisitObjCPropertyDecl(clang::ObjCPropertyDecl *decl) {
// Properties are imported as variables.
auto dc = Impl.importDeclContext(decl->getDeclContext());
@@ -1513,6 +1546,14 @@ namespace {
if (!type)
return nullptr;
// Look for an iboutletcollection attribute, which provides additional
// typing information for known containers.
if (auto collectionAttr = decl->getAttr<clang::IBOutletCollectionAttr>()){
if (auto elementType = Impl.importType(collectionAttr->getInterface())){
type = getTypedCollection(type, elementType);
}
}
// Import the getter.
auto getter
= cast_or_null<FuncDecl>(Impl.importDecl(decl->getGetterMethodDecl()));