0

I want to use JavaParser to get the number of identifiers that a java class has.

I downloaded JavaParser jar file and added it to my project, then, I followed some of these instructions and now I am able to programatically parse some Java classes and use methods from ClassOrInterfaceDeclaration like .getMethods(), .getMembers(), etc...

Now, I am wondering how can I get the number of identifiers in each class. There is no .getIdentifiers() method, so what approach should I take?

undisp
  • 711
  • 3
  • 11
  • 34
  • identifier (in class) is method or member variable. so number of identifiers is sum of method of members. – Bartosz Bilicki May 05 '18 at 16:56
  • The code `class MyClass { void main(String[] args) { int a = 5, b = 6; int c = a * b; System.out.println(c); } }` syntactically uses 13 *identifiers* ([see JLS 3.8](https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.8)): `MyClass`, `main`, `String`, `args`, `a`, `b`, `c`, `a`, `b`, `System`, `out`, `println`, and `c`. Is that the count you're looking for? If not, please clarify the question. If it is, the approach you should take is to write some code to do that counting while navigating the AST. – Andreas May 05 '18 at 17:10
  • Yes, that is what I want to count, but I can't manage to find a way to do it withe the JavaParser. @Andreas – undisp May 05 '18 at 17:53

1 Answers1

3

If you read the javadoc of javaparser-core, you will find that JavaParser.parse(...) returns a CompilationUnit, which is a Node in the AST (Abstract Syntax Tree).

The AST can be traversed, e.g. using walk(Consumer<Node> consumer).

Here is a program that will walk the AST of the source previously posted in a comment, and print all the nodes. It will print the identifier of the node, if is has one:

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.*", "..."));
        });
    }
}

Output

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
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Thank you very much for your help. This seems to be exactly what I am looking for, but when compiling, I get an error in the line `JavaParser.parse(javaSource).walk(node -> {` "cannot find symbol" referring to the `.walk()` method. Do you know where can be the problem? – undisp May 05 '18 at 23:32
  • @undisp Seems the `walk(...)` methods were added in version 3.5, so perhaps you're running an older version. I used version 3.6.3. – Andreas May 06 '18 at 03:24
  • That was actally the problem. I was using version 3.0.1. Thank you very much for your help! – undisp May 06 '18 at 16:51