AssignableFrom check on PsiClassType, given a FQ class name String

Hi

If I have a reference to a PsiClassType instance, what is the most economic way to check whether the class behind that PsiClassType instance is of a certain type x. All I have is x as a FQ class name String.

For example, check whether the class behind the PsiClassType instance pct is of type java.util.List. I'm currently using PsiClassType.isAssignableFrom(pct) but in order to achieve this, I first have to create a PsiClassType from the FQ class name String "java.util.List". Although this works fine, I'm not sure if that's the best way to do.

Any help on this would be highly appreciated. Thanks in advance.

etienne

9 comments


etienne wrote:

If I have a reference to a PsiClassType instance, what is the most
economic way to check whether the class behind that PsiClassType
instance is of a certain type x. All I have is x as a
FQ class name String.


PsiType.equalsToText()

Bas

0

This is not correct for generic types.

0

The right solution is to resolve and check FQ name of the resolved class. Though it may seem to be expensive, the methods listed before are going to trigger resolve in most cases anyway.

0

Sorry, checking FQ name is of course not what you need if you try to ensure isAssignable(). The real implementation of isAssignable is rather complex, but for checking assignability for simple class types like java.util.List without type parameters, you could indeed resolve and check isInheritor() for classes.

0

Unfortunately, this won't work since java.util.ArrayList is also of type java.util.List but won't be true for equalsToText().

0

Hi Evgueny

I'm not sure about how to resolve the class from the String. Would you mind commenting on the code below, which is what I currently do:

PsiField field = ...;
PsiClassType rootType = field.getManager().getElementFactory().createTypeByFQClassName("java.util.List", field.getResolveScope());
boolean isAssignable = rootType.isAssignableFrom(field.getType());

Suggestions for improvements would be appreciated very much.

etienne

0

My guess:

should be faster than createTypeByFQClassName() ?!

0

Yep,

what I meant is resolving the class type you already have, and then calling findClass().

Still
PsiManager.getInstance(project).findClass(clazzName, class1.getResolveScope());
would be better, since it is going to handle multi jdk projects correctly.

0

Hi Yann and Evgueny

Thanks for the feedback. I have made use of your suggestions and everything works fine.

etienne

0

Please sign in to leave a comment.