JavaParser: как получить все имена ParentNode из MethodDeclaration? - PullRequest
0 голосов
/ 02 января 2019

Я использую библиотеку JavaParser (https://github.com/javaparser/javaparser) для анализа объявлений методов Java. Я хочу идентифицировать различные объявления методов из разных пакетов, классов, областей и т. Д., Чтобы я мог точно идентифицировать все объявления методов.

Например:

Вот файл Java с именем 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) {
        //...
    }
}

Обратите внимание, что приведенный выше пример содержит три void doTask(int x, int y) методы:

  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)

Чтобы идентифицировать различные объявления методов с одинаковыми сигнатурами методов, мне нужно пройти через все родительские узлы до корневого узла.

До сих пор я пробовал этот код (упрощенно), используя 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.

1 Ответ

0 голосов
/ 09 мая 2019

Вы должны попытаться использовать метод 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...