FIR IDE: Visit only the smallest acceptable declaration if possible

This commit is contained in:
Roman Golyshev
2021-02-10 11:21:51 +03:00
committed by Space
parent c3831baba2
commit bc26230392
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.SmartPsiElementPointer import com.intellij.psi.SmartPsiElementPointer
import com.intellij.psi.util.parentsOfType
import com.intellij.util.containers.addIfNotNull import com.intellij.util.containers.addIfNotNull
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
@@ -44,7 +45,6 @@ import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFir import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFir
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirOfType
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.components.KtReferenceShortener import org.jetbrains.kotlin.idea.frontend.api.components.KtReferenceShortener
import org.jetbrains.kotlin.idea.frontend.api.components.ShortenCommand import org.jetbrains.kotlin.idea.frontend.api.components.ShortenCommand
@@ -65,11 +65,13 @@ internal class KtFirReferenceShortener(
private val context = FirShorteningContext(firResolveState) private val context = FirShorteningContext(firResolveState)
override fun collectShortenings(file: KtFile, selection: TextRange): ShortenCommand { override fun collectShortenings(file: KtFile, selection: TextRange): ShortenCommand {
resolveFileToBodyResolve(file) val declarationToVisit = file.findSmallestDeclarationContainingSelection(selection)
val firFile = file.getOrBuildFirOfType<FirFile>(firResolveState) ?: file.withDeclarationsResolvedToBodyResolve()
val firDeclaration = declarationToVisit.getOrBuildFir(firResolveState)
val collector = ElementsToShortenCollector(context) val collector = ElementsToShortenCollector(context)
firFile.acceptChildren(collector) firDeclaration.accept(collector)
return ShortenCommandImpl( return ShortenCommandImpl(
file, file,
@@ -79,13 +81,20 @@ internal class KtFirReferenceShortener(
) )
} }
private fun resolveFileToBodyResolve(file: KtFile) { private fun KtFile.withDeclarationsResolvedToBodyResolve(): KtFile {
for (declaration in file.declarations) { for (declaration in declarations) {
declaration.getOrBuildFir(firResolveState) // temporary hack, resolves declaration to BODY_RESOLVE stage declaration.getOrBuildFir(firResolveState) // temporary hack, resolves declaration to BODY_RESOLVE stage
} }
return this
} }
} }
private fun KtFile.findSmallestDeclarationContainingSelection(selection: TextRange): KtDeclaration? =
findElementAt(selection.startOffset)
?.parentsOfType<KtDeclaration>(withSelf = true)
?.firstOrNull { selection in it.textRange }
private data class AvailableClassifier(val classId: ClassId, val isFromStarOrPackageImport: Boolean) private data class AvailableClassifier(val classId: ClassId, val isFromStarOrPackageImport: Boolean)
private class FirShorteningContext(val firResolveState: FirModuleResolveState) { private class FirShorteningContext(val firResolveState: FirModuleResolveState) {