agd*_*v84 9 java versioning merge
我需要合并两个类似的巨大项目(1000多个类).第二个是第一个的分支,它包含一些特定于国家的行为.这两个项目分歧很大,因为svn版本处理得非常糟糕.
经常发生两个类在语义上相同.它们的源代码仅在警告,导入语句,某些方法或变量的顺序,代码格式,注释等方面有所不同.
有没有办法自动检查两个类在语义上是否相同?
您应该考虑使用像Soot这样的程序分析工具。Soot 拥有一些出色的 API 来分析最适合您目的的代码。例如,要检查两个类是否“语义相同”,您可以考虑(1)两个类是否具有相同(或相似的字段)(2)两个类是否具有相同(或相似的方法)。
场以烟灰形式表示SootField。SootField您将在要用于比较的对象中拥有所有必要的信息。要检查两种方法的语义相似性,您可以检查它们的控制流图(CFG)是否相似(详细信息参见本指南的第 5.7 节)。
有关如何使用烟灰的提示。
如果您的源目录是srcDir,Java Home 是javaHome并且类列表是classNames,那么您可以使用以下代码片段以编程方式在 Soot 工具集中加载您的类。
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();
Run Code Online (Sandbox Code Playgroud)
加载类后,您可以访问如下所示的类:
SootClass sClass = Scene.v().loadClassAndSupport(className); // "className" is like a.b.Myclass
Run Code Online (Sandbox Code Playgroud)
sClass现在您可以访问如下所示的字段和方法:
Chain<SootField> fieldList = sClass.getFields(); // import soot.util.Chain;
List<SootMethod> methods = sClass.getMethods();
Run Code Online (Sandbox Code Playgroud)
你可以迭代一个方法的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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
133 次 |
| 最近记录: |