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 annotationsContributor = FirAnnotationCompletionContributor(basicContext)
|
||||||
val packageCompletionContributor = FirPackageCompletionContributor(basicContext)
|
val packageCompletionContributor = FirPackageCompletionContributor(basicContext)
|
||||||
val importDirectivePackageMembersCompletionContributor = FirImportDirectivePackageMembersCompletionContributor(basicContext)
|
val importDirectivePackageMembersCompletionContributor = FirImportDirectivePackageMembersCompletionContributor(basicContext)
|
||||||
|
val typeParameterConstraintNameInWhereClauseContributor = FirTypeParameterConstraintNameInWhereClauseCompletionContributor(basicContext)
|
||||||
|
|
||||||
when (positionContext) {
|
when (positionContext) {
|
||||||
is FirExpressionNameReferencePositionContext -> {
|
is FirExpressionNameReferencePositionContext -> {
|
||||||
@@ -103,6 +104,10 @@ private object KotlinFirCompletionProvider : CompletionProvider<CompletionParame
|
|||||||
complete(packageCompletionContributor, positionContext)
|
complete(packageCompletionContributor, positionContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is FirTypeConstraintNameInWhereClausePositionContext -> {
|
||||||
|
complete(typeParameterConstraintNameInWhereClauseContributor, positionContext)
|
||||||
|
}
|
||||||
|
|
||||||
is FirUnknownPositionContext -> {
|
is FirUnknownPositionContext -> {
|
||||||
complete(keywordContributor, positionContext)
|
complete(keywordContributor, positionContext)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-2
@@ -19,6 +19,11 @@ internal sealed class FirRawPositionCompletionContext {
|
|||||||
abstract val position: PsiElement
|
abstract val position: PsiElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class FirTypeConstraintNameInWhereClausePositionContext(
|
||||||
|
override val position: PsiElement,
|
||||||
|
val typeParametersOwner: KtTypeParameterListOwner
|
||||||
|
) : FirRawPositionCompletionContext()
|
||||||
|
|
||||||
internal sealed class FirNameReferencePositionContext : FirRawPositionCompletionContext() {
|
internal sealed class FirNameReferencePositionContext : FirRawPositionCompletionContext() {
|
||||||
abstract val reference: KtSimpleNameReference
|
abstract val reference: KtSimpleNameReference
|
||||||
abstract val nameExpression: KtSimpleNameExpression
|
abstract val nameExpression: KtSimpleNameExpression
|
||||||
@@ -40,7 +45,6 @@ internal class FirPackageDirectivePositionContext(
|
|||||||
) : FirNameReferencePositionContext()
|
) : FirNameReferencePositionContext()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal class FirTypeNameReferencePositionContext(
|
internal class FirTypeNameReferencePositionContext(
|
||||||
override val position: PsiElement,
|
override val position: PsiElement,
|
||||||
override val reference: KtSimpleNameReference,
|
override val reference: KtSimpleNameReference,
|
||||||
@@ -108,6 +112,10 @@ internal object FirPositionCompletionContextDetector {
|
|||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
parent is KtTypeConstraint -> FirTypeConstraintNameInWhereClausePositionContext(
|
||||||
|
position,
|
||||||
|
position.parentOfType()!!,
|
||||||
|
)
|
||||||
else -> {
|
else -> {
|
||||||
FirExpressionNameReferencePositionContext(position, reference, nameExpression, explicitReceiver)
|
FirExpressionNameReferencePositionContext(position, reference, nameExpression, explicitReceiver)
|
||||||
}
|
}
|
||||||
@@ -169,7 +177,10 @@ internal object FirPositionCompletionContextDetector {
|
|||||||
positionContext.nameExpression,
|
positionContext.nameExpression,
|
||||||
action
|
action
|
||||||
)
|
)
|
||||||
is FirUnknownPositionContext, is FirImportDirectivePositionContext, is FirPackageDirectivePositionContext -> {
|
is FirUnknownPositionContext,
|
||||||
|
is FirImportDirectivePositionContext,
|
||||||
|
is FirPackageDirectivePositionContext,
|
||||||
|
is FirTypeConstraintNameInWhereClausePositionContext -> {
|
||||||
analyse(basicContext.originalKtFile, action)
|
analyse(basicContext.originalKtFile, action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -9,9 +9,11 @@ import com.intellij.codeInsight.lookup.LookupElement
|
|||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.idea.completion.*
|
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.FirBasicCompletionContext
|
||||||
import org.jetbrains.kotlin.idea.completion.context.FirNameReferencePositionContext
|
import org.jetbrains.kotlin.idea.completion.context.FirNameReferencePositionContext
|
||||||
import org.jetbrains.kotlin.idea.completion.context.FirRawPositionCompletionContext
|
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.context.FirUnknownPositionContext
|
||||||
import org.jetbrains.kotlin.idea.completion.contributors.keywords.OverrideKeywordHandler
|
import org.jetbrains.kotlin.idea.completion.contributors.keywords.OverrideKeywordHandler
|
||||||
import org.jetbrains.kotlin.idea.completion.contributors.keywords.ReturnKeywordHandler
|
import org.jetbrains.kotlin.idea.completion.contributors.keywords.ReturnKeywordHandler
|
||||||
@@ -44,6 +46,9 @@ internal class FirKeywordCompletionContributor(basicContext: FirBasicCompletionC
|
|||||||
else -> reference.expression
|
else -> reference.expression
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is FirTypeConstraintNameInWhereClausePositionContext -> {
|
||||||
|
error("keyword completion should not be called for FirTypeConstraintNameInWhereClausePositionContext")
|
||||||
|
}
|
||||||
is FirUnknownPositionContext -> null
|
is FirUnknownPositionContext -> null
|
||||||
}
|
}
|
||||||
completeWithResolve(expression ?: positionContext.position, expression)
|
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
|
val lookupObject = item.`object` as SuperCallLookupObject
|
||||||
|
|
||||||
replaceWithClassIdAndShorten(lookupObject, context)
|
replaceWithClassIdAndShorten(lookupObject, context)
|
||||||
context.addDotAndInvokeCompletion()
|
context.addSymbolAndInvokeCompletion(symbol = ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun replaceWithClassIdAndShorten(
|
private fun replaceWithClassIdAndShorten(
|
||||||
|
|||||||
+4
-4
@@ -10,8 +10,8 @@ import com.intellij.codeInsight.completion.CompletionType
|
|||||||
import com.intellij.codeInsight.completion.InsertionContext
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
|
||||||
internal fun InsertionContext.addDotAndInvokeCompletion() {
|
internal fun InsertionContext.addSymbolAndInvokeCompletion(symbol: String) {
|
||||||
addDotToCompletion(this)
|
addSymbolToCompletion(this, symbol)
|
||||||
invokeCompletion(this)
|
invokeCompletion(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,8 +22,8 @@ private fun invokeCompletion(context: InsertionContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addDotToCompletion(context: InsertionContext) {
|
private fun addSymbolToCompletion(context: InsertionContext, symbol: String) {
|
||||||
context.document.insertString(context.tailOffset, ".")
|
context.document.insertString(context.tailOffset, symbol)
|
||||||
context.commitDocument()
|
context.commitDocument()
|
||||||
context.editor.caretModel.moveToOffset(context.tailOffset)
|
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.LookupElement
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||||
import com.intellij.icons.AllIcons
|
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.idea.completion.lookups.KotlinLookupObject
|
||||||
import org.jetbrains.kotlin.miniStdLib.letIf
|
import org.jetbrains.kotlin.miniStdLib.letIf
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -41,7 +41,7 @@ private object PackagePartInsertionHandler : InsertHandler<LookupElement> {
|
|||||||
val name = lookupElement.shortName.render()
|
val name = lookupElement.shortName.render()
|
||||||
context.document.replaceString(context.startOffset, context.tailOffset, name)
|
context.document.replaceString(context.startOffset, context.tailOffset, name)
|
||||||
context.commitDocument()
|
context.commitDocument()
|
||||||
context.addDotAndInvokeCompletion()
|
context.addSymbolAndInvokeCompletion(symbol = ".")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user