2

c / c ++でソースコードをリファクタリングするためのユーティリティを書く必要があります。これには Clang を使用します。Visual Studio 2012 を使用して Windows 7 x64 上に構築された Clang。

IF以下は、条件を反転し、コード ブロックTHENとを交換する必要があるコードですELSE

void foo(int* a, int *b) 
{
  if (a[0] > 1) 
  {
      b[0] = 2;
  }
  else
  {
      b[0] = 3;
  }
}

基本として、https://github.com/eliben/llvm-clang-samples/blob/master/src_clang/tooling_sample.cppの例を使用します。 これを行うには、すべての条件をバイパスし、それぞれを変更します。

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;
    }

結果リファクタリングの例を以下に示します。

void foo(int* a, int *b) 
{
  if ( !( a[0] > 1 ) ) 
  {
    b[0] = 3;
}

  else
  {
    b[0] = 2;
}

}

私が好きなほど良くはありませんが、うまくいきます。しかし、リファクタリングを行うと、アプリケーションお粥の出力で以下のプログラムが得られます。

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;
  }
}

私のユーティリティの結果:

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;
    }
}


}

教えてください、私は何を間違っていますか?変数の名前変更やラベルへの移動など、リファクタリングのためのClangの他の機能はありますか? 前もって感謝します。

4

0 に答える 0