How to distinguish a user-defined class and API class using Eclipse JDT ITypeBinding

75 Views Asked by At

I am using the following code while parsing a method invocation:

ITypeBinding typeBinding = node.getExpression().resolveTypeBinding();
if ( typeBinding != null) //type resolution found actual type
    {
        className = typeBinding.getName();
    }

where className is a String containing the name of the type. Is there a way to distinguish between user-defined Java class names and API class names or external/included library class names in a method invocation?

For example, given a complete invocation String.valueOf(c);, I want to detect String as a non-user-defined class name with a method invocation valueOf.

For the following code snippet: MyCalculator calc = new MyCalculator(); calc.add(1,2);

Given the invocation calc.add(1,2), I want to detect MyCalculator as a user-defined class name with a method invocation add

I am including a code snippet showing how I set up parsing. Maybe someone can point put any errors in the setup.

 private static CompilationUnit parse(String unit) {
    ASTParser parser = ASTParser.newParser(AST.JLS8);
    parser.setResolveBindings(true);
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setBindingsRecovery(true);

    File f = new File(currentFilePath);        
    String unitName = f.getName();
    parser.setUnitName(unitName);

    String[] sources = {Constants.SOURCES}; 
    String[] classpath = {Constants.CLASSPATH};

    parser.setEnvironment(classpath, sources, new String[] { "UTF-8"}, true);
    parser.setSource(unit.toCharArray());

    return (CompilationUnit) parser.createAST(null); 
}

where Constants.SOURCES is public static String SOURCES = "F:\\BluetoothChat"; the path to the root folder of the Java project being parsed.

1

There are 1 best solutions below

3
Stephan Herrmann On

JDT's Java Model has the notion that every IType is contained in an IPackageFragment which is rooted in an IPackageFragmentRoot. The latter represents either a source folder or a library (jar, class folder etc.).

This means, if you have resolved AST (DOM), you could ask the ITypeBinding representing the method receiver: getJavaElement(). The result should actually be an IType, which will tell you its package fragment root if you just say type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT).

Looking at the package fragment root there are several options to figure out, what exactly you have, e.g., isArchive(). Also getResolvedClasspathEntry() can tell you, how this thing got pulled into compilation. Based on this information you can draw whatever line you wish between "your" code and "API".