这个是对Eclipse AST 获取与访问的介绍,http://blog.csdn.net/LoveLion/article/details/19050155 (我的老师的博客)
本文的工具类完全来自于该文章,其他的类有这篇文章的影子
首先是 工具类,不多讲,请看老师的介绍
package com.kyc.rec; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.CompilationUnit; public class JdtAstUtil { /** * get compilation unit of source code * @param javaFilePath * @return CompilationUnit */ public static CompilationUnit getCompilationUnit(String javaFilePath){ byte[] input = null; try { BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(javaFilePath)); input = new byte[bufferedInputStream.available()]; bufferedInputStream.read(input); bufferedInputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } ASTParser astParser = ASTParser.newParser(AST.JLS3); astParser.setSource(new String(input).toCharArray()); astParser.setKind(ASTParser.K_COMPILATION_UNIT); CompilationUnit result = (CompilationUnit) (astParser.createAST(null)); return result; } }接下来是DTO用来存储类中方法的相关信息
package com.kyc.rec; public class MethodDTO { private String name;//方法名 private int codeLength;//方法的代码长度 private int numOfParam;//方法参数个数 public MethodDTO(String name,int codeLength,int numOfParam){ setName(name); setCodeLength(codeLength); setNumOfParam(numOfParam); } public MethodDTO(){ } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCodeLength() { return codeLength; } public void setCodeLength(int codeLength) { this.codeLength = codeLength; } public int getNumOfParam() { return numOfParam; } public void setNumOfParam(int numOfParam) { this.numOfParam = numOfParam; } }下面开始访问,其他访问都不难,只是在获取参数最多的方法的名字时,对我来说有点小麻烦,,因为我对AST的了解还很肤浅,不知道有没有更先进的技术可以使我的方法变得简单
package com.kyc.rec; import java.util.ArrayList; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.TypeDeclaration; public class DemoVisitor extends ASTVisitor { /*类中方法的个数、 * 属性的个数、 * 源代码行数、 * 代码行最多的方法名以及 * 代码行数、 * 参数个数最多的方法名 * 及其参数的个数等信息*/ public int numOfMethod=0;//方法个数 public int numOffield=0;//属性个数 public int codeLength=0;//代码总行数 public int index=-1;//用于获取参数的时候,指向上一个方法; public int[] listOfParam=new int[100]; private int numOfParam=0; private ArrayList<MethodDTO> arrayList =new ArrayList<MethodDTO>();//存储类中方法的相关信息 public void print(){ System.out.println("属性个数为:"+numOfMethod); System.out.println("方法个数为:"+numOffield); System.out.println("代码行数为:"+codeLength); System.out.println("代码行最多的方法:"+findLongestCodeLength().getName()+ "行数为:"+findLongestCodeLength().getCodeLength()); System.out.println("参数最多的方法:"+findMaxNumOfParam().getName()+ "方法数为:"+findMaxNumOfParam().getNumOfParam()); // for(int i=0;i<arrayList.size();i++){ // System.out.println(arrayList.get(i).getName()+" - "+arrayList.get(i).getNumOfParam()); // } } @Override public boolean visit(FieldDeclaration node) { numOffield++; return true; } @Override public boolean visit(MethodDeclaration node) { if(index!=-1){ arrayList.get(index).setNumOfParam(numOfParam); numOfParam=0; } index++; //System.out.println("Method:\t" + node.getName()+" "+node.getLength()); numOfMethod++; CountLength cl=new CountLength(); cl.countLength(node.toString(), "\n"); addToArrayList(new MethodDTO(node.getName().toString(), cl.getCodeLength(),0)); return true; } @Override public boolean visit(TypeDeclaration node) { //该方法可访问类名 //System.out.println("Class:\t" + node.getName()); return true; } @Override public boolean visit(CompilationUnit node){ //该方法可获得代码的总行数 CountLength cl=new CountLength(); cl.countLength(node.toString(), "\n"); codeLength=cl.getCodeLength(); return true; } public void addToArrayList(MethodDTO meDto) { arrayList.add(meDto); } public MethodDTO findLongestCodeLength(){ //获取代码行数最多的方法 int maxLength=0; MethodDTO methodDTO=new MethodDTO(); for(int i=0;i<arrayList.size();i++){ if(arrayList.get(i).getCodeLength()>maxLength){ maxLength=arrayList.get(i).getCodeLength(); } } for(int i=0;i<arrayList.size();i++){ if(arrayList.get(i).getCodeLength()==maxLength){ methodDTO=arrayList.get(i); break; } } return methodDTO; } public MethodDTO findMaxNumOfParam(){ //获取参数最多的方法 //这个方法与上一个方法存在明显的代码的坏味道(重复代码),可以对此进行优化 int maxNum=0; MethodDTO methodDTO=new MethodDTO(); for(int i=0;i<arrayList.size();i++){ if(arrayList.get(i).getNumOfParam()>maxNum){ maxNum=arrayList.get(i).getNumOfParam(); } } for(int i=0;i<arrayList.size();i++){ if(arrayList.get(i).getNumOfParam()==maxNum){ methodDTO=arrayList.get(i); break; } } return methodDTO; } @Override public boolean visit(SingleVariableDeclaration node){ //本方法在执行visit(MethodDeclaration node)后执行 Method中的参数次; numOfParam++; return true; } public void dotheEndParam(){ arrayList.get(index).setNumOfParam(numOfParam); } }
package com.kyc.rec; public class CountLength { //此类用于获取字符串中换行字符的个数,str2代表子字符串 private int codeLength=0; public int getCodeLength() { return codeLength; } public void setCodeLength(int codeLength) { this.codeLength = codeLength; } public int countLength(String str1, String str2) { if (str1.indexOf(str2) == -1) { return 0; } else if (str1.indexOf(str2) != -1) { codeLength++; countLength(str1.substring(str1.indexOf(str2) + str2.length()), str2); return codeLength ; } return 0; } }
package com.kyc.rec; import org.eclipse.jdt.core.dom.CompilationUnit; public class DemoVisitorTest { public DemoVisitorTest(String path) { CompilationUnit comp = JdtAstUtil.getCompilationUnit(path); DemoVisitor visitor = new DemoVisitor(); comp.accept(visitor); visitor.dotheEndParam(); visitor.print(); } public static void main(String[] args) { new DemoVisitorTest("DemoVisitor.java"); } }结果如下:
jar包可私信