FIR IDE: Get rid of originalPosition in KtFirCompletionCandidateChecker

This commit is contained in:
Roman Golyshev
2020-09-07 18:31:30 +03:00
parent 828fc2520c
commit 8c876e4621
4 changed files with 15 additions and 17 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.idea.completion
import com.intellij.codeInsight.completion.* import com.intellij.codeInsight.completion.*
import com.intellij.patterns.PlatformPatterns import com.intellij.patterns.PlatformPatterns
import com.intellij.patterns.PsiJavaPatterns import com.intellij.patterns.PsiJavaPatterns
import com.intellij.psi.PsiElement
import com.intellij.util.ProcessingContext import com.intellij.util.ProcessingContext
import org.jetbrains.kotlin.idea.frontend.api.InvalidWayOfUsingAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.InvalidWayOfUsingAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
@@ -81,7 +80,7 @@ private object KotlinAvailableScopesCompletionProvider {
val (implicitScopes, _) = originalFile.getScopeContextForPosition(nameExpression) val (implicitScopes, _) = originalFile.getScopeContextForPosition(nameExpression)
fun KtCallableSymbol.hasSuitableExtensionReceiver(): Boolean = fun KtCallableSymbol.hasSuitableExtensionReceiver(): Boolean =
checkExtensionIsSuitable(originalFile, parameters.originalPosition, nameExpression, explicitReceiver) checkExtensionIsSuitable(originalFile, nameExpression, explicitReceiver)
when { when {
nameExpression.parent is KtUserType -> collectTypesCompletion(result, implicitScopes) nameExpression.parent is KtUserType -> collectTypesCompletion(result, implicitScopes)
@@ -122,13 +122,11 @@ abstract class KtAnalysisSession(override val token: ValidityToken) : ValidityTo
fun KtCallableSymbol.checkExtensionIsSuitable( fun KtCallableSymbol.checkExtensionIsSuitable(
originalPsiFile: KtFile, originalPsiFile: KtFile,
originalPosition: PsiElement?,
psiFakeCompletionExpression: KtSimpleNameExpression, psiFakeCompletionExpression: KtSimpleNameExpression,
psiReceiverExpression: KtExpression?, psiReceiverExpression: KtExpression?,
): Boolean = completionCandidateChecker.checkExtensionFitsCandidate( ): Boolean = completionCandidateChecker.checkExtensionFitsCandidate(
this, this,
originalPsiFile, originalPsiFile,
originalPosition,
psiFakeCompletionExpression, psiFakeCompletionExpression,
psiReceiverExpression psiReceiverExpression
) )
@@ -15,7 +15,6 @@ abstract class KtCompletionCandidateChecker : KtAnalysisSessionComponent() {
abstract fun checkExtensionFitsCandidate( abstract fun checkExtensionFitsCandidate(
firSymbolForCandidate: KtCallableSymbol, firSymbolForCandidate: KtCallableSymbol,
originalFile: KtFile, originalFile: KtFile,
originalPosition: PsiElement?,
nameExpression: KtSimpleNameExpression, nameExpression: KtSimpleNameExpression,
possibleExplicitReceiver: KtExpression?, possibleExplicitReceiver: KtExpression?,
): Boolean ): Boolean
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.components package org.jetbrains.kotlin.idea.frontend.api.fir.components
import com.intellij.psi.PsiElement
import com.jetbrains.rd.util.getOrCreate import com.jetbrains.rd.util.getOrCreate
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -40,15 +39,14 @@ internal class KtFirCompletionCandidateChecker(
override fun checkExtensionFitsCandidate( override fun checkExtensionFitsCandidate(
firSymbolForCandidate: KtCallableSymbol, firSymbolForCandidate: KtCallableSymbol,
originalFile: KtFile, originalFile: KtFile,
originalPosition: PsiElement?,
nameExpression: KtSimpleNameExpression, nameExpression: KtSimpleNameExpression,
possibleExplicitReceiver: KtExpression?, possibleExplicitReceiver: KtExpression?,
): Boolean = withValidityAssertion { ): Boolean = withValidityAssertion {
val functionFits = firSymbolForCandidate.withResolvedFirOfType<KtFirFunctionSymbol, FirSimpleFunction, Boolean> { firFunction -> val functionFits = firSymbolForCandidate.withResolvedFirOfType<KtFirFunctionSymbol, FirSimpleFunction, Boolean> { firFunction ->
checkExtension(firFunction, originalFile, originalPosition, nameExpression, possibleExplicitReceiver) checkExtension(firFunction, originalFile, nameExpression, possibleExplicitReceiver)
} }
val propertyFits = firSymbolForCandidate.withResolvedFirOfType<KtFirPropertySymbol, FirProperty, Boolean> { firProperty -> val propertyFits = firSymbolForCandidate.withResolvedFirOfType<KtFirPropertySymbol, FirProperty, Boolean> { firProperty ->
checkExtension(firProperty, originalFile, originalPosition, nameExpression, possibleExplicitReceiver) checkExtension(firProperty, originalFile, nameExpression, possibleExplicitReceiver)
} }
functionFits ?: propertyFits ?: false functionFits ?: propertyFits ?: false
@@ -61,14 +59,13 @@ internal class KtFirCompletionCandidateChecker(
private fun checkExtension( private fun checkExtension(
candidateSymbol: FirCallableDeclaration<*>, candidateSymbol: FirCallableDeclaration<*>,
originalFile: KtFile, originalFile: KtFile,
originalPosition: PsiElement?,
nameExpression: KtSimpleNameExpression, nameExpression: KtSimpleNameExpression,
possibleExplicitReceiver: KtExpression?, possibleExplicitReceiver: KtExpression?,
): Boolean { ): Boolean {
val file = originalFile.getOrBuildFirOfType<FirFile>(firResolveState) val file = originalFile.getOrBuildFirOfType<FirFile>(firResolveState)
val explicitReceiverExpression = possibleExplicitReceiver?.getOrBuildFirOfType<FirExpression>(firResolveState) val explicitReceiverExpression = possibleExplicitReceiver?.getOrBuildFirOfType<FirExpression>(firResolveState)
val resolver = SingleCandidateResolver(firResolveState.firIdeSourcesSession, file) val resolver = SingleCandidateResolver(firResolveState.firIdeSourcesSession, file)
val implicitReceivers = getImplicitReceivers(file, nameExpression, originalPosition) val implicitReceivers = getImplicitReceivers(originalFile, file, nameExpression)
for (implicitReceiverValue in implicitReceivers) { for (implicitReceiverValue in implicitReceivers) {
val resolutionParameters = ResolutionParameters( val resolutionParameters = ResolutionParameters(
singleCandidateResolutionMode = SingleCandidateResolutionMode.CHECK_EXTENSION_FOR_COMPLETION, singleCandidateResolutionMode = SingleCandidateResolutionMode.CHECK_EXTENSION_FOR_COMPLETION,
@@ -85,17 +82,17 @@ internal class KtFirCompletionCandidateChecker(
} }
private fun getImplicitReceivers( private fun getImplicitReceivers(
file: FirFile, originalFile: KtFile,
fakeNameExpression: KtSimpleNameExpression, firFile: FirFile,
originalPosition: PsiElement? fakeNameExpression: KtSimpleNameExpression
): Sequence<ImplicitReceiverValue<*>?> { ): Sequence<ImplicitReceiverValue<*>?> {
val fakeEnclosingFunction = fakeNameExpression.getNonStrictParentOfType<KtNamedFunction>() val fakeEnclosingFunction = fakeNameExpression.getNonStrictParentOfType<KtNamedFunction>()
?: error("Cannot find enclosing function for ${fakeNameExpression.getElementTextInContext()}") ?: error("Cannot find enclosing function for ${fakeNameExpression.getElementTextInContext()}")
val originalEnclosingFunction = originalPosition?.getNonStrictParentOfType<KtNamedFunction>() val originalEnclosingFunction = originalFile.findFunctionDeclarationAt(fakeEnclosingFunction.textOffset)
?: error("Cannot find enclosing function for completion in provided position (or position is absent)") ?: error("Cannot find enclosing function for completion in provided position (or position is absent)")
val completionContext = completionContextCache.getOrCreate(file to fakeEnclosingFunction) { val completionContext = completionContextCache.getOrCreate(firFile to fakeEnclosingFunction) {
LowLevelFirApiFacade.buildCompletionContextForFunction( LowLevelFirApiFacade.buildCompletionContextForFunction(
file, firFile,
fakeEnclosingFunction, fakeEnclosingFunction,
originalEnclosingFunction, originalEnclosingFunction,
state = firResolveState state = firResolveState
@@ -109,4 +106,9 @@ internal class KtFirCompletionCandidateChecker(
yieldAll(towerDataContext.implicitReceiverStack) yieldAll(towerDataContext.implicitReceiverStack)
} }
} }
private fun KtFile.findFunctionDeclarationAt(offset: Int): KtNamedFunction? =
findElementAt(offset)
?.getNonStrictParentOfType<KtNamedFunction>()
?.takeIf { it.textOffset == offset }
} }