Is it possible to statically distinguish between fully qualified names and nested class types?

I am using JavaParser (open source) to parse the following code.

package testfiles.simple.tricky.before;

import testfiles.simple.before.InnerClassSample;

public class InnerClassReference {
    public void ref(InnerClassSample.MyInnerClass myInnerClass, java.util.List<Long> list) {
        int i = 0;
    }
}

Under the methodDeclaration node named ref, I get the parameter node hierarchy as follows:

// myInnerClass
Parameter
  ClassOrInterfaceType:
    ClassOrInterfaceType:
      SimpleName: InnerClassSample
    SimpleName: MyInnerClass
  SimpleName: myInnerClass
// list
Parameter
  ClassOrInterfaceType:
    ClassOrInterfaceType:
      ClassOrInterfaceType:
        SimpleName: java
      SimpleName: util
    SimpleName: List
  SimpleName: list

I need to find the fully qualified names for each parameter. So for myInnerClass I would get testfiles.simple.before.InnerClassSample$MyInnerClass and for list it would be java.util.List.

I understand that normally one would write List<Long> and put an import statement instead of writing java.util.List<Long>, however, I need to handle cases where the FQN is written in the parameter.

Now my question is, is there a way statically to distinguish if such a parsed tree is a type for a nested class, or it is merely a fully qualified name of a class?

I have thought about distinguishing by checking if the SimpleName starts with a lower case letter (meaning it is a package name), but, this is only a convention so we cannot assume safely that a developer would always start a package name with a lower case letter, or start a class name with a capital letter, hence I do not think this is a good way.

Any idea or insight about this matter would be much appreciated.


Solution 1:

It is unfortunately not possible to distinguish between the name of a top-level class and the name of a nested class from only the qualified name, or by analysing only a single source file. At least not in all cases.

To make that distinction you have to perform a resolution step, to find out what the names reference. This necessarily involves multiple source files.

The resolution step probably involves looking at the information in the AST or the class files of the referenced elements.


Note: Even if the resolution step involves multiple source files that information is still static information.