我正在使用JavaParser
库(https://github.com/javaparser/javaparser)来解析Java方法声明。我想从不同的包,类,范围等中识别出不同的方法声明,以便可以精确地识别每个方法声明。
例如:
这是一个名为MainClass.java
的Java文件:
package com.company.packA.packB;
public class MainClass {
void doTask(int x, int y) {
//...
}
private class InnerClass {
void doTask(int x, int y) {
//...
}
}
}
class AnotherClassSameFile {
void doTask(int x, int y) {
//...
}
}
请注意,上面的示例包含三个 void doTask(int x, int y)
方法:
com.company.packA.packB
→MainClass
→doTask(int x, int y)
com.company.packA.packB
→MainClass
→InnerClass
→doTask(int x, int y)
com.company.packA.packB
→AnotherClassSameFile
→doTask(int x, int y)
要标识具有相同方法签名的不同方法声明,我需要遍历所有父节点直到根节点。
到目前为止,我已经使用JavaParser
库尝试了以下代码(简化):
class MethodStruct { // the second example will be:
String parentNodes; // com.company.packA.packB#MainClass#InnerClass
String returnType; // void
String methodName; // doTask
String parameters; // int,int
}
class JavaParserTest {
// this is the method to be called from outside
static List<MethodStruct> getMethodStructs(Reader reader) {
CompilationUnit cu = JavaParser.parse(reader);
List<MethodStruct> methodStructs = new LinkedList<>();
cu.accept(new MethodVisitor(), methodStructs);
return methodStructs;
}
static class MethodVisitor extends VoidVisitorAdapter<List<MethodStruct>> {
@Override
public void visit(MethodDeclaration methodDeclaration, List<MethodStruct> methodStructs) {
super.visit(methodDeclaration, methodStructs);
// adding individual methodStruct into the list
methodStructs.add(getMethodStruct(methodDeclaration));
}
static MethodStruct getMethodStruct(MethodDeclaration methodDeclaration) {
return new MethodStruct(
getParents(methodDeclaration),
methodDeclaration.getTypeAsString(),
methodDeclaration.getNameAsString(),
getParameterAsString(methodDeclaration.getParameters()));
}
// it is the method to be concerned for my question
static String getParents(MethodDeclaration methodDeclaration) {
StringBuilder parents = new StringBuilder();
Node currentNode = methodDeclaration;
while (currentNode.getParentNode().isPresent()) {
// goto parent node
currentNode = currentNode.getParentNode().get();
//TODO: I'm stuck here. Help me please!
//TODO: How to identify each node whether
// it is a package, innerClass, etc?
}
// convert StringBuilder into String and return the String
return parents.toString();
}
static String getParameterAsString(NodeList<Parameter> parameters) {
// easy task! convert parameter string list
// into a single string (comma separated)
}
}
}
我在定义getParents(MethodDeclaration methodDeclaration)
方法时遇到困难。如何解决(即标识每个父节点)?我找不到实现目标的Node
类的任何有用方法。我可能错过了JavaParser
库中的某些内容。
答案 0 :(得分:0)
您应该尝试使用walk
方法来查找具体方法声明的所有范围:
static String getParents(fina MethodDeclaration methodDeclaration) {
final StringBuilder parents = new StringBuilder();
methodDeclaration.walk(Node.TreeTraversal.PARENTS, node -> {
if (node instanceof ClassOrInterfaceDeclaration) {
path.insert(0, ((ClassOrInterfaceDeclaration) node).getNameAsString());
path.insert(0, '$');
}
if (node instanceof ObjectCreationExpr) {
path.insert(0, ((ObjectCreationExpr) node).getType().getNameAsString());
path.insert(0, '$');
}
if (node instanceof MethodDeclaration) {
path.insert(0, ((MethodDeclaration) node).getNameAsString());
path.insert(0, '#');
}
if (node instanceof CompilationUnit) {
final Optional<PackageDeclaration> pkg = ((CompilationUnit) node).getPackageDeclaration();
if (pkg.isPresent()) {
path.replace(0, 1, ".");
path.insert(0, pkg.get().getNameAsString());
}
}
});
// convert StringBuilder into String and return the String
return parents.toString();
}