ObjectiveC migration: Handle another special case of
setter/getter methods which can be migrated to
a @property.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188005 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index f676149..931f6ed 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -206,20 +206,31 @@
BodyMigrator(*this).TraverseDecl(D);
}
+static void append_attr(std::string &PropertyString, const char *attr,
+ bool GetterHasIsPrefix) {
+ PropertyString += (GetterHasIsPrefix ? ", " : "(");
+ PropertyString += attr;
+ PropertyString += ')';
+}
+
static bool rewriteToObjCProperty(const ObjCMethodDecl *Getter,
const ObjCMethodDecl *Setter,
- const NSAPI &NS, edit::Commit &commit) {
+ const NSAPI &NS, edit::Commit &commit,
+ bool GetterHasIsPrefix) {
ASTContext &Context = NS.getASTContext();
std::string PropertyString = "@property";
-
std::string PropertyNameString = Getter->getNameAsString();
StringRef PropertyName(PropertyNameString);
+ if (GetterHasIsPrefix) {
+ PropertyString += "(getter=";
+ PropertyString += PropertyNameString;
+ }
// Short circuit properties that contain the name "delegate" or "dataSource",
// or have exact name "target" to have unsafe_unretained attribute.
if (PropertyName.equals("target") ||
(PropertyName.find("delegate") != StringRef::npos) ||
(PropertyName.find("dataSource") != StringRef::npos))
- PropertyString += "(unsafe_unretained)";
+ append_attr(PropertyString, "unsafe_unretained", GetterHasIsPrefix);
else {
const ParmVarDecl *argDecl = *Setter->param_begin();
QualType ArgType = Context.getCanonicalType(argDecl->getType());
@@ -231,29 +242,46 @@
ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
if (IDecl &&
IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
- PropertyString += "(copy)";
+ append_attr(PropertyString, "copy", GetterHasIsPrefix);
else
- PropertyString += "(retain)";
- }
+ append_attr(PropertyString, "retain", GetterHasIsPrefix);
+ } else if (GetterHasIsPrefix)
+ PropertyString += ')';
} else if (propertyLifetime == Qualifiers::OCL_Weak)
// TODO. More precise determination of 'weak' attribute requires
// looking into setter's implementation for backing weak ivar.
- PropertyString += "(weak)";
+ append_attr(PropertyString, "weak", GetterHasIsPrefix);
else if (RetainableObject)
- PropertyString += "(retain)";
+ append_attr(PropertyString, "retain", GetterHasIsPrefix);
+ else if (GetterHasIsPrefix)
+ PropertyString += ')';
}
- // strip off any ARC lifetime qualifier.
- QualType CanResultTy = Context.getCanonicalType(Getter->getResultType());
- if (CanResultTy.getQualifiers().hasObjCLifetime()) {
- Qualifiers Qs = CanResultTy.getQualifiers();
- Qs.removeObjCLifetime();
- CanResultTy = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
+ QualType RT = Getter->getResultType();
+ if (!isa<TypedefType>(RT)) {
+ // strip off any ARC lifetime qualifier.
+ QualType CanResultTy = Context.getCanonicalType(RT);
+ if (CanResultTy.getQualifiers().hasObjCLifetime()) {
+ Qualifiers Qs = CanResultTy.getQualifiers();
+ Qs.removeObjCLifetime();
+ RT = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
+ }
}
PropertyString += " ";
- PropertyString += CanResultTy.getAsString(Context.getPrintingPolicy());
+ PropertyString += RT.getAsString(Context.getPrintingPolicy());
PropertyString += " ";
- PropertyString += PropertyNameString;
+ if (GetterHasIsPrefix) {
+ // property name must strip off "is" and lower case the first character
+ // after that; e.g. isContinuous will become continuous.
+ StringRef PropertyNameStringRef(PropertyNameString);
+ PropertyNameStringRef = PropertyNameStringRef.drop_front(2);
+ PropertyNameString = PropertyNameStringRef;
+ std::string NewPropertyNameString = PropertyNameString;
+ NewPropertyNameString[0] = std::tolower(NewPropertyNameString[0]);
+ PropertyString += NewPropertyNameString;
+ }
+ else
+ PropertyString += PropertyNameString;
commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(),
Getter->getDeclaratorEndLoc()),
PropertyString);
@@ -285,7 +313,25 @@
SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
PP.getSelectorTable(),
getterName);
- if (ObjCMethodDecl *SetterMethod = D->lookupMethod(SetterSelector, true)) {
+ ObjCMethodDecl *SetterMethod = D->lookupMethod(SetterSelector, true);
+ bool GetterHasIsPrefix = false;
+ if (!SetterMethod) {
+ // try a different naming convention for getter: isXxxxx
+ StringRef getterNameString = getterName->getName();
+ if (getterNameString.startswith("is")) {
+ GetterHasIsPrefix = true;
+ const char *CGetterName = getterNameString.data() + 2;
+ if (CGetterName[0]) {
+ getterName = &Ctx.Idents.get(CGetterName);
+ SetterSelector =
+ SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
+ PP.getSelectorTable(),
+ getterName);
+ SetterMethod = D->lookupMethod(SetterSelector, true);
+ }
+ }
+ }
+ if (SetterMethod) {
// Is this a valid setter, matching the target getter?
QualType SRT = SetterMethod->getResultType();
if (!SRT->isVoidType())
@@ -296,7 +342,8 @@
SetterMethod->hasAttrs())
continue;
edit::Commit commit(*Editor);
- rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit);
+ rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit,
+ GetterHasIsPrefix);
Editor->commit(commit);
}
}
diff --git a/test/ARCMT/objcmt-property.m b/test/ARCMT/objcmt-property.m
index 6511acd..8453999 100644
--- a/test/ARCMT/objcmt-property.m
+++ b/test/ARCMT/objcmt-property.m
@@ -3,6 +3,7 @@
// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties %s.result
+typedef char BOOL;
@class NSString;
@protocol NSCopying @end
@@ -77,4 +78,13 @@
- (int)value;
- (void)setValue: (int)val;
+
+-(BOOL) isContinuous;
+-(void) setContinuous:(BOOL)value;
+
+- (id) isAnObject;
+- (void)setAnObject : (id) object;
+
+- (id)isxdelegateYYY;
+- (void)setXdelegateYYY:(id)delegate;
@end
diff --git a/test/ARCMT/objcmt-property.m.result b/test/ARCMT/objcmt-property.m.result
index 3c9a539..1cd771a 100644
--- a/test/ARCMT/objcmt-property.m.result
+++ b/test/ARCMT/objcmt-property.m.result
@@ -3,6 +3,7 @@
// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties %s.result
+typedef char BOOL;
@class NSString;
@protocol NSCopying @end
@@ -77,4 +78,13 @@
@property int value;
+
+@property(getter=isContinuous) BOOL continuous;
+
+
+@property(getter=isAnObject, retain) id anObject;
+
+
+@property(getter=isxdelegateYYY, unsafe_unretained) id xdelegateYYY;
+
@end