Querying Whether there are any custom PsiReferences to a PsiFile?

Answered

If I have a PsiReferenceContributor, can I use that as a reverse index later?

Basically my PageReference's resolve to a PsiFile. Later I have an instance of a PsiFile and I want to know, are there any PageReference's that resolve to this file.

This is to decide whether I should show a line marker on the file or not.

Below is my PageReference if it matters

import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ContentIterator
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiReferenceBase
import nz.hailwood.plugin.displayPath
import nz.hailwood.plugin.pagesDirectory

class PageReference(element: PsiElement, textRange: TextRange) : PsiReferenceBase<PsiElement?>(element, textRange) {

private val key: String = element.text.substring(textRange.startOffset, textRange.endOffset)

override fun resolve(): PsiElement? = locateReferences(element.project, key).firstOrNull()

override fun getVariants(): Array<LookupElement> = locateReferences(element.project, null).map {
LookupElementBuilder
.create(it.virtualFile.displayPath(element.project))
.withIcon(it.fileType.icon)
}.toTypedArray()

private fun locateReferences(project: Project, name: String?): List<PsiFile> {
val pagesDir = project.pagesDirectory ?: return emptyList()

val references = mutableListOf<PsiFile>()

ProjectRootManager.getInstance(project).fileIndex.iterateContentUnderDirectory(pagesDir, object : ContentIterator {
override fun processFile(fileOrDir: VirtualFile): Boolean {
if (fileOrDir.isDirectory) {
return true
}

if (name == null || name == fileOrDir.displayPath(project)) {
PsiManager.getInstance(project).findFile(fileOrDir)?.let { file -> references.add(file) }
}

return true
}
})

return references
}

}

 

2 comments
Comment actions Permalink
Okay so it looks like I can do
val hasReferences = ReferencesSearch.search(
psiFile,
GlobalSearchScope.projectScope(psiFile.project)
).anyMatch { it is PageReference }
Is that going to be the most effective method?
0
Comment actions Permalink

Yes, that's the generic solution to reverse-search PsiReference.

0

Please sign in to leave a comment.