Receiver type given a possibly unqualified PsiMethodCallExpression? Follow
Given a PsiMethodCallExpression, how can I discover the actual static receiver type?
I don't want to do resolveMethod.type, because that will give me the class within which the method was declared.
Is there a utility function that I can use for this?
Or can/should I use receiverType from javaUCallExpressions.kt for this purpose?
Please sign in to leave a comment.
Hi Christian,
what is "actual static receiver type", e.g. if the method is instance method?
I believe that you need to check if `call.getMethodExpression().getQualifierExpression()` is `null`. If yes, then the type corresponds to the method's containing class; if not, then you need to call `getType()` on the qualifier. It's effectively what is done in UAST util but I'd rather suggest to write this piece manually as the api is not stable yet.
Anna
Hi Anna
By "actual static receiver type", I mean the receiver type that is known through static analysis. I probably should have just said the "receiver type" :)
For example,
class Entity { deleteEntity() }
class Student extends Entity { someMethod() { deleteEntity() }
At the call site of deleteEntity, the receiver type is known to be "at least" of type Student.
Sure, in the case of qualified method calls, this is easy to accomplish via the qualifierExpression.
However, in the case of unqualified method calls, this method may be inherited from the parent class.
Further, I might be accessing this within a lambda or from within a nested class, so just looking up the method that contains the method call in question might not be enough, right?
Cheers
Chris
If you resolve a method call and call `getContainingClass()` it will return a class where the method is defined and thus the receiver type. Or do you mean that you need the current "this" of the call? If so, please explain what you are going to do with this type
Anna
Exactly, I want to know what the "current this" is,.
For all for all these delete() calls, I want to find out that the call will apply to the Student object.
Live plugin experiments
> If you resolve a method call and call `getContainingClass()` it will return a class where the method is defined and thus the receiver type
Yes, that's why I wrote "I don't want to resolveMethod.wrongThing *because that will give me the class within which the method was declared.*
Does IntelliJ not have a utility function to determine the type of receiver for unqualified calls? Or is that why call hierarchy doesn't take it into account? :)
This seems to work on the examples I threw at it:
I simply walk to parents of the node and do an inheritance check. Is there no built in functionality for this?
Also, is there no "isSubtypeOf" check, because isInheritor isn't reflective and I need to do an equality check beforehand.
Cheers
Chris
Try to look at `com.intellij.psi.util.InheritanceUtil#findEnclosingInstanceInScope` where you find class by `call.resolveMethod().getContainingClass()`