这个是对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;
}
}
test 类
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包可私信