2つのJavaクラスは、意味的に同一である場合にはどうすれば確認できますか?

agdev84:

私は2つの似た巨大プロジェクト(1000 +クラス)をマージする必要があります。二つ目は、最初の1のフォークです、そしてそれはいくつかの国固有の振る舞いが含まれています。SVNバージョン管理が非常に悪く扱われたため、二つのプロジェクトは、多くのことを発散します。

多くの場合、2つのクラスが意味的に同一であることを起こります。そのソースコードは、などの警告、import文、いくつかのメソッドや変数の順序、コードの書式設定、コメント、という点で異なります

2つのクラスが意味的に同一である場合、自動的にチェックする方法はありますか?

Sazzadur Ra​​haman:

あなたは次のようにプログラム解析ツールを使用することを検討すべきであるすすすすは、最良のあなたの目的に適しているコードを分析するためのいくつかの優れたAPIを持っています。例えば、二つのクラス「意味的に同一である」かどうかを確認するために、あなたはクラスの両方が同じ(または類似の方法を)持っている(1)クラスの両方が同じ(または類似のフィールド)を持っているかどうか(2)検討することができます。

フィールドは次のように表現されるSootFieldすすインチ あなたには、すべての必要な情報を持っていますSootFieldあなたは比較のために使用することをオブジェクト。それらの制御フローグラフ(かどうかの二つの方法の意味的な類似性をチェックするには、あなたがチェックできるのCFGが)類似またはではありません(詳細はセクション5.7であり、このガイド)。

あなたはすすを使用する方法のヒント。

ソースdirがされている場合はsrcDir、JavaのホームがあるjavaHomeとクラスのリストがありclassNames、その後、あなたはプログラムですすツールセットで、あなたのクラスをロードするために、次のコードスニペットを使用することができます。

 String sootClassPath = srcDir + ":" 
            + javaHome + "/jre/lib/rt.jar:"
            +javaHome + "/jre/lib/jce.jar";

    Options.v().set_output_format(Options.output_format_jimple);
    Options.v().set_src_prec(Options.src_prec_java);

    for (String className : classNames) { // // "className" is like a.b.Myclass
        Options.v().classes().add(className);
    }

    Options.v().set_keep_line_number(true);
    Options.v().set_allow_phantom_refs(true);
    Scene.v().setSootClassPath(sootClassPath);

    Scene.v().loadBasicClasses();

あなたのクラスがロードされるときは、以下のようなクラスにアクセスすることができます。

 SootClass sClass = Scene.v().loadClassAndSupport(className); // "className" is like a.b.Myclass

今、あなたはフィールドとメソッドのアクセスすることができsClass、以下のように:

 Chain<SootField> fieldList =  sClass.getFields(); // import soot.util.Chain;
 List<SootMethod> methods = sClass.getMethods();

それの命令のリストを取得するには、以下のようなあなたは、メソッドのCFGを反復することができます

  if (method.isConcrete()) {

     List<Unit> instructionList = new ArrayList<>();

     Body b = method.retrieveActiveBody();
     DirectedGraph g = new ExceptionalUnitGraph(b);
     Iterator gitr = g.iterator();
     while (gitr.hasNext()) {
          Unit unit = (Unit) gitr.next();
          instructionList.add(unit);
     }
  }

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=137214&siteId=1