2

I am using JavaParser library (https://github.com/javaparser/javaparser) for parsing Java method declarations. I want to identify different method declarations from different packages, classes, scopes, etc. so that I can precisely identify every method declarations.

For example:

Here is a Java file called MainClass.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) {
        //...
    }
}

Notice that the above example contains three void doTask(int x, int y) methods:

  1. com.company.packA.packBMainClassdoTask(int x, int y)
  2. com.company.packA.packBMainClassInnerClassdoTask(int x, int y)
  3. com.company.packA.packBAnotherClassSameFiledoTask(int x, int y)

To identify different method declarations with the same method signatures, I need to traverse all parent nodes until the root node.

So far I have tried this code (simplified) using JavaParser library:

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)
        }
    }
}

I am facing difficulties in defining my getParents(MethodDeclaration methodDeclaration) method. How can I solve it (i.e., identify every parent nodes)? I can't find any useful method of Node class for my goal. I might have missed something in JavaParser library.

arnobpl
  • 1,126
  • 4
  • 16
  • 32

1 Answers1

-1

You should try to use walk method to find all scopes of concrete method declaration:

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();
}
Alexey Nikitin
  • 604
  • 7
  • 22