2009-06-10 140 views
4

鑑於在Eclipse下面的代碼:Eclipse的抽象語法樹DIFF

import org.eclipse.jdt.core.dom.AST; 
import org.eclipse.jdt.core.dom.ASTParser; 
import org.eclipse.jdt.core.dom.CompilationUnit; 

public class Question { 
    public static void main(String[] args) { 
     String source = "class Bob {}"; 
     ASTParser parser = ASTParser.newParser(AST.JLS3); 
     parser.setSource(source.toCharArray()); 
     CompilationUnit result = (CompilationUnit) parser.createAST(null); 

     String source2 = "class Bob {public void MyMethod(){}}"; 
     ASTParser parser2 = ASTParser.newParser(AST.JLS3); 
     parser2.setSource(source2.toCharArray()); 
     CompilationUnit result2 = (CompilationUnit) parser2.createAST(null); 
    } 
} 

你如何使用Eclipse比較API(org.eclipse.compare)找到AST區別? (而且可以這樣做外的一個插件?)

我在看下面的API

http://kickjava.com/src/org/eclipse/compare/structuremergeviewer/Differencer.java.htm http://kickjava.com/src/org/eclipse/jdt/internal/ui/compare/JavaStructureCreator.java.htm http://kickjava.com/src/org/eclipse/compare/CompareUI.java.htm

任何人都可以點示例代碼(或API - 但代碼是首選)。

回答

2

鑑於Eclipse不會執行AST差異化,也許OP想要根據忽略空格和註釋的語言構造找出兩個文件之間的差異。我們的Smart Differencer tool根據語言結構(變量,表達式,語句,塊,方法等)比較了兩個源文件,並描述了對這些元素進行抽象編輯操作的差異(刪除,複製,移動,重命名標識符區域,...)

+0

是否有任何開源解決方案? – 2010-11-11 20:25:03

5

GumTree做工作,免費:)

它也支持其他語言如javascript。

1

實際上,使用ASTNode的屬性來檢查相等性是很簡單的。之後,這取決於你,你想如何獲得差異。檢查代碼示例以進行相等性測試:

public class ASTCompare { 

    @SuppressWarnings("unchecked") 
    static boolean equals(ASTNode left, ASTNode right) { 
     // if both are null, they are equal, but if only one, they aren't 
     if (left == null && right == null) { 
      return true; 
     } else if (left == null || right == null) { 
      return false; 
     } 
     // if node types are the same we can assume that they will have the same 
     // properties 
     if (left.getNodeType() != right.getNodeType()) { 
      return false; 
     } 
     List<StructuralPropertyDescriptor> props = left 
       .structuralPropertiesForType(); 
     for (StructuralPropertyDescriptor property : props) { 
      Object leftVal = left.getStructuralProperty(property); 
      Object rightVal = right.getStructuralProperty(property); 
      if (property.isSimpleProperty()) { 
       // check for simple properties (primitive types, Strings, ...) 
       // with normal equality 
       if (!leftVal.equals(rightVal)) { 
        return false; 
       } 
      } else if (property.isChildProperty()) { 
       // recursively call this function on child nodes 
       if (!equals((ASTNode) leftVal, (ASTNode) rightVal)) { 
        return false; 
       } 
      } else if (property.isChildListProperty()) { 
       Iterator<ASTNode> leftValIt = ((Iterable<ASTNode>) leftVal) 
         .iterator(); 
       Iterator<ASTNode> rightValIt = ((Iterable<ASTNode>) rightVal) 
         .iterator(); 
       while (leftValIt.hasNext() && rightValIt.hasNext()) { 
        // recursively call this function on child nodes 
        if (!equals(leftValIt.next(), rightValIt.next())) { 
         return false; 
        } 
       } 
       // one of the value lists have additional elements 
       if (leftValIt.hasNext() || rightValIt.hasNext()) { 
        return false; 
       } 
      } 
     } 
     return true; 
    } 
}