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:
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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})
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
|
||||
+15
-83
@@ -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:"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -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()
|
||||
}
|
||||
+69
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
@@ -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()
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user