I need to write a utility to refactoring source code in c / c ++. For this I use the Clang. Clang built on windows 7 x64 with visual studio 2012.
Below is the code that needs to be inverted conditions IF
and swap code blocks THEN
and ELSE
.
void foo(int* a, int *b)
{
if (a[0] > 1)
{
b[0] = 2;
}
else
{
b[0] = 3;
}
}
For the base, I use the example https://github.com/eliben/llvm-clang-samples/blob/master/src_clang/tooling_sample.cpp To do this, I bypass all the conditions and change each of them.
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> {
public:
MyASTVisitor(Rewriter &R) : TheRewriter(R) {}
bool VisitStmt(Stmt *s)
{
if (isa<IfStmt>(s))
{
IfStmt * IfStatement = cast<IfStmt>(s);
Stmt * Then = IfStatement->getThen();
Stmt * Else = IfStatement->getElse();
Expr * ifCondition = IfStatement->getCond();
SourceRange conditionRange = IfStatement->getCond()->getSourceRange();
stringstream invertConditionStream;
invertConditionStream << " !( " << TheRewriter.ConvertToString(ifCondition) << " ) ";
TheRewriter.ReplaceText(conditionRange, invertConditionStream.str());
TheRewriter.ReplaceStmt(Then, Else);
TheRewriter.ReplaceStmt(Else, Then);
}
return true;
}
Result refactoring example is shown below:
void foo(int* a, int *b)
{
if ( !( a[0] > 1 ) )
{
b[0] = 3;
}
else
{
b[0] = 2;
}
}
Not so nice as I like but works. But if you engage in refactoring the program below is obtained at the output of the application porridge.
void foo(int* a, int *b)
{
if (a[0] > 1)
{
b[0] = 2;
if (a[0] > 1)
{
b[0] = 2;
}
else
{
b[0] = 3;
}
}
else
{
b[0] = 3;
}
}
The result of my utilities:
vo !( a[0] > 1 ) nt* a{
b[0] = 3;
}
!( a[0] > 1 {
b[0] = 2;
}
;
}
else
{
b[0] = 2;
if (a[0] > 1) {
b[0] = 2;
} else {
b[0] = 3;
}
}
}
Tell me, what am I doing wrong? Does Clang's some other functionality for refactoring such as renaming variables and goto labels? Thanks in advance.