1

There is a little problem with JavaParser usage.

I've parsed source code file and get all methods from parsed interface. Each method has a few parameters. I can get types of this parameters as string, but I couldn't get original package name or class name of this type. I always get java parser classes names or packages. But I need original package name. En example if parsed method parameter has type String I wont his class name etc.

P.S parsing action is executing in build.gladle before compile task. Reflection is not possible.

Code:

// Create compilation unit for parsed file
CompilationUnit cu = StaticJavaParser.parse(sourceFile);

// Get ClassOrInterfaceDeclaration optional from the compilation unit for parsed file
Optional<ClassOrInterfaceDeclaration> parsedInterfaceOptional =
        cu.getInterfaceByName("InterfaceName");

// Get ClassOrInterfaceDeclaration from optional
ClassOrInterfaceDeclaration parsedInterface = parsedInterfaceOptional.get();

for (MethodDeclaration method : parsedInterface.findAll(MethodDeclaration.class)) {
    final NodeList<Parameter> parameters = method.getParameters();

// At this step I already have a list of method parameters(parameters).

// I am iterating through the all method parameters and try to get 
// original class name or class or package of the parameter type
for (Parameter parameter : parameters) {
        // Trying to get original class of the parameter type
        Class parameterTypeOriginalClass = parameter.type...
    }

Please help if you know how to do it. Still actual.

Jackkobec
  • 5,889
  • 34
  • 34

1 Answers1

2

JavaParser just parses the provided static source code (i.e. text) so it cannot resolve the actual fully qualified name of the used type. And you cannot get Class from it either. All that you can get using JavaParser is a String with fully qualified name of the used type, e.g. "com.package.Type1"). But you need to do it manually.

For example, you got a string type name "Type1" of the parameter which is "Type1 param"

  1. At first, you need to check if this type is not a primitive type from java.lang. If it does - then the fully qualified name of the type will be java.lang. + type name.

  2. If this is not a primitive, you need to check if this type presents among the import statements of the CompilationUnit. If yes, the fully qualified name of this type can be obtained from the import statement value + type name.

  3. If both first and second items didn't succeed, need to check if an inner class with this type is not declared in this CompilationUnit. If it does - than a fully qualified name will be package of the CompilationUnit + type name.

  4. If even the previous step didn't found anything - need to check if a root class of CompilationUnit extends any superclass or implements any interface and check them correspondingly in the same manner as was checked in item 3.

As you can see, it is not an easy task, but it definitely is a solvable one.

VadymVL
  • 5,366
  • 3
  • 26
  • 41
  • 1
    Thank you. The above algorithm is fair. Also I have asked developers of the JavaParser library and they answered that we need to use JavaSimbolSolver. JavaSimbolSolver is their library too. – Jackkobec Oct 21 '19 at 20:14
  • Great news, it seems that the JavaSymbolSolver is the right tool for this case and it already implements the algorithm above. – VadymVL Oct 22 '19 at 06:53
  • Do you have an example for this case with JavaSymbolSolver usage? – Jackkobec Oct 22 '19 at 13:18
  • I don't have an example, but you can see how to use it in the free book https://leanpub.com/javaparservisited/read_full under section `Solving Symbols and References` – VadymVL Oct 22 '19 at 14:08