.java 报告生成,方法调用方和被调用方



欢迎来到互联网上最有帮助的社区!

我正在做一个可以读取.java文件并吐出数据的项目。我的一个提取数据的程序并没有按照我的意愿工作(非常老套)。它解析文件树中的所有.java文件,并使用linkedhashmap在.txt文件中列出调用方pkg.class.method和调用方pkg.class.method.等数据它做得很好,只是只给了我从一个方法调用的最后一个方法,而不是从每个方法调用的所有方法。我认为这是因为我在linkedhashmap中存储数据的方式,即一个键(调用方方法)和多个值(被调用的方法)。

我希望文本文件列出从第一次遇到的每个方法开始调用的每个方法。有办法绕过这个吗?

这是代码:

import japa.parser.JavaParser;
import japa.parser.ast.CompilationUnit;
import japa.parser.ast.body.MethodDeclaration;
import japa.parser.ast.expr.MethodCallExpr;
import japa.parser.ast.visitor.VoidVisitorAdapter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.LinkedHashMap;
/*--------------------------------------------------------------------------------------------------        
 *      TASK 3: Information Extraction, Method Caller and Method Callee
 *              This java code will extract data in 2 columns
 *              (Format:pkg.class.method). First column denotes the method
 *              from which another method is being called and the second
 *              column denotes the name of the called method.
 *--------------------------------------------------------------------------------------------------
 */
public class Task3 
{
    private static HashMap<String,String> methods = new LinkedHashMap<String,String>();
    static class ClassVisitor extends VoidVisitorAdapter<Object> 
    {
        private static String className = "";
        public void visit(japa.parser.ast.body.ClassOrInterfaceDeclaration n, Object arg) 
        {
            className = arg + "," + n.getName();
            new MethodVisitor().visit(n, className);
        }
    }
    static class MethodVisitor extends VoidVisitorAdapter<Object> {
        private static String methodName = "";
        @Override
        public void visit(MethodDeclaration n, Object arg) 
        {
            methodName = arg + "," + n.getName();
            new MethodCallVisitor().visit(n,methodName);
        }

    }
    static class MethodCallVisitor extends VoidVisitorAdapter<Object>{
        @Override
        public void visit(MethodCallExpr n, Object arg) 
        {
              String className=arg.toString();    
              methods.put(arg.toString(),className.substring(0,className.lastIndexOf(','))+","+n.getName());
        }

    }
    public static void main(String[] args) 
    {
        try 
        {
            ListFiles files = new ListFiles();
            String projPath = "C:\JavaBook\Final\JMencode_v0.64_src\";
            Path file = Paths.get(projPath);
            Files.walkFileTree(file, files);
            CompilationUnit compilationUnit = null;
            FileInputStream fileInputStream = null;
            String pkg = "";
            ClassVisitor codeVisitor = null;
            for (Path path : files.javaFiles) 
            {
                fileInputStream = new FileInputStream(path.toFile());
                try 
                {
                    compilationUnit = JavaParser.parse(fileInputStream);
                } 
                finally 
                {
                    fileInputStream.close();
                }
                pkg = compilationUnit.getPackage().getName().toString();
                codeVisitor = new ClassVisitor();
                codeVisitor.visit(compilationUnit, pkg);
            }
            File ouputFile = new File("C:\JavaBook\Final\src\pkg\Task_1_2_3\JMencode_v0.64_src_task3_" + methods.size() + ".txt");
            FileWriter fW = new FileWriter(ouputFile);
            fW.write("Caller Method" + " ttt " + "Callee Methodn");
            for (String callerMeth : methods.keySet()) 
            {
                fW.write(callerMeth + " ttt "+ methods.get(callerMeth)+"n");
                System.out.println(callerMeth + " ttt " + methods.get(callerMeth)+"n");
            }
            fW.close();
        } 
        catch (Exception ex) 
        {
            System.out.println("Exception in ProjectInfo " + ex.getMessage());
        }
    }
}

提前感谢大家!

在这种情况下,有多个值具有相同的键,所以您应该像这样声明方法映射:

private static HashMap<String, Set<String>> methods = new LinkedHashMap<String, Set<String>>();

并将值存储在一个集合中:

Set<String> set = methods.get(arg.toString());
if (set == null) {
  set = new HashSet<String>();
  methods.put(arg.toString(), set);
}
set.add(className.substring(0,className.lastIndexOf(','))+","+n.getName());

最新更新