Генерация отчета.java, метод Caller & Callee
Привет самым полезным сообществом в Интернете!
Я работаю над проектом, который может читать файл.java и выкладывать данные. Одна из моих программ для извлечения данных не работает точно так, как я намереваюсь работать (очень клише). Он анализирует все файлы.java в дереве файлов и перечисляет данные, такие как вызывающий файл pkg.class.method и файл pkg.class.method, в файле.txt с использованием таблицы связанных ссылок. Он делает все правильно, за исключением того, что он дает мне только последний метод, вызванный из метода, а не все методы, вызываемые из каждого метода. Я думаю, это из-за того, как я храню данные в связанной хэш-карте, то есть один ключ (метод вызывающего абонента) и несколько значений (так называемый метод).
Я хочу, чтобы в текстовом файле были перечислены все методы, вызываемые из каждого метода, начиная с первого. Это можно обойти?
Вот код:
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" + " \t\t\t " + "Callee Method\n");
for (String callerMeth : methods.keySet())
{
fW.write(callerMeth + " \t\t\t "+ methods.get(callerMeth)+"\n");
System.out.println(callerMeth + " \t\t\t " + methods.get(callerMeth)+"\n");
}
fW.close();
}
catch (Exception ex)
{
System.out.println("Exception in ProjectInfo " + ex.getMessage());
}
}
}
Спасибо всем заранее!
1 ответ
В этом случае есть несколько значений с одинаковым ключом, поэтому вы должны объявить методы map следующим образом:
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());