【程式碼重構 & JDT】遍歷AST,獲取每個節點的所有直接子節點
阿新 • • 發佈:2018-12-19
public class DataNode { public ASTNode node; //所代表的的AST節點 public int label; //編號 public List<Integer> childrenLables = new ArrayList<>(); //直接的子節點的編號 public List<ASTNode> childrenNodes = new ArrayList<>(); //直接的子節點 public boolean isLeaf = false; //是否是葉子節點 public String nodeType = "unknown"; } public static int ID = 0; //用來編號 // 輸入的是CompilationUnit根節點, label為0 public static void getDirectChildren(ASTNode node, int label, Map<Integer, DataNode> Nodes){ //先建立一個節點資料結構 DataNode myNode = new DataNode(); Nodes.put(label, myNode); myNode.label = label; myNode.node = node; myNode.nodeType = node.getClass().toString(); List listProperty = node.structuralPropertiesForType(); boolean hasChildren = false; for(int i = 0; i < listProperty.size(); i++){ StructuralPropertyDescriptor propertyDescriptor = (StructuralPropertyDescriptor) listProperty.get(i); if(propertyDescriptor instanceof ChildListPropertyDescriptor){//ASTNode列表 ChildListPropertyDescriptor childListPropertyDescriptor = (ChildListPropertyDescriptor)propertyDescriptor; Object children = node.getStructuralProperty(childListPropertyDescriptor); List<ASTNode> childrenNodes = (List<ASTNode>)children; for(ASTNode childNode: childrenNodes){ //獲取所有節點 if(childNode == null) continue; hasChildren = true; myNode.childrenNodes.add(childNode); myNode.childrenLables.add((++ID)); getDirectChildren(childNode, ID, Nodes);//繼續遞迴 //System.out.println("childrenList: "+childNode+" "+childNode.getClass()); } }else if(propertyDescriptor instanceof ChildPropertyDescriptor){//一個ASTNode ChildPropertyDescriptor childPropertyDescriptor = (ChildPropertyDescriptor)propertyDescriptor; Object child = node.getStructuralProperty(childPropertyDescriptor); ASTNode childNode = (ASTNode)child; if(childNode == null) continue; hasChildren = true; //獲取了這個節點 myNode.childrenNodes.add(childNode); myNode.childrenLables.add((++ID)); getDirectChildren(childNode, ID, Nodes);//繼續遞迴 //System.out.println("child: "+childNode +" "+childNode.getClass()); } } if(hasChildren){ //進行遞迴子節點 myNode.isLeaf = false; } else{ //結束,是葉子結點 myNode.isLeaf = true; } }