summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2013-08-01 22:29:32 +0000
committerFariborz Jahanian <fjahanian@apple.com>2013-08-01 22:29:32 +0000
commit8234d40843d545e80d98147e30e2917169d30840 (patch)
tree15826d8ea9e20ad8876f993382d599311ab2e758 /clang/lib
parent7699e4a50b14faf8a0dd821d0bda87eaa67b45eb (diff)
downloadbcm5719-llvm-8234d40843d545e80d98147e30e2917169d30840.tar.gz
bcm5719-llvm-8234d40843d545e80d98147e30e2917169d30840.zip
ObjectiveC migrator. Migrate to instancetype return type
for mehods with certain prefix selector matching their class names' suffix. llvm-svn: 187626
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/ARCMigrate/ObjCMT.cpp80
-rw-r--r--clang/lib/Basic/IdentifierTable.cpp8
2 files changed, 63 insertions, 25 deletions
diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp
index 2b2f9224e99..62f3c6b7e79 100644
--- a/clang/lib/ARCMigrate/ObjCMT.cpp
+++ b/clang/lib/ARCMigrate/ObjCMT.cpp
@@ -41,6 +41,8 @@ class ObjCMigrateASTConsumer : public ASTConsumer {
void migrateInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl);
void migrateMethodInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl,
ObjCMethodDecl *OM);
+ void migrateFactoryMethod(ASTContext &Ctx, ObjCContainerDecl *CDecl,
+ ObjCMethodDecl *OM);
public:
std::string MigrateDir;
@@ -549,13 +551,34 @@ void ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
Editor->commit(commit);
}
+static void ReplaceWithInstancetype(const ObjCMigrateASTConsumer &ASTC,
+ ObjCMethodDecl *OM) {
+ SourceRange R;
+ std::string ClassString;
+ if (TypeSourceInfo *TSInfo = OM->getResultTypeSourceInfo()) {
+ TypeLoc TL = TSInfo->getTypeLoc();
+ R = SourceRange(TL.getBeginLoc(), TL.getEndLoc());
+ ClassString = "instancetype";
+ }
+ else {
+ R = SourceRange(OM->getLocStart(), OM->getLocStart());
+ ClassString = OM->isInstanceMethod() ? '-' : '+';
+ ClassString += " (instancetype)";
+ }
+ edit::Commit commit(*ASTC.Editor);
+ commit.replace(R, ClassString);
+ ASTC.Editor->commit(commit);
+}
+
void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx,
ObjCContainerDecl *CDecl,
ObjCMethodDecl *OM) {
ObjCInstanceTypeFamily OIT_Family =
Selector::getInstTypeMethodFamily(OM->getSelector());
- if (OIT_Family == OIT_None)
+ if (OIT_Family == OIT_None) {
+ migrateFactoryMethod(Ctx, CDecl, OM);
return;
+ }
std::string ClassName;
switch (OIT_Family) {
case OIT_Array:
@@ -581,24 +604,11 @@ void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx,
IDecl = ImpDecl->getClassInterface();
}
if (!IDecl ||
- !IDecl->lookupInheritedClass(&Ctx.Idents.get(ClassName)))
+ !IDecl->lookupInheritedClass(&Ctx.Idents.get(ClassName))) {
+ migrateFactoryMethod(Ctx, CDecl, OM);
return;
-
- SourceRange R;
- std::string ClassString;
- if (TypeSourceInfo *TSInfo = OM->getResultTypeSourceInfo()) {
- TypeLoc TL = TSInfo->getTypeLoc();
- R = SourceRange(TL.getBeginLoc(), TL.getEndLoc());
- ClassString = "instancetype";
- }
- else {
- R = SourceRange(OM->getLocStart(), OM->getLocStart());
- ClassString = OM->isInstanceMethod() ? '-' : '+';
- ClassString += " (instancetype)";
}
- edit::Commit commit(*Editor);
- commit.replace(R, ClassString);
- Editor->commit(commit);
+ ReplaceWithInstancetype(*this, OM);
}
void ObjCMigrateASTConsumer::migrateInstanceType(ASTContext &Ctx,
@@ -612,6 +622,42 @@ void ObjCMigrateASTConsumer::migrateInstanceType(ASTContext &Ctx,
}
}
+void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx,
+ ObjCContainerDecl *CDecl,
+ ObjCMethodDecl *OM) {
+ if (OM->isInstanceMethod() || !OM->getResultType()->isObjCIdType())
+ return;
+
+ // Candidate factory methods are + (id) NaMeXXX : ... which belong to a class
+ // NSYYYNamE with matching names be at least 3 characters long.
+ ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
+ if (!IDecl) {
+ if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
+ IDecl = CatDecl->getClassInterface();
+ else if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(CDecl))
+ IDecl = ImpDecl->getClassInterface();
+ }
+ if (!IDecl)
+ return;
+
+ StringRef ClassName = IDecl->getName();
+ if (!ClassName.startswith("NS"))
+ return;
+
+ ClassName = ClassName.lower();
+ IdentifierInfo *MethodIdName = OM->getSelector().getIdentifierInfoForSlot(0);
+ StringRef MethodName = MethodIdName->getName();
+ StringRef MethodNamePrefix = MethodName.substr(0, 3).lower();
+ size_t Ix = ClassName.rfind(MethodNamePrefix);
+ if (Ix == StringRef::npos)
+ return;
+ StringRef ClassNamePostfix = ClassName.substr(Ix);
+ MethodName = MethodName.lower();
+ if (!MethodName.startswith(ClassNamePostfix))
+ return;
+ ReplaceWithInstancetype(*this, OM);
+}
+
namespace {
class RewritesReceiver : public edit::EditsReceiver {
diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp
index 96d9e56b6c3..3572930903f 100644
--- a/clang/lib/Basic/IdentifierTable.cpp
+++ b/clang/lib/Basic/IdentifierTable.cpp
@@ -474,14 +474,6 @@ ObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) {
case 'r':
if (startsWithWord(name, "retain")) return OIT_MemManage;
break;
- case 's':
- if (startsWithWord(name, "string")) return OIT_NSString;
- else
- if (startsWithWord(name, "set")) return OIT_NSSet;
- break;
- case 'U':
- if (startsWithWord(name, "URL")) return OIT_NSURL;
- break;
default:
break;
}
OpenPOWER on IntegriCloud