我想重写代码中的所有消息,我只需要替换选择器,但我需要能够替换嵌套表达式 fe :
[super foo:[someInstance someMessage:@""] foo2:[someInstance someMessage2]];
我尝试使用它clang::Rewriter replaceText
并只生成新字符串,但有一个问题:如果我更改选择器长度,它将不起作用,因为我用那些旧位置替换了嵌套消息。
所以,我认为我需要使用clang::Rewriter ReplaceStmt(originalStatement, newStatement);
我RecursiveASTVisitor
用来访问所有消息,我想复制这些消息对象,并替换选择器:
我怎样才能做到这一点?
我尝试使用ObjCMessageExpr::Create
,但参数太多,我不知道如何从原始消息中获取ASTContext &Context
and ArrayRef<SourceLocation> SeLocs
和参数。Expr *Receiver
使用 clang 工具(clang 工具界面)替换嵌套消息中的选择器的正确方法是什么?
更新:
我应该使用ReplaceStmtWithStmt
回调和ASTMatchFinder
吗?
更新:
我正在使用以下函数重写文件中的文本:
void ReplaceText(SourceLocation start, unsigned originalLength, StringRef string) {
m_rewriter.ReplaceText(start, originalLength, string);
m_rewriter.overwriteChangedFiles();
}
我想用新的选择器 fe 替换代码中的所有 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<ObjCMessageExpr>(statement)) {
ReplaceMessage(*messageExpr)
}
return true;
}
我创建了生成新消息 expr 字符串的方法:
string StringFromObjCMessageExpr(ObjCMessageExpr& messageExpression) {
std::ostringstream stringStream;
const string selectorString = messageExpression.getSelector().getAsString();
cout << selectorString << endl;
vector<string> methodParts;
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<string>::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();
该如何解决?