KT-32368 Rework Inline hints settings // split KotlinInlayParameterHintsProvider

Platform supports 2 interfaces for inlay hints providers:
- InlayParameterHintsProvider [1]
- InlayHintsProvider [2]

KotlinInlayParameterHintsProvider as an implementation of (1) and a
source of "Inlay Hints" menu has the following limitations:
- Platform treats component as a source of "Parameter hints" submenu
that cannot be split. Once can only add or remove its nested checkboxes.
- Only a single instance of (1) can be defined.

To have a separate menu items for "Inlay Hints" existing
KotlinInlayParameterHintsProvider was split. New providers
implementing (2) were extracted from it:
- KotlinReferencesTypeHintsProvider
- KotlinSuspendingCallHintsProvider
- KotlinLambdasHintsProvider

TODO: HintType move as a separate commit
This commit is contained in:
Andrei Klunnyi
2020-05-05 14:24:16 +02:00
parent 5ec93fd74c
commit 533507de25
21 changed files with 383 additions and 103 deletions
@@ -25,7 +25,7 @@ import com.intellij.psi.impl.PsiDocumentManagerBase
import com.intellij.testFramework.ExtensionTestUtil
import com.intellij.testFramework.runInEdtAndWait
import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.idea.parameterInfo.HintType
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.perf.util.logMessage
import org.jetbrains.kotlin.idea.test.runPostStartupActivitiesOnce
import java.nio.file.Paths
@@ -21,7 +21,7 @@ import com.intellij.psi.impl.PsiDocumentManagerBase
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.runInEdtAndWait
import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.idea.parameterInfo.HintType
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.test.runPostStartupActivitiesOnce
fun commitAllDocuments() {
@@ -401,21 +401,29 @@ livetemplate.description.exval=Extension read-only property
livetemplate.description.exvar=Extension read-write property
hints.progress.calculating.parameter.info=Calculating parameter info
hints.title.property.type.enabled=Show property type hints
hints.settings.common.items=Show hints for:
hints.settings.parameters=Parameter names
hints.settings.types=Types
hints.settings.types.property=Property types
hints.settings.types.variable=Local variable types
hints.settings.types.return=Function return types
hints.settings.types.parameter=Function parameter types
hints.settings.lambdas=Lambdas
hints.settings.lambda.return=Return expressions
hints.settings.lambda.receivers.parameters=Implicit receivers and parameters
hints.settings.suspending=Suspending calls
hints.title.property.type.disabled=Do not show property type hints
hints.title.locals.type.enabled=Show local variable type hints
hints.title.locals.type.disabled=Do not show local variable type hints
hints.title.function.type.enabled=Show function return type hints
hints.title.function.type.disabled=Do not show function return type hints
hints.title.parameter.type.enabled=Show parameter type hints
hints.title.parameter.type.disabled=Do not show parameter type hints
hints.title.argument.name.enabled=Show argument name hints
hints.title.argument.name.enabled=Argument name
hints.title.argument.name.disabled=Do not show argument name hints
hints.title.return.expression.enabled=Show lambda return expression hints
hints.title.return.expression.disabled=Do not show lambda return expression hints
hints.title.implicit.parameters.enabled=Show hints for implicit receivers and parameters of lambdas
hints.title.implicit.parameters.disabled=Do not show hints for implicit receivers and parameters of lambdas
hints.title.suspend.calls.enabled=Show hints for suspending calls
hints.title.suspend.calls.disabled=Do not show hints for suspending calls
presentation.text.paren=({0})
-4
View File
@@ -775,10 +775,6 @@
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.parameterInfo.custom.DisableReturnLambdaHintOptionAction</className>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.AddUnderscoresToNumericLiteralIntention</className>
<category>Kotlin</category>
+5 -1
View File
@@ -375,7 +375,11 @@
<codeInsight.parameterInfo language="kotlin" implementationClass="org.jetbrains.kotlin.idea.parameterInfo.KotlinArrayAccessParameterInfoHandler"/>
<codeInsight.parameterInfo language="kotlin" implementationClass="org.jetbrains.kotlin.idea.parameterInfo.KotlinClassTypeArgumentInfoHandler"/>
<codeInsight.parameterInfo language="kotlin" implementationClass="org.jetbrains.kotlin.idea.parameterInfo.KotlinFunctionTypeArgumentInfoHandler"/>
<codeInsight.parameterNameHints language="kotlin" implementationClass="org.jetbrains.kotlin.idea.parameterInfo.KotlinInlayParameterHintsProvider"/>
<codeInsight.parameterNameHints language="kotlin" implementationClass="org.jetbrains.kotlin.idea.codeInsight.hints.KotlinInlayParameterHintsProvider"/>
<codeInsight.inlayProvider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.codeInsight.hints.KotlinReferencesTypeHintsProvider"/>
<codeInsight.inlayProvider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.codeInsight.hints.KotlinLambdasHintsProvider"/>
<codeInsight.inlayProvider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.codeInsight.hints.KotlinSuspendingCallHintsProvider"/>
<codeInsight.gotoSuper language="kotlin" implementationClass="org.jetbrains.kotlin.idea.codeInsight.GotoSuperActionHandler"/>
@@ -1,34 +1,26 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 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.parameterInfo
package org.jetbrains.kotlin.idea.codeInsight.hints
import com.intellij.codeInsight.hints.HintInfo
import com.intellij.codeInsight.hints.InlayInfo
import com.intellij.codeInsight.hints.InlayParameterHintsProvider
import com.intellij.codeInsight.hints.Option
import com.intellij.lang.Language
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.application.ApplicationManager
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.parameterInfo.*
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getReturnTypeReference
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
enum class HintType(val showDesc: String, val doNotShowDesc: String, defaultEnabled: Boolean) {
@Suppress("UnstableApiUsage")
enum class HintType(private val showDesc: String, val doNotShowDesc: String, defaultEnabled: Boolean) {
PROPERTY_HINT(
KotlinBundle.message("hints.title.property.type.enabled"),
KotlinBundle.message("hints.settings.types.property"),
KotlinBundle.message("hints.title.property.type.disabled"),
false
) {
@@ -40,7 +32,7 @@ enum class HintType(val showDesc: String, val doNotShowDesc: String, defaultEnab
},
LOCAL_VARIABLE_HINT(
KotlinBundle.message("hints.title.locals.type.enabled"),
KotlinBundle.message("hints.settings.types.variable"),
KotlinBundle.message("hints.title.locals.type.disabled"),
false
) {
@@ -55,7 +47,7 @@ enum class HintType(val showDesc: String, val doNotShowDesc: String, defaultEnab
},
FUNCTION_HINT(
KotlinBundle.message("hints.title.function.type.enabled"),
KotlinBundle.message("hints.settings.types.return"),
KotlinBundle.message("hints.title.function.type.disabled"),
false
) {
@@ -73,7 +65,7 @@ enum class HintType(val showDesc: String, val doNotShowDesc: String, defaultEnab
},
PARAMETER_TYPE_HINT(
KotlinBundle.message("hints.title.parameter.type.enabled"),
KotlinBundle.message("hints.settings.types.parameter"),
KotlinBundle.message("hints.title.parameter.type.disabled"),
false
) {
@@ -103,7 +95,7 @@ enum class HintType(val showDesc: String, val doNotShowDesc: String, defaultEnab
},
LAMBDA_RETURN_EXPRESSION(
KotlinBundle.message("hints.title.return.expression.enabled"),
KotlinBundle.message("hints.settings.lambda.return"),
KotlinBundle.message("hints.title.return.expression.disabled"),
true
) {
@@ -111,18 +103,13 @@ enum class HintType(val showDesc: String, val doNotShowDesc: String, defaultEnab
elem is KtExpression && elem !is KtFunctionLiteral && !elem.isNameReferenceInCall()
override fun provideHints(elem: PsiElement): List<InlayInfo> {
// Will be painted with ReturnHintLinePainter
// Enable/Disable setting will be present in the list with other hints.
// Enable action will be provided by the platform.
// Disable action need to be reimplemented as hints are not actually added, see DisableReturnLambdaHintOptionAction.
return emptyList()
if (elem !is KtExpression) return emptyList()
return provideLambdaReturnValueHints(elem)
}
},
LAMBDA_IMPLICIT_PARAMETER_RECEIVER(
KotlinBundle.message("hints.title.implicit.parameters.enabled"),
KotlinBundle.message("hints.settings.lambda.receivers.parameters"),
KotlinBundle.message("hints.title.implicit.parameters.disabled"),
true
) {
@@ -137,7 +124,7 @@ enum class HintType(val showDesc: String, val doNotShowDesc: String, defaultEnab
},
SUSPENDING_CALL(
KotlinBundle.message("hints.title.suspend.calls.enabled"),
KotlinBundle.message("hints.settings.suspending"),
KotlinBundle.message("hints.title.suspend.calls.disabled"),
false
) {
@@ -171,59 +158,4 @@ enum class HintType(val showDesc: String, val doNotShowDesc: String, defaultEnab
val option = Option("SHOW_${this.name}", this.showDesc, defaultEnabled)
val enabled
get() = option.get()
}
@Suppress("UnstableApiUsage")
class KotlinInlayParameterHintsProvider : InlayParameterHintsProvider {
override fun getSupportedOptions(): List<Option> = HintType.values().map { it.option }
override fun getDefaultBlackList(): Set<String> =
setOf(
"*listOf", "*setOf", "*arrayOf", "*ListOf", "*SetOf", "*ArrayOf", "*assert*(*)", "*mapOf", "*MapOf",
"kotlin.require*(*)", "kotlin.check*(*)", "*contains*(value)", "*containsKey(key)", "kotlin.lazyOf(value)",
"*SequenceBuilder.resume(value)", "*SequenceBuilder.yield(value)"
)
override fun getHintInfo(element: PsiElement): HintInfo? {
return when (val hintType = HintType.resolve(element) ?: return null) {
HintType.PARAMETER_HINT -> {
val parent = (element as? KtValueArgumentList)?.parent
(parent as? KtCallElement)?.let { getMethodInfo(it) }
}
else -> HintInfo.OptionInfo(hintType.option)
}
}
override fun getParameterHints(element: PsiElement): List<InlayInfo> {
val resolveToEnabled = HintType.resolveToEnabled(element) ?: return emptyList()
return resolveToEnabled.provideHints(element)
}
override fun getBlackListDependencyLanguage(): Language = JavaLanguage.INSTANCE
override fun getInlayPresentation(inlayText: String): String =
if (inlayText.startsWith(TYPE_INFO_PREFIX)) {
inlayText.substring(TYPE_INFO_PREFIX.length)
} else {
super.getInlayPresentation(inlayText)
}
private fun getMethodInfo(elem: KtCallElement): HintInfo.MethodInfo? {
val resolvedCall = elem.resolveToCall()
val resolvedCallee = resolvedCall?.candidateDescriptor
if (resolvedCallee is FunctionDescriptor) {
val paramNames =
resolvedCallee.valueParameters.asSequence().map { it.name }.filter { !it.isSpecial }.map(Name::asString).toList()
val fqName = if (resolvedCallee is ConstructorDescriptor)
resolvedCallee.containingDeclaration.fqNameSafe.asString()
else
(resolvedCallee.fqNameOrNull()?.asString() ?: return null)
return HintInfo.MethodInfo(fqName, paramNames)
}
return null
}
}
fun PsiElement.isNameReferenceInCall() =
this is KtNameReferenceExpression && parent is KtCallExpression
}
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2020 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.codeInsight.hints
import com.intellij.codeInsight.hints.*
import com.intellij.codeInsight.hints.presentation.InlayPresentation
import com.intellij.codeInsight.hints.presentation.InsetPresentation
import com.intellij.codeInsight.hints.presentation.MenuOnClickPresentation
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.parameterInfo.TYPE_INFO_PREFIX
@Suppress("UnstableApiUsage")
abstract class KotlinAbstractHintsProvider<T : Any> : InlayHintsProvider<T> {
override val key: SettingsKey<T> = SettingsKey(this::class.simpleName!!)
override val previewText: String? = ""
abstract fun isElementSupported(resolved: HintType?, settings: T): Boolean
override fun getCollectorFor(file: PsiFile, editor: Editor, settings: T, sink: InlayHintsSink): InlayHintsCollector? {
return object : FactoryInlayHintsCollector(editor) {
override fun collect(element: PsiElement, editor: Editor, sink: InlayHintsSink): Boolean {
val resolved = HintType.resolve(element) ?: return true
if (!isElementSupported(resolved, settings)) return true
resolved.provideHints(element)
.mapNotNull { info -> convert(info, editor.project) }
.forEach { triple -> sink.addInlineElement(triple.first, triple.second, triple.third) }
return true
}
fun convert(inlayInfo: InlayInfo, project: Project?): Triple<Int, Boolean, InlayPresentation>? {
val inlayText = getInlayPresentation(inlayInfo.text)
val presentation = factory.roundWithBackground(factory.smallText(inlayText))
val finalPresentation = if (project == null) presentation else
InsetPresentation(
MenuOnClickPresentation(presentation, project) {
val provider = this@KotlinAbstractHintsProvider
listOf(
InlayProviderDisablingAction(provider.name, file.language, project, provider.key),
ShowInlayHintsSettings()
)
}, left = 1
)
return Triple(inlayInfo.offset, inlayInfo.relatesToPrecedingText, finalPresentation)
}
fun getInlayPresentation(inlayText: String): String =
if (inlayText.startsWith(TYPE_INFO_PREFIX)) {
inlayText.substring(TYPE_INFO_PREFIX.length)
} else {
"$inlayText:"
}
}
}
}
@@ -0,0 +1,75 @@
/*
* Copyright 2010-2020 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.codeInsight.hints
import com.intellij.codeInsight.hints.*
import com.intellij.lang.Language
import com.intellij.lang.java.JavaLanguage
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.parameterInfo.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@Suppress("UnstableApiUsage")
class KotlinInlayParameterHintsProvider : InlayParameterHintsProvider {
override fun getSupportedOptions(): List<Option> = listOf(HintType.PARAMETER_HINT.option)
override fun getDefaultBlackList(): Set<String> =
setOf(
"*listOf", "*setOf", "*arrayOf", "*ListOf", "*SetOf", "*ArrayOf", "*assert*(*)", "*mapOf", "*MapOf",
"kotlin.require*(*)", "kotlin.check*(*)", "*contains*(value)", "*containsKey(key)", "kotlin.lazyOf(value)",
"*SequenceBuilder.resume(value)", "*SequenceBuilder.yield(value)"
)
override fun getHintInfo(element: PsiElement): HintInfo? {
if (!(HintType.PARAMETER_HINT.isApplicable(element))) return null
val parent: PsiElement = (element as? KtValueArgumentList)?.parent ?: return null
return getMethodInfo(parent as KtCallElement)
}
override fun getParameterHints(element: PsiElement): List<InlayInfo> {
return if (HintType.PARAMETER_HINT.isApplicable(element))
HintType.PARAMETER_HINT.provideHints(element)
else emptyList()
}
override fun getBlackListDependencyLanguage(): Language = JavaLanguage.INSTANCE
override fun getInlayPresentation(inlayText: String): String =
if (inlayText.startsWith(TYPE_INFO_PREFIX)) {
inlayText.substring(TYPE_INFO_PREFIX.length)
} else {
super.getInlayPresentation(inlayText)
}
private fun getMethodInfo(elem: KtCallElement): HintInfo.MethodInfo? {
val resolvedCall = elem.resolveToCall()
val resolvedCallee = resolvedCall?.candidateDescriptor
if (resolvedCallee is FunctionDescriptor) {
val paramNames =
resolvedCallee.valueParameters.asSequence().map { it.name }.filter { !it.isSpecial }.map(Name::asString).toList()
val fqName = if (resolvedCallee is ConstructorDescriptor)
resolvedCallee.containingDeclaration.fqNameSafe.asString()
else
(resolvedCallee.fqNameOrNull()?.asString() ?: return null)
return HintInfo.MethodInfo(fqName, paramNames)
}
return null
}
override fun getMainCheckboxText(): String {
return KotlinBundle.message("hints.settings.common.items")
}
}
fun PsiElement.isNameReferenceInCall() =
this is KtNameReferenceExpression && parent is KtCallExpression
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2020 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.codeInsight.hints
import com.intellij.codeInsight.hints.ChangeListener
import com.intellij.codeInsight.hints.ImmediateConfigurable
import com.intellij.ui.layout.panel
import org.jetbrains.kotlin.idea.KotlinBundle
import javax.swing.JComponent
@Suppress("UnstableApiUsage")
class KotlinLambdasHintsProvider : KotlinAbstractHintsProvider<KotlinLambdasHintsProvider.Settings>() {
data class Settings(
var returnExpressions: Boolean = true,
var implicitReceiversAndParams: Boolean = true,
)
override val name: String = KotlinBundle.message("hints.settings.lambdas")
override fun isElementSupported(resolved: HintType?, settings: Settings): Boolean {
return when (resolved) {
HintType.LAMBDA_RETURN_EXPRESSION -> settings.returnExpressions
HintType.LAMBDA_IMPLICIT_PARAMETER_RECEIVER -> settings.implicitReceiversAndParams
else -> false
}
}
override fun createConfigurable(settings: Settings): ImmediateConfigurable {
return object : ImmediateConfigurable {
override fun createComponent(listener: ChangeListener): JComponent = panel {}
override val mainCheckboxText: String = KotlinBundle.message("hints.settings.common.items")
override val cases: List<ImmediateConfigurable.Case>
get() = listOf(
ImmediateConfigurable.Case(
KotlinBundle.message("hints.settings.lambda.return"),
"hints.lambda.return",
settings::returnExpressions
),
ImmediateConfigurable.Case(
KotlinBundle.message("hints.settings.lambda.receivers.parameters"),
"hints.lambda.receivers.parameters",
settings::implicitReceiversAndParams
)
)
}
}
override fun createSettings(): Settings = Settings()
}
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2020 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.codeInsight.hints
import com.intellij.codeInsight.hints.ChangeListener
import com.intellij.codeInsight.hints.ImmediateConfigurable
import com.intellij.ui.layout.panel
import org.jetbrains.kotlin.idea.KotlinBundle
import javax.swing.JComponent
@Suppress("UnstableApiUsage")
class KotlinReferencesTypeHintsProvider : KotlinAbstractHintsProvider<KotlinReferencesTypeHintsProvider.Settings>() {
data class Settings(
var propertyType: Boolean = false,
var localVariableType: Boolean = false,
var functionReturnType: Boolean = false,
var parameterType: Boolean = false
)
override val name: String = KotlinBundle.message("hints.settings.types")
override fun createConfigurable(settings: Settings): ImmediateConfigurable {
return object : ImmediateConfigurable {
override fun createComponent(listener: ChangeListener): JComponent = panel {}
override val mainCheckboxText: String = KotlinBundle.message("hints.settings.common.items")
override val cases: List<ImmediateConfigurable.Case>
get() = listOf(
ImmediateConfigurable.Case(
KotlinBundle.message("hints.settings.types.property"),
"hints.type.property",
settings::propertyType
),
ImmediateConfigurable.Case(
KotlinBundle.message("hints.settings.types.variable"),
"hints.type.variable",
settings::localVariableType
),
ImmediateConfigurable.Case(
KotlinBundle.message("hints.settings.types.return"),
"hints.type.function.return",
settings::functionReturnType
),
ImmediateConfigurable.Case(
KotlinBundle.message("hints.settings.types.parameter"),
"hints.type.function.parameter",
settings::parameterType
),
)
}
}
override fun createSettings(): Settings = Settings()
override fun isElementSupported(resolved: HintType?, settings: Settings): Boolean {
return when (resolved) {
HintType.PROPERTY_HINT -> settings.propertyType
HintType.LOCAL_VARIABLE_HINT -> settings.localVariableType
HintType.FUNCTION_HINT -> settings.functionReturnType
HintType.PARAMETER_TYPE_HINT -> settings.parameterType
else -> false
}
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2020 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.codeInsight.hints
import com.intellij.codeInsight.hints.ChangeListener
import com.intellij.codeInsight.hints.ImmediateConfigurable
import com.intellij.ui.layout.panel
import org.jetbrains.kotlin.idea.KotlinBundle
import javax.swing.JComponent
@Suppress("UnstableApiUsage")
class KotlinSuspendingCallHintsProvider : KotlinAbstractHintsProvider<KotlinSuspendingCallHintsProvider.Settings>() {
data class Settings(var suspendingCalls: Boolean = false)
override val name: String = KotlinBundle.message("hints.settings.suspending")
override fun createConfigurable(settings: Settings): ImmediateConfigurable {
return object : ImmediateConfigurable {
override fun createComponent(listener: ChangeListener): JComponent = panel {}
override val mainCheckboxText: String = KotlinBundle.message("hints.settings.common.items")
override val cases: List<ImmediateConfigurable.Case>
get() = listOf(
ImmediateConfigurable.Case(
KotlinBundle.message("hints.settings.suspending"),
"hints.suspending.calls",
settings::suspendingCalls
)
)
}
}
override fun createSettings(): Settings = Settings()
override fun isElementSupported(resolved: HintType?, settings: Settings): Boolean {
return when (resolved) {
HintType.SUSPENDING_CALL -> settings.suspendingCalls
else -> false
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2020 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.codeInsight.hints
import com.intellij.codeInsight.hints.settings.InlayHintsConfigurable
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
class ShowInlayHintsSettings : AnAction("Hints Settings...") {
override fun actionPerformed(e: AnActionEvent) {
val file = CommonDataKeys.PSI_FILE.getData(e.dataContext) ?: return
val fileLanguage = file.language
InlayHintsConfigurable.showSettingsDialogForLanguage(
file.project,
fileLanguage
)
}
}
@@ -10,12 +10,13 @@ import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.util.isOneLiner
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsResultOfLambda
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@Suppress("UnstableApiUsage")
fun provideLambdaReturnValueHints(expression: KtExpression): List<InlayInfo> {
if (expression is KtWhenExpression || expression is KtBlockExpression) {
return emptyList()
@@ -46,7 +47,9 @@ fun provideLambdaReturnValueHints(expression: KtExpression): List<InlayInfo> {
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL_WITH_CFA)
if (expression.isUsedAsResultOfLambda(bindingContext)) {
val lambdaName = getNameOfFunctionThatTakesLambda(expression) ?: "lambda"
return listOf(InlayInfo("$TYPE_INFO_PREFIX^$lambdaName", expression.startOffset))
return listOf(
InlayInfo("$TYPE_INFO_PREFIX^$lambdaName", expression.endOffset)
)
}
return emptyList()
}
@@ -13,7 +13,7 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.parameterInfo.HintType
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.util.refreshAllOpenEditors
class DisableReturnLambdaHintOptionAction : IntentionAction, LowPriorityAction {
@@ -16,7 +16,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.SyntaxTraverser
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.parameterInfo.HintType
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.parameterInfo.TYPE_INFO_PREFIX
import org.jetbrains.kotlin.idea.parameterInfo.provideLambdaReturnValueHints
import org.jetbrains.kotlin.psi.KtExpression
@@ -19,7 +19,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.SyntaxTraverser
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.parameterInfo.HintType
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.parameterInfo.TYPE_INFO_PREFIX
import org.jetbrains.kotlin.idea.parameterInfo.provideLambdaReturnValueHints
import org.jetbrains.kotlin.psi.KtExpression
@@ -12,6 +12,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.junit.Assert
internal fun JavaCodeInsightTestFixture.checkHintType(text: String, hintType: HintType) {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.parameterInfo
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.parameterInfo
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
@@ -10,6 +10,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.LineExtensionInfo
import com.intellij.openapi.editor.impl.EditorImpl
import com.intellij.testFramework.utils.inlays.InlayHintsChecker
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.parameterInfo
import org.jetbrains.kotlin.idea.codeInsight.hints.HintType
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor