Pass in the "right" element to Find Usage Handler

I am implementing a custom FindUsagesHandler for my custom language:

public class MyFindUsagesHandler extends FindUsagesHandler{
public MyFindUsagesHandler(PsiElement psiElement) {
super(psiElement);
}

@Override
public boolean processElementUsages(@NotNull final PsiElement element,
@NotNull final Processor<UsageInfo> processor,
@NotNull final FindUsagesOptions options) {
/* process here */
return true;
}
}

The problem is, the parameter "element" I got at this point is wrong. It seems somewhere in intellij will call reference.resolve and pass in the reference of the element that I clicked on. I don't want that. I want the exact element that I clicked on.

The reason why I need this is my custom language allows a variable to be the definition and usage of other variables at the same time. That is, if I have a vairable v2, whose reference.resolve() is v1, and v1.reference.resolve() is v0, when I click "find usage" on v1 I expect v1 to be passed in processElementUsages but not v0.

How should I handle this? Thanks!

14 comments
Comment actions Permalink

Hello Yen,

is the element which is passed to

processElementUsages

somewhere near the element you expect? I mean, is it a complex element which is made of parts, and a wrong part is passed?
0
Comment actions Permalink

Are you asking if intelliJ detects the wrong element? If so then no, I think that part is handled correctly. Because if a variable v0's reference.resovle() is null, then the element passed in processElementUsages is v0, as expected.

0
Comment actions Permalink

so is element passed to 

processElementUsages - correct?
0
Comment actions Permalink

Depends.

Says there are 3 variables v2, v1, v0.

v2.reference.resolve() is v1.

v1.reference.resolve() is v0.

v0.reference.resolve() is null.

 

Currently:

When I click on v2, the element passed to processElement is v1.

When I click on v1, the element passed to processElement is v0.

When I click on v0, the element passed to processElement is v0.

 

What I want: 

When I click on v2, the element passed to processElement is v2.

When I click on v1, the element passed to processElement is v1.

When I click on v0, the element passed to processElement is v0.

 

0
Comment actions Permalink

yes it seems that the element passed to 

FindUsagesHandler

is the resolved one.

 

Could you tweak "resolve" to it always points to the element itself?

You could tweak search too, so the correct elements are found.

 

-1
Comment actions Permalink

... If I tweak resolve then how am I supposed to get the correct result when I need resolve() method?

0
Comment actions Permalink

well you'd need to tweak something. Most likely, in a few places.

here is an idea:

in your FindUsagesHandler implementation, override this method:

@NotNull
@Override
public PsiElement[] getPrimaryElements()

to always return the element passed in to FindUsagesHandler ctor.

this may give you the expected result.

-1
Comment actions Permalink

.... No. That's the wrong place to tweak. The right element should be pass to its constructor. Something needs to be done before that. 

0
Comment actions Permalink

I don't quite understand why passing correctly resolved element to find usage handler breaks find usage..

0
Comment actions Permalink

It fixes "find usage" and then it breaks "go to definition" and wherever else that I need it to perform correctly 

0
Comment actions Permalink

I wouldn't worry if find usage returns too many results.

If it left usages out, this would be a bigger problem.

-1
Comment actions Permalink

...........

How is it related to my problem....

You are just not helping at all

0
Comment actions Permalink

well this surely wasn't related to any of my problems.

0
Comment actions Permalink

Yes, stop bothering me with unrelated replies would be appreciated. 

0

Please sign in to leave a comment.