我想重写我的代码中的所有消息,我只需要替换选择器,但我需要能够替换嵌套的表达式fe:
[super foo:[someInstance someMessage:@""] foo2:[someInstance someMessage2]];
我尝试使用clang::Rewriter replaceText
并生成新的字符串,但是有一个问题:如果我更改选择器长度,它将无法工作,因为我用那些旧位置替换嵌套消息.
所以,我认为我需要使用 clang::Rewriter ReplaceStmt(originalStatement, newStatement);
我RecursiveASTVisitor
用来访问所有消息,我想复制这些消息对象,并替换选择器:
我怎样才能做到这一点?
我试过使用ObjCMessageExpr::Create
但是有如此经典的args,我不知道如何从原始消息中获取ASTContext &Context
and ArrayRef
和Expr *Receiver
参数.
使用clang工具(clang工具界面)替换嵌套消息中选择器的正确方法是什么?
更新:
我应该使用ReplaceStmtWithStmt
回调ASTMatchFinder
吗?
更新:
我正在使用以下函数来重写文件中的文本:
void ReplaceText(SourceLocation start, unsigned originalLength, StringRef string) { m_rewriter.ReplaceText(start, originalLength, string); m_rewriter.overwriteChangedFiles(); }
我想用新的选择器替换代码中的所有messageExpr:它是怎么回事:
[object someMessage:[object2 someMessage:obj3 calculate:obj4]];
怎么样:
[object newSelector:[object2 newSelector:obj3 newSelector:obj4]];
我正在使用ReqoursiveASTVisitor:
bool VisitStmt(Stmt *statement) { if (ObjCMessageExpr *messageExpr = dyn_cast(statement)) { ReplaceMessage(*messageExpr) } return true; }
我创建了生成新消息expr字符串的方法:
string StringFromObjCMessageExpr(ObjCMessageExpr& messageExpression) { std::ostringstream stringStream; const string selectorString = messageExpression.getSelector().getAsString(); cout << selectorString << endl; vectormethodParts; split(selectorString, ParametersDelimiter, methodParts); stringStream << "[" ; const string receiver = GetStringFromLocations(m_compiler, messageExpression.getReceiverRange().getBegin(), messageExpression.getSelectorStartLoc()); stringStream << receiver; clang::ObjCMessageExpr::arg_iterator argIterator = messageExpression.arg_begin(); for (vector ::const_iterator partsIterator = methodParts.begin(); partsIterator != methodParts.end(); ++partsIterator) { stringStream << "newSelector"; if (messageExpression.getNumArgs() != 0) { const clang::Stmt *argument = *argIterator; stringStream << ":" << GetStatementString(*argument) << " "; ++argIterator; } } stringStream << "]"; return stringStream.str(); } void ReplaceMessage(ObjCMessageExpr& messageExpression) { SourceLocation locStart = messageExpression.getLocStart(); SourceLocation locEnd = messageExpression.getLocEnd(); string newExpr = StringFromObjCMessageExpr(messageExpression); const int exprStringLegth = m_rewriter.getRangeSize(SourceRange(locStart, locEnd)); ReplaceText(locStart, exprStringLegth, newExpr); }
当我尝试替换嵌套消息时会出现问题,例如:
[simpleClass doSomeActionWithString:string3 andAnotherString:string4]; [simpleClass doSomeActionWithString:str andAnotherString:str2]; [simpleClass doSomeActionWithString:@"" andAnotherString:@"asdasdsad"]; [simpleClass setSimpleClassZAZAZAZAZAZAZAZA:[simpleClass getSimpleClassZAZAZAZAZAZAZAZA]];
结果是:
[simpleClass newSelector:string3 newSelector:string4 ]; [simpleClass newSelector:str newSelector:str2 ]; [simpleClass newSelector:@"" newSelector:@"asdasdsad" ]; [simpleClass newSelector:[simpleClass getSimp[simpleClass newSelector]];
因为messageExpression有"老"的价值getLocStart();
和getLocEnd();
如何解决呢?