Added caching for local label references.
This commit is contained in:
parent
66fa728a45
commit
56697ac1df
@ -6,6 +6,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementResolveResult
|
||||
import com.intellij.psi.PsiPolyVariantReferenceBase
|
||||
import com.intellij.psi.ResolveResult
|
||||
import com.intellij.psi.impl.source.resolve.ResolveCache
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.SmartList
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kGlobalLabel
|
||||
@ -15,12 +16,45 @@ import de.platon42.intellij.plugins.m68k.psi.M68kSymbolReference
|
||||
|
||||
class M68kLocalLabelReference(element: M68kSymbolReference) : PsiPolyVariantReferenceBase<M68kSymbolReference>(element, TextRange(0, element.textLength)) {
|
||||
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> {
|
||||
val refName = myElement.symbolName
|
||||
companion object {
|
||||
val INSTANCE = Resolver()
|
||||
|
||||
return findLocalLabels { it.name == refName }
|
||||
.map { PsiElementResolveResult(it) }
|
||||
.toTypedArray()
|
||||
fun findLocalLabels(element: M68kSymbolReference, predicate: (M68kLocalLabel) -> Boolean): List<M68kLocalLabel> {
|
||||
val statement = PsiTreeUtil.getStubOrPsiParentOfType(element, M68kStatement::class.java)!!
|
||||
val results: MutableList<M68kLocalLabel> = SmartList()
|
||||
// go backward
|
||||
var currentStatement = PsiTreeUtil.getPrevSiblingOfType(statement, M68kStatement::class.java)
|
||||
while (currentStatement != null) {
|
||||
val child = currentStatement.firstChild
|
||||
if (child is M68kGlobalLabel) break
|
||||
if (child is M68kLocalLabel && predicate.invoke(child)) results.add(child)
|
||||
currentStatement = PsiTreeUtil.getPrevSiblingOfType(currentStatement, M68kStatement::class.java)
|
||||
}
|
||||
// go forward
|
||||
currentStatement = statement
|
||||
while (currentStatement != null) {
|
||||
val child = currentStatement.firstChild
|
||||
if (child is M68kGlobalLabel) break
|
||||
if (child is M68kLocalLabel && predicate.invoke(child)) results.add(child)
|
||||
currentStatement = PsiTreeUtil.getNextSiblingOfType(currentStatement, M68kStatement::class.java)
|
||||
}
|
||||
return results
|
||||
}
|
||||
}
|
||||
|
||||
class Resolver : ResolveCache.PolyVariantResolver<M68kLocalLabelReference> {
|
||||
override fun resolve(ref: M68kLocalLabelReference, incompleteCode: Boolean): Array<ResolveResult> {
|
||||
val refName = ref.element.symbolName
|
||||
|
||||
return findLocalLabels(ref.myElement) { it.name == refName }
|
||||
.map { PsiElementResolveResult(it) }
|
||||
.toTypedArray()
|
||||
}
|
||||
}
|
||||
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> {
|
||||
return ResolveCache.getInstance(element.project)
|
||||
.resolveWithCaching(this, INSTANCE, false, incompleteCode)
|
||||
}
|
||||
|
||||
override fun resolve(): PsiElement? {
|
||||
@ -29,30 +63,10 @@ class M68kLocalLabelReference(element: M68kSymbolReference) : PsiPolyVariantRefe
|
||||
}
|
||||
|
||||
override fun getVariants(): Array<Any> {
|
||||
return findLocalLabels { true }
|
||||
return findLocalLabels(element) { true }.asSequence()
|
||||
.distinct()
|
||||
.map { LookupElementBuilder.createWithIcon(it) }
|
||||
.toList()
|
||||
.toTypedArray()
|
||||
}
|
||||
|
||||
private fun findLocalLabels(predicate: (M68kLocalLabel) -> Boolean): List<M68kLocalLabel> {
|
||||
val statement = PsiTreeUtil.getStubOrPsiParentOfType(element, M68kStatement::class.java)!!
|
||||
val results: MutableList<M68kLocalLabel> = SmartList()
|
||||
// go backward
|
||||
var currentStatement = PsiTreeUtil.getPrevSiblingOfType(statement, M68kStatement::class.java)
|
||||
while (currentStatement != null) {
|
||||
val child = currentStatement.firstChild
|
||||
if (child is M68kGlobalLabel) break
|
||||
if (child is M68kLocalLabel && predicate.invoke(child)) results.add(child)
|
||||
currentStatement = PsiTreeUtil.getPrevSiblingOfType(currentStatement, M68kStatement::class.java)
|
||||
}
|
||||
// go forward
|
||||
currentStatement = statement
|
||||
while (currentStatement != null) {
|
||||
val child = currentStatement.firstChild
|
||||
if (child is M68kGlobalLabel) break
|
||||
if (child is M68kLocalLabel && predicate.invoke(child)) results.add(child)
|
||||
currentStatement = PsiTreeUtil.getNextSiblingOfType(currentStatement, M68kStatement::class.java)
|
||||
}
|
||||
return results
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user