Java:如何使用 JavaParser 获取 Java class 的标识符数量

Java: how to use JavaParser to get number of identifiers of a Java class

我想使用 JavaParser 来获取 java class 具有的标识符的数量。

我下载了 JavaParser jar 文件并将其添加到我的项目中,然后,我遵循了一些 these 说明,现在我能够以编程方式解析一些 Java classes 并使用 ClassOrInterfaceDeclaration 中的方法,例如 .getMethods().getMembers() 等...

现在,我想知道如何获得每个 class 中的标识符数量。没有.getIdentifiers()方法,我应该采取什么方法?

如果你阅读了 AST(抽象语法树)中的 javadoc of javaparser-core, you will find that JavaParser.parse(...) returns a CompilationUnit, which is a Node

AST是可以遍历的,例如使用 walk(Consumer<Node> consumer).

这是一个将遍历 的 AST 并打印所有节点的程序。它将打印节点的 identifier,如果它有一个:

import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.nodeTypes.NodeWithIdentifier;

public class Test {
    public static void main(String[] args) throws Exception {
        String javaSource = "class MyClass {" +
                            "  void main(String[] args) {" +
                            "    int a = 5, b = 6;" +
                            "    int c = a * b;" +
                            "    System.out.println(c);" +
                            "  }" +
                            "}";

        System.out.printf("%-28s %-12s %s%n", "Node.class.simpleName", "Identifier", "Node.toString()");
        System.out.printf("%-28s %-12s %s%n", "=====================", "==========", "===============");
        JavaParser.parse(javaSource).walk(node -> {
            String identifier = "";
            if (node instanceof NodeWithIdentifier)
                identifier = ((NodeWithIdentifier<?>) node).getIdentifier();
            System.out.printf("%-28s %-12s %s%n",
                              node.getClass().getSimpleName(),
                              identifier,
                              node.toString().replaceFirst("(?s)\R.*", "..."));
        });
    }
}

输出

Node.class.simpleName        Identifier   Node.toString()
=====================        ==========   ===============
CompilationUnit                           class MyClass {...
ClassOrInterfaceDeclaration               class MyClass {...
SimpleName                   MyClass      MyClass
MethodDeclaration                         void main(String[] args) {...
SimpleName                   main         main
Parameter                                 String[] args
ArrayType                                 String[]
ClassOrInterfaceType                      String
SimpleName                   String       String
SimpleName                   args         args
VoidType                                  void
BlockStmt                                 {...
ExpressionStmt                            int a = 5, b = 6;
VariableDeclarationExpr                   int a = 5, b = 6
VariableDeclarator                        a = 5
PrimitiveType                             int
SimpleName                   a            a
IntegerLiteralExpr                        5
VariableDeclarator                        b = 6
PrimitiveType                             int
SimpleName                   b            b
IntegerLiteralExpr                        6
ExpressionStmt                            int c = a * b;
VariableDeclarationExpr                   int c = a * b
VariableDeclarator                        c = a * b
PrimitiveType                             int
SimpleName                   c            c
BinaryExpr                                a * b
NameExpr                                  a
SimpleName                   a            a
NameExpr                                  b
SimpleName                   b            b
ExpressionStmt                            System.out.println(c);
MethodCallExpr                            System.out.println(c)
FieldAccessExpr                           System.out
NameExpr                                  System
SimpleName                   System       System
SimpleName                   out          out
SimpleName                   println      println
NameExpr                                  c
SimpleName                   c            c