From: Fariborz Jahanian Date: Wed, 28 Aug 2013 23:22:46 +0000 (+0000) Subject: ObjectiveC migrator. This patch infers readonly properties for no-parameter X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b98aba1d74184923da32016c3abbc20e9a7686d;p=clang ObjectiveC migrator. This patch infers readonly properties for no-parameter instance methods returning non-void. This will be quite noisy. So, it is placed under a new migrator flag -objcmt-migrate-readonly-property. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189537 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h index 2023c729b8..50f8b281ed 100644 --- a/include/clang/ARCMigrate/ARCMTActions.h +++ b/include/clang/ARCMigrate/ARCMTActions.h @@ -60,13 +60,15 @@ class ObjCMigrateAction : public WrapperFrontendAction { bool MigrateLiterals; bool MigrateSubscripting; bool MigrateProperty; + bool MigrateReadonlyProperty; FileRemapper Remapper; CompilerInstance *CompInst; public: ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, bool migrateLiterals, bool migrateSubscripting, - bool migrateProperty); + bool migrateProperty, + bool migrateReadonlyProperty); protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile); diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 0bee8e9108..17a71cf53f 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -173,6 +173,8 @@ def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">, Fl HelpText<"Enable migration to modern ObjC subscripting">; def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">, Flags<[CC1Option]>, HelpText<"Enable migration to modern ObjC property">; +def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">, Flags<[CC1Option]>, + HelpText<"Enable migration to modern ObjC readonly property">; // Make sure all other -ccc- options are rejected. def ccc_ : Joined<["-"], "ccc-">, Group, Flags<[Unsupported]>; diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 0b78d95e75..9c1b8d5ac5 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -161,7 +161,9 @@ public: /// \brief Enable migration to modern ObjC subscripting. ObjCMT_Subscripting = 0x2, /// \brief Enable migration to modern ObjC property. - ObjCMT_Property = 0x4 + ObjCMT_Property = 0x4, + /// \brief Enable migration to modern ObjC readonly property. + ObjCMT_ReadonlyProperty = 0x8 }; unsigned ObjCMTAction; diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index 9b9d6aa10d..d71ab0d1bc 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -75,6 +75,7 @@ public: bool MigrateLiterals; bool MigrateSubscripting; bool MigrateProperty; + bool MigrateReadonlyProperty; unsigned FileId; OwningPtr NSAPIObj; OwningPtr Editor; @@ -90,6 +91,7 @@ public: bool migrateLiterals, bool migrateSubscripting, bool migrateProperty, + bool migrateReadonlyProperty, FileRemapper &remapper, FileManager &fileMgr, const PPConditionalDirectiveRecord *PPRec, @@ -98,8 +100,9 @@ public: : MigrateDir(migrateDir), MigrateLiterals(migrateLiterals), MigrateSubscripting(migrateSubscripting), - MigrateProperty(migrateProperty), FileId(0), - Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), + MigrateProperty(migrateProperty), + MigrateReadonlyProperty(migrateReadonlyProperty), + FileId(0), Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), IsOutputFile(isOutputFile) { } protected: @@ -131,10 +134,12 @@ ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, bool migrateLiterals, bool migrateSubscripting, - bool migrateProperty) + bool migrateProperty, + bool migrateReadonlyProperty) : WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir), MigrateLiterals(migrateLiterals), MigrateSubscripting(migrateSubscripting), MigrateProperty(migrateProperty), + MigrateReadonlyProperty(migrateReadonlyProperty), CompInst(0) { if (MigrateDir.empty()) MigrateDir = "."; // user current directory if none is given. @@ -151,6 +156,7 @@ ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, MigrateLiterals, MigrateSubscripting, MigrateProperty, + MigrateReadonlyProperty, Remapper, CompInst->getFileManager(), PPRec, @@ -250,13 +256,17 @@ static bool rewriteToObjCProperty(const ObjCMethodDecl *Getter, PropertyString += ", getter="; PropertyString += PropertyNameString; } + // Property with no setter may be suggested as a 'readonly' property. + if (!Setter) + append_attr(PropertyString, "readonly"); + // 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)) append_attr(PropertyString, "unsafe_unretained"); - else { + else if (Setter) { const ParmVarDecl *argDecl = *Setter->param_begin(); QualType ArgType = Context.getCanonicalType(argDecl->getType()); Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime(); @@ -308,10 +318,12 @@ static bool rewriteToObjCProperty(const ObjCMethodDecl *Getter, commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(), Getter->getDeclaratorEndLoc()), PropertyString); - SourceLocation EndLoc = Setter->getDeclaratorEndLoc(); - // Get location past ';' - EndLoc = EndLoc.getLocWithOffset(1); - commit.remove(CharSourceRange::getCharRange(Setter->getLocStart(), EndLoc)); + if (Setter) { + SourceLocation EndLoc = Setter->getDeclaratorEndLoc(); + // Get location past ';' + EndLoc = EndLoc.getLocWithOffset(1); + commit.remove(CharSourceRange::getCharRange(Setter->getLocStart(), EndLoc)); + } return true; } @@ -320,7 +332,8 @@ void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx, for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end(); M != MEnd; ++M) { ObjCMethodDecl *Method = (*M); - if (Method->isPropertyAccessor() || Method->param_size() != 0) + if (Method->isPropertyAccessor() || !Method->isInstanceMethod() || + Method->param_size() != 0) continue; // Is this method candidate to be a getter? QualType GRT = Method->getResultType(); @@ -368,7 +381,15 @@ void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx, rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit, GetterHasIsPrefix); Editor->commit(commit); - } + } + else if (MigrateReadonlyProperty) { + // Try a non-void method with no argument (and no setter or property of same name + // as a 'readonly' property. + edit::Commit commit(*Editor); + rewriteToObjCProperty(Method, 0 /*SetterMethod*/, *NSAPIObj, commit, + false /*GetterHasIsPrefix*/); + Editor->commit(commit); + } } } @@ -1170,6 +1191,7 @@ ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, /*MigrateLiterals=*/true, /*MigrateSubscripting=*/true, /*MigrateProperty*/true, + /*MigrateReadonlyProperty*/true, Remapper, CI.getFileManager(), PPRec, diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index b637938735..819ed4b135 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -793,6 +793,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Subscripting; if (Args.hasArg(OPT_objcmt_migrate_property)) Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Property; + if (Args.hasArg(OPT_objcmt_migrate_readonly_property)) + Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadonlyProperty; if (Opts.ARCMTAction != FrontendOptions::ARCMT_None && Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) { diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 2f6d4b29b6..7ba7103c76 100644 --- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -164,7 +164,8 @@ static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { Act = new arcmt::ObjCMigrateAction(Act, FEOpts.MTMigrateDir, FEOpts.ObjCMTAction & FrontendOptions::ObjCMT_Literals, FEOpts.ObjCMTAction & FrontendOptions::ObjCMT_Subscripting, - FEOpts.ObjCMTAction & FrontendOptions::ObjCMT_Property); + FEOpts.ObjCMTAction & FrontendOptions::ObjCMT_Property, + FEOpts.ObjCMTAction & FrontendOptions::ObjCMT_ReadonlyProperty); } #endif diff --git a/test/ARCMT/objcmt-property.m b/test/ARCMT/objcmt-property.m index 9a8bfa5aaf..6d66da7803 100644 --- a/test/ARCMT/objcmt-property.m +++ b/test/ARCMT/objcmt-property.m @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11 +// RUN: %clang_cc1 -objcmt-migrate-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11 // 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 @@ -87,4 +87,9 @@ typedef char BOOL; - (BOOL) isinValid; - (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; @end diff --git a/test/ARCMT/objcmt-property.m.result b/test/ARCMT/objcmt-property.m.result index 5fa9063327..2a633367c5 100644 --- a/test/ARCMT/objcmt-property.m.result +++ b/test/ARCMT/objcmt-property.m.result @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11 +// RUN: %clang_cc1 -objcmt-migrate-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11 // 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 @@ -82,9 +82,14 @@ typedef char BOOL; @property(nonatomic, getter=isContinuous) BOOL continuous; -- (id) isAnObject; +@property(nonatomic, readonly) id isAnObject; - (void)setAnObject : (id) object; -- (BOOL) isinValid; +@property(nonatomic, readonly) BOOL isinValid; - (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property(nonatomic, readonly) int Length; +@property(nonatomic, readonly) id object; ++ (double) D; @end