Why my Symbol reference is unidirectional (no usages)?

I’ve created TypeScript to Java Symbol reference which matches service calls by class and method names. It works perfectly TS → Java way, but then in Java file I see “No usages”

I’ve implemented:
NavigatableSymbol, PsiSymbolReference and PsiSymbolReferenceProvider

Our symbols implementation might be found here:

What should I do more to see usages of Java class methods?

Hey Marcin,

Find usage machinery checks only those references that are provided by implementations of so-called reference searchers.
The idea is that if you are looking for references of a class Foo, you basically need to search for all text occurrences of Foo in all source files and check if each occurrence has a reference to Foo class. But Java reference searchers do not look into non-Java files, and it’s the responsibility of the plugin to provide a searcher that consumes all potential occurrences in other languages.
See com.intellij.psi.impl.search.JavaRecordComponentSearcher as an example.

Thank you for reply, first issue encountered: why it does not list methods?

After clicking around I got only what’s on screenshot. Selecting method results in PsiParameter being found only, and only if method has any parameters. Selecting non params method does nothing…

Using methodReferencesSearch instead worked.

Managed to make it work, if someone is looking for Java → TypeScript (TSX) reference searcher:

class HillaReferenceSearcher : QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters>() {

    override fun processQuery(queryParameters: MethodReferencesSearch.SearchParameters, consumer: Processor<in PsiReference>) {
        val element = queryParameters.method

        val searchHelper = PsiSearchHelper.getInstance(queryParameters.project)
        val scope = GlobalSearchScope.projectScope(queryParameters.project)
        val typeScriptFileType = TypeScriptJSXFileType.INSTANCE

        val filteredScope = GlobalSearchScope.getScopeRestrictedByFileTypes(scope, typeScriptFileType)
        searchHelper.processElementsWithWord(
            { psiElement, offset ->
                if (psiElement.elementType == JSElementTypes.REFERENCE_EXPRESSION) {
                    val range = TextRange(offset, offset + element.name.length)
                    val reference = object : PsiReferenceBase<PsiElement>(psiElement, range) {
                        override fun resolve(): PsiElement = psiElement
                    }
                    consumer.process(reference)
                }
                true // return false to stop the search early
            },
            filteredScope,
            element.name,
            UsageSearchContext.IN_CODE,
            true
        )

    }

}

If you spot any errors in above please add comment.

1 Like