FIR IDE: implement completion in where clause
This commit is contained in:
committed by
TeamCityServer
parent
5b5bbdd113
commit
0f13359229
+5
@@ -69,6 +69,7 @@ private object KotlinFirCompletionProvider : CompletionProvider<CompletionParame
|
||||
val annotationsContributor = FirAnnotationCompletionContributor(basicContext)
|
||||
val packageCompletionContributor = FirPackageCompletionContributor(basicContext)
|
||||
val importDirectivePackageMembersCompletionContributor = FirImportDirectivePackageMembersCompletionContributor(basicContext)
|
||||
val typeParameterConstraintNameInWhereClauseContributor = FirTypeParameterConstraintNameInWhereClauseCompletionContributor(basicContext)
|
||||
|
||||
when (positionContext) {
|
||||
is FirExpressionNameReferencePositionContext -> {
|
||||
@@ -103,6 +104,10 @@ private object KotlinFirCompletionProvider : CompletionProvider<CompletionParame
|
||||
complete(packageCompletionContributor, positionContext)
|
||||
}
|
||||
|
||||
is FirTypeConstraintNameInWhereClausePositionContext -> {
|
||||
complete(typeParameterConstraintNameInWhereClauseContributor, positionContext)
|
||||
}
|
||||
|
||||
is FirUnknownPositionContext -> {
|
||||
complete(keywordContributor, positionContext)
|
||||
}
|
||||
|
||||
+13
-2
@@ -19,6 +19,11 @@ internal sealed class FirRawPositionCompletionContext {
|
||||
abstract val position: PsiElement
|
||||
}
|
||||
|
||||
internal class FirTypeConstraintNameInWhereClausePositionContext(
|
||||
override val position: PsiElement,
|
||||
val typeParametersOwner: KtTypeParameterListOwner
|
||||
) : FirRawPositionCompletionContext()
|
||||
|
||||
internal sealed class FirNameReferencePositionContext : FirRawPositionCompletionContext() {
|
||||
abstract val reference: KtSimpleNameReference
|
||||
abstract val nameExpression: KtSimpleNameExpression
|
||||
@@ -40,7 +45,6 @@ internal class FirPackageDirectivePositionContext(
|
||||
) : FirNameReferencePositionContext()
|
||||
|
||||
|
||||
|
||||
internal class FirTypeNameReferencePositionContext(
|
||||
override val position: PsiElement,
|
||||
override val reference: KtSimpleNameReference,
|
||||
@@ -108,6 +112,10 @@ internal object FirPositionCompletionContextDetector {
|
||||
explicitReceiver,
|
||||
)
|
||||
}
|
||||
parent is KtTypeConstraint -> FirTypeConstraintNameInWhereClausePositionContext(
|
||||
position,
|
||||
position.parentOfType()!!,
|
||||
)
|
||||
else -> {
|
||||
FirExpressionNameReferencePositionContext(position, reference, nameExpression, explicitReceiver)
|
||||
}
|
||||
@@ -169,7 +177,10 @@ internal object FirPositionCompletionContextDetector {
|
||||
positionContext.nameExpression,
|
||||
action
|
||||
)
|
||||
is FirUnknownPositionContext, is FirImportDirectivePositionContext, is FirPackageDirectivePositionContext -> {
|
||||
is FirUnknownPositionContext,
|
||||
is FirImportDirectivePositionContext,
|
||||
is FirPackageDirectivePositionContext,
|
||||
is FirTypeConstraintNameInWhereClausePositionContext -> {
|
||||
analyse(basicContext.originalKtFile, action)
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -9,9 +9,11 @@ import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.completion.*
|
||||
import org.jetbrains.kotlin.idea.completion.context.*
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirNameReferencePositionContext
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirRawPositionCompletionContext
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirTypeConstraintNameInWhereClausePositionContext
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirUnknownPositionContext
|
||||
import org.jetbrains.kotlin.idea.completion.contributors.keywords.OverrideKeywordHandler
|
||||
import org.jetbrains.kotlin.idea.completion.contributors.keywords.ReturnKeywordHandler
|
||||
@@ -44,6 +46,9 @@ internal class FirKeywordCompletionContributor(basicContext: FirBasicCompletionC
|
||||
else -> reference.expression
|
||||
}
|
||||
}
|
||||
is FirTypeConstraintNameInWhereClausePositionContext -> {
|
||||
error("keyword completion should not be called for FirTypeConstraintNameInWhereClausePositionContext")
|
||||
}
|
||||
is FirUnknownPositionContext -> null
|
||||
}
|
||||
completeWithResolve(expression ?: positionContext.position, expression)
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion.contributors
|
||||
|
||||
import com.intellij.codeInsight.completion.InsertHandler
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import org.jetbrains.kotlin.idea.completion.KotlinFirIconProvider.getIconFor
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirTypeConstraintNameInWhereClausePositionContext
|
||||
import org.jetbrains.kotlin.idea.completion.contributors.helpers.addSymbolAndInvokeCompletion
|
||||
import org.jetbrains.kotlin.idea.completion.lookups.KotlinLookupObject
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithTypeParameters
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
|
||||
internal class FirTypeParameterConstraintNameInWhereClauseCompletionContributor(
|
||||
basicContext: FirBasicCompletionContext
|
||||
) : FirCompletionContributorBase<FirTypeConstraintNameInWhereClausePositionContext>(basicContext) {
|
||||
|
||||
override fun KtAnalysisSession.complete(positionContext: FirTypeConstraintNameInWhereClausePositionContext) {
|
||||
val ownerSymbol = positionContext.typeParametersOwner.getSymbol() as? KtSymbolWithTypeParameters ?: return
|
||||
ownerSymbol.typeParameters.forEach { typeParameter ->
|
||||
val name = typeParameter.name
|
||||
val icon = getIconFor(typeParameter)
|
||||
LookupElementBuilder.create(TypeParameterInWhenClauseILookupObject(name), name.asString())
|
||||
.withTailText(" : ")
|
||||
.withInsertHandler(TypeParameterInWhenClauseInsertionHandler)
|
||||
.withPsiElement(typeParameter.psi)
|
||||
.withIcon(icon)
|
||||
.let(result::addElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TypeParameterInWhenClauseILookupObject(override val shortName: Name) : KotlinLookupObject
|
||||
|
||||
|
||||
private object TypeParameterInWhenClauseInsertionHandler : InsertHandler<LookupElement> {
|
||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||
val lookupElement = item.`object` as TypeParameterInWhenClauseILookupObject
|
||||
val name = lookupElement.shortName.render()
|
||||
context.document.replaceString(context.startOffset, context.tailOffset, name)
|
||||
context.commitDocument()
|
||||
context.addSymbolAndInvokeCompletion(symbol = " : ")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ internal object SuperCallInsertionHandler : InsertHandler<LookupElement> {
|
||||
val lookupObject = item.`object` as SuperCallLookupObject
|
||||
|
||||
replaceWithClassIdAndShorten(lookupObject, context)
|
||||
context.addDotAndInvokeCompletion()
|
||||
context.addSymbolAndInvokeCompletion(symbol = ".")
|
||||
}
|
||||
|
||||
private fun replaceWithClassIdAndShorten(
|
||||
|
||||
+4
-4
@@ -10,8 +10,8 @@ import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
|
||||
internal fun InsertionContext.addDotAndInvokeCompletion() {
|
||||
addDotToCompletion(this)
|
||||
internal fun InsertionContext.addSymbolAndInvokeCompletion(symbol: String) {
|
||||
addSymbolToCompletion(this, symbol)
|
||||
invokeCompletion(this)
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ private fun invokeCompletion(context: InsertionContext) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun addDotToCompletion(context: InsertionContext) {
|
||||
context.document.insertString(context.tailOffset, ".")
|
||||
private fun addSymbolToCompletion(context: InsertionContext, symbol: String) {
|
||||
context.document.insertString(context.tailOffset, symbol)
|
||||
context.commitDocument()
|
||||
context.editor.caretModel.moveToOffset(context.tailOffset)
|
||||
}
|
||||
+2
-2
@@ -10,7 +10,7 @@ import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.icons.AllIcons
|
||||
import org.jetbrains.kotlin.idea.completion.contributors.helpers.addDotAndInvokeCompletion
|
||||
import org.jetbrains.kotlin.idea.completion.contributors.helpers.addSymbolAndInvokeCompletion
|
||||
import org.jetbrains.kotlin.idea.completion.lookups.KotlinLookupObject
|
||||
import org.jetbrains.kotlin.miniStdLib.letIf
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -41,7 +41,7 @@ private object PackagePartInsertionHandler : InsertHandler<LookupElement> {
|
||||
val name = lookupElement.shortName.render()
|
||||
context.document.replaceString(context.startOffset, context.tailOffset, name)
|
||||
context.commitDocument()
|
||||
context.addDotAndInvokeCompletion()
|
||||
context.addSymbolAndInvokeCompletion(symbol = ".")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user