Eclipse AST 实现一个类信息统计小程序

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



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

康雨城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值