From: Fariborz Jahanian Date: Wed, 3 Jul 2013 23:05:00 +0000 (+0000) Subject: [ObjectiveC Migration]: Provide knobs for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=baf15574ebe70871b4682cdd5a87028bad1c9f6f;p=clang [ObjectiveC Migration]: Provide knobs for migrating setter/getter methods to an eventual property declaraiton. This is wip. // rdar://14345082 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185591 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index 57fac0389f..8f56648b07 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -32,6 +32,7 @@ namespace { class ObjCMigrateASTConsumer : public ASTConsumer { void migrateDecl(Decl *D); + void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCInterfaceDecl *D); public: std::string MigrateDir; @@ -42,6 +43,7 @@ public: FileRemapper &Remapper; FileManager &FileMgr; const PPConditionalDirectiveRecord *PPRec; + Preprocessor &PP; bool IsOutputFile; ObjCMigrateASTConsumer(StringRef migrateDir, @@ -50,11 +52,12 @@ public: FileRemapper &remapper, FileManager &fileMgr, const PPConditionalDirectiveRecord *PPRec, + Preprocessor &PP, bool isOutputFile = false) : MigrateDir(migrateDir), MigrateLiterals(migrateLiterals), MigrateSubscripting(migrateSubscripting), - Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), + Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), IsOutputFile(isOutputFile) { } protected: @@ -105,7 +108,8 @@ ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, MigrateSubscripting, Remapper, CompInst->getFileManager(), - PPRec); + PPRec, + CompInst->getPreprocessor()); ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer }; return new MultiplexConsumer(Consumers); } @@ -184,6 +188,40 @@ void ObjCMigrateASTConsumer::migrateDecl(Decl *D) { BodyMigrator(*this).TraverseDecl(D); } +void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx, + ObjCInterfaceDecl *D) { + for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end(); + M != MEnd; ++M) { + ObjCMethodDecl *Method = (*M); + if (Method->isPropertyAccessor()) + continue; + // Is this method candidate to be a getter? + if (Method->param_size() == 0) { + QualType GRT = Method->getResultType(); + if (GRT->isVoidType()) + continue; + Selector GetterSelector = Method->getSelector(); + IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0); + Selector SetterSelector = + SelectorTable::constructSetterSelector(PP.getIdentifierTable(), + PP.getSelectorTable(), + getterName); + if (ObjCMethodDecl *SetterMethod = D->lookupMethod(SetterSelector, true)) { + // Is this a valid setter, matching the target getter? + QualType SRT = SetterMethod->getResultType(); + if (!SRT->isVoidType()) + continue; + const ParmVarDecl *argDecl = *SetterMethod->param_begin(); + // FIXME. Can relax rule for matching getter/setter type further. + if (!Ctx.hasSameType(argDecl->getType(), GRT)) + continue; + // we have a matching setter/getter pair. + // TODO. synthesize a suitable property declaration here. + } + } + } +} + namespace { class RewritesReceiver : public edit::EditsReceiver { @@ -203,6 +241,14 @@ public: } void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { + + TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl(); + for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end(); + D != DEnd; ++D) { + if (ObjCInterfaceDecl *CDecl = dyn_cast(*D)) + migrateObjCInterfaceDecl(Ctx, CDecl); + } + Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); RewritesReceiver Rec(rewriter); Editor->applyRewrites(Rec); @@ -247,5 +293,6 @@ ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, Remapper, CI.getFileManager(), PPRec, + CI.getPreprocessor(), /*isOutputFile=*/true); }