PsiClass Visitor
Hi
I am trying to build an analysis where I can detect which methods and variables from other classes a PsiClass uses using a visitor, namely JavaElementVisitor.
Suppose we have a class like Foo:
class Foo {
void compute() {
Bar bar = new Bar();
Baz baz = new Baz();
FooBar fooBar = new FooBar();
if (baz.someVariable > 10) {
bar.doSomething(fooBar.someOtherVariable);
}
}
}
In the above example, Foo uses Bar's doSomething method, Baz's someVariable as well as FooBar's someOtherVariable.
My current understanding is that I can detect the doSomething method call using the visitMethodCallExpression, and use resolveMethod to see where doSomething comes from.
However, I'm unsure about how I would detect either someVariable or someOtherVariable.
The closest I got is to identify that the baz.someVariable is a PsiReferenceExpression. It looks to me however that unlike a PsiMethodCallExpression which is only applicable to method calls, there's a whole cohort of expression which can be a PsiReferenceExpression.
Thank you!
Radu
请先登录再写评论。
Hi,
Your assumption is correct and references to the variables are represented as PsiReferenceExpressions.
BTW you can use Tools | View PSI Structure of Current File... action to check how the text is represented in the PSI.
Anna
Hi Anna,
Thank you for your confirmation.
Yes, I use PsiViewer to analyse PsiTree structure, that's how I got to notice the abundance of PsiReferenceExpressions which is why I was slightly confused.
Having played around a little bit, I've narrowed my specific variable lookup to something that looks roughly like this
void visitReferenceExpression(PsiReferenceExpression expression) {
if (!expression.isQualified) return;
PsiElement expressionParent = expression.parent();
if (expressionParent instanceof PsiReferenceExpression) return;
PsiElement expressionSource = expression.resolve();
if (!(expressionSource instanceof PsiField)) return;
// get class of the PsiField etc.
}
Expression must be qualified as I am only interested in variables of other classes, and the parent of the expression mustn't be a PsiReferenceExpression as it means this is a branch of a broader PsiReferenceExpression.
Do you think the implementation is ok? Also, would there be any issues by providing this algorithm to an overridden visitReferenceExpression?
Thank you!
Radu
Just realised the first condition of my search is incomplete; I meant to write
what about references like ClassFQN.ourStaticField or classA.myFieldB.myFieldC. All in all the implementation looks similar to what we have normally, should be ok.
Anna