Problem with Find Usages

Hi all,

I'm implementing a custom language plugin for Scheme. It's mostly working ok, but I can't get Find Usages (and consequently Rename) to work reliably. My symbol resolution seems to work, I can Cmd-click to navigate to the identifier definition and quick definition lookup also works. However, Find Usages does not in some cases. I've put a bunch of debug log in. For the following code:

(define get-sid-request
  (lambda (username password)
    <snip body>))



(define find-sid
  (lambda (lines)
    <snip body>))


(define get-sid
  (lambda (username password)
    (let* ((response (http:GET (get-sid-request username password)))
           (lines (string-split response (string #\newline))))
      (find-sid lines))))


Here Find Usages works for get-sid-request, both from the definition and the use. However it doesn't work for find-sid from either. Navigation does work for find-sid though - I can Cmd-click on the use and it will take me to the definition. I put some debugging log in my identifier class which implements PsiReference and PsiNamedElement. I also put some in my FindUsagesProvider.

This is running Find Usages on the usage of find-sid. The numbers are the identity hash values. You can see it resolving correctly from the usage to the def, it then calls canFindUsagesFor multiple times, calls getName() on the identifier and then the process seems to end.

Resolving 4671350 to 13957976
canFindUsagesFor 13957976: true
canFindUsagesFor 13957976: true
canFindUsagesFor 13957976: true
Returning name string find-sid for 13957976
Returning name string find-sid for 13957976


Find usages on the definition of find-sid, more or less the same.

Resolving 13957976 to null
canFindUsagesFor 13957976: true
canFindUsagesFor 13957976: true
canFindUsagesFor 13957976: true
Returning name string find-sid for 13957976
Returning name string find-sid for 13957976


Find Usages on the definition of get-sid-request, it continues after the point where find-sid stops and goes on to call isReferenceTo and correctly finds the reference.

Resolving 14747142 to null
canFindUsagesFor 14747142: true
canFindUsagesFor 14747142: true
canFindUsagesFor 14747142: true
Returning name string get-sid-request for 14747142
Returning name string get-sid-request for 14747142
Resolving 14747142 to null
14747142 resolves to null, comparing to 14747142
Resolving 7942760 to 14747142
7942760 resolves to 14747142, comparing to 14747142


And the same from the usage of get-sid-request.

Resolving 7942760 to 14747142
canFindUsagesFor 14747142: true
canFindUsagesFor 14747142: true
canFindUsagesFor 14747142: true
Returning name string get-sid-request for 14747142
Returning name string get-sid-request for 14747142
Resolving 14747142 to null
14747142 resolves to null, comparing to 14747142
Resolving 7942760 to 14747142
7942760 resolves to 14747142, comparing to 14747142


What's going on here? Another strange thing is that my getWordsScanner() function is never called, in fact I'm throwing UnsupportedOperationException from it at the moment. It seems like maybe the source isn't being tokenised correctly in this case, but I'm not sure where it's getting the scanner from.

Thanks for any help,
Colin

6 comments
Comment actions Permalink

*bump*

Does anyone have any ideas about this? I tried again on the weekend with Community Edition, figuring that I could debug the code and see where it was failing. I ported my code to Maia but I get exceptions in Intellij while debugging the Find Usages code and can't continue. Under Maia the getWordsScanner() is called, which it wasn't under 8.

Cheers,
Colin

0
Comment actions Permalink

Hi Colin,

I have also spent some time to get my plugin alone with Find Usage.
In my interpretation, the flow which IDEA runs on call of Find Usage may look as follows:

If the element at the cursor is an instance of PsiReference
    CounterPart = PsiReference.resolve()
    CounterPart must be an instance of PsiNamedElement
    if( FindUsagesProvider.canFindUsageFor(CounterPart) == true )
        then
          // IDEA uses the word cache to search for the text returned from the CounterPart.getName()
          // Once the element is located and the element is a reference
                  PsiReference.resolve()
          if( PsiReference.isReference(CounterPart) == true )
            then - Populate Usages pane with the PsiReference



Prerequisites:
    The PSI element at the cursor must be a PsiNamedElement or PsiReference.

I am not sure that the flow is quite correct, at least, mayHaveReferences is never called but according to the doc it should.
Hope, my finding will be helpful for you.

Serhiy

0
Comment actions Permalink

Hi Serhiy,

Thanks - that's interesting. The bit that I don't understand is that I'm returning true from canFindUsageFor(), but it's not calling resolve(). I'm wondering if for some reason it can't find the word in the word cache. I'm going to have another go at debugging it this weekend and see if I can see anything new.

Cheers,
Colin

0
Comment actions Permalink

So I got some time to debug this some more, and I think I see the problem. From what I can tell, the class that should be finding the usages in this case is the CachesBasedRefSearcher. This in turn invokes PsiSearchHelperImpl.processElementsWithTextInGlobalScope(). However this class calls StringUtil.getWordsIn() on my search string, which splits get-sid-request into 3 words since it's using Java identifier rules to split it. My scanner will return that as one word since it's aware of scheme naming rules, which seems to be why it never finds it (in my original message I said that get-sid-request was working - it now doesn't seem to).

Is there anything I can do to fix this? Is this actually my problem?

Cheers,
Colin

0
Comment actions Permalink

This seems to be my problem, it looks like a bug in IDEA. If I add a comment somewhere in my file, for example:

;;; get sid request
(define get-sid-request


and

;;; find sid
(define find-sid


Find Usages works perfectly. It seems that get-sid-request is split into 3 words, and a file has to contain all 3 of them for the search to continue. If I manually force that by putting it in a comment, it all works.

Cheers,
Colin

0
Comment actions Permalink

Bug filed: http://youtrack.jetbrains.net/issue/IDEA-25346

I think it's worth emphasising that I would never have found this if IntelliJ wasn't newly open source :-)

Cheers,
Colin

0

Please sign in to leave a comment.