javajavaparser

JavaParser: Detect if FieldDeclaration is Interface Type


I am gathering class metadata using JavaParser to store in a JSON object. For each compilation unit I collect, I also collect a list of the FieldDeclarations. For each FieldDeclaration, I would like to see if the type is an interface type.

In the java doc I noticed that FieldDeclaration inherits isClassOrInterfaceDeclaration() from BodyDeclaration, however I would like something like isInterfaceDeclaration().

I notice, however, that the class ClassOrInterfaceDeclaration has a method isInterface(). Would it be irresponsible to take a FieldDeclaration f and do something like:

Boolean b = f.toClassOrInterfaceDeclaration().isInterface()

Ultimately I would like to distinguish whether a FieldDeclaration is of a Class type, or Interface type.

Something I have also considered is:

Type t = f.getElementType() ;
// Dodgy code ahead
if(t == Class) { // do something...}

If someone can point in me in the right direction, any help would be greatly appreciated.

Edit: Some exploratory testing I did yielded some unexpected results. I collected a list of Field declarations from a class, the fields are:

private String s;
private String addedState ;
// Component is an interface
private Component c ;

When performing isClassOrInterfaceDeclaration() on each of these fields, each one returned false. But when I performed:

f.forEach(n->System.out.println(n.getElementType().isClassOrInterfaceType())) ;

each one returned true.

My assumptions about what the expected output would be have been proven false.

Edit 2: I have come to realize why calling isClassOrInterfaceDeclaration() does not yield true, because the fields are literally not declaring a class or interface. I need to find a way to determine if the type is a Class or Interface.


Solution

  • I think what you are looking for is a Java symbol solver, which is included with JavaParser.

    To use it, you have to instantiate the parser a certain way

     //The files are jar files that contain types you want to resolve
     static final JavaParser createJavaParser(File... jarFiles) {
          CombinedTypeSolver typeSolver = new CombinedTypeSolver();
    
          //Allows you to resolve types that comes with the JDK 
          typeSolver.add(new ReflectionTypeSolver());
    
          // Make it so the parser can recognize types within the jar files
          try {
               for (File jar : jarFiles) {
                    typeSolver.add(new JarTypeSolver(jar));
               }
          } catch (IOException e) {
               e.printStackTrace();
          }
    
          // Create the config for the parser
          JavaSymbolSolver symbolSolver = new JavaSymbolSolver(typeSolver);
          ParserConfiguration parserConfiguration = new ParserConfiguration();
          parserConfiguration.setSymbolResolver(symbolSolver);
    
          // Construct the parser
          return new JavaParser(parserConfiguration);
     }
    

    If a CompilationUnit was contructed using a parser from this method, you can then use the following code to determine if the type of a FieldDeclaration is an interface type

     static final boolean hasInterfaceType(FieldDeclaration f) {
          return f.resolve().declaringType().isInterface();
     }