diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInsight/hints/KotlinAbstractHintsProvider.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInsight/hints/KotlinAbstractHintsProvider.kt index bc8b40951264..f20e853b3055 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInsight/hints/KotlinAbstractHintsProvider.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInsight/hints/KotlinAbstractHintsProvider.kt @@ -11,6 +11,7 @@ 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.KotlinLanguage @Suppress("UnstableApiUsage") abstract class KotlinAbstractHintsProvider : InlayHintsProvider { @@ -29,83 +30,89 @@ abstract class KotlinAbstractHintsProvider : InlayHintsProvider { val f = factory resolved.provideHintDetails(element) - .map { convert(it, f, editor.project ?: element.project) } + .map { + PresentationAndSettings( + getInlayPresentationForInlayInfoDetails(it, f, editor.project ?: element.project, this@KotlinAbstractHintsProvider), + it.inlayInfo.offset, + it.inlayInfo.relatesToPrecedingText + ) + } .forEach { p -> sink.addInlineElement(p.offset, p.relatesToPrecedingText, p.presentation, hintsArePlacedAtTheEndOfLine) } return true } + } + } - private fun convert( - infoDetails: InlayInfoDetails, - f: PresentationFactory, project: Project - ): PresentationAndSettings { - val inlayInfo = infoDetails.inlayInfo - val details = mergeAdjacentTextInlayInfoDetails(infoDetails.details) - val basePresentation = when (details.size) { - 1 -> convert(details.first(), f, project) - else -> f.seq(*(details.map { convert(it, f, project) }.toTypedArray())) - } - val roundedPresentation = f.roundWithBackground(basePresentation) - val finalPresentation = InsetPresentation( - MenuOnClickPresentation(roundedPresentation, project) { - val provider = this@KotlinAbstractHintsProvider - listOf( - InlayProviderDisablingAction(provider.name, file.language, project, provider.key), - ShowInlayHintsSettings() - ) - }, left = 1 - ) - - return PresentationAndSettings(finalPresentation, inlayInfo.offset, inlayInfo.relatesToPrecedingText) + companion object { + private fun getInlayPresentationForInlayInfoDetails( + infoDetails: InlayInfoDetails, + factory: PresentationFactory, + project: Project, + provider: InlayHintsProvider<*> + ): InlayPresentation { + val inlayInfo = infoDetails.inlayInfo + val details = mergeAdjacentTextInlayInfoDetails(infoDetails.details) + val basePresentation = when (details.size) { + 1 -> getInlayPresentationForInlayInfoDetail(details.first(), factory, project) + else -> factory.seq(*(details.map { getInlayPresentationForInlayInfoDetail(it, factory, project) }.toTypedArray())) } + val roundedPresentation = factory.roundWithBackground(basePresentation) + return InsetPresentation( + MenuOnClickPresentation(roundedPresentation, project) { + listOf( + InlayProviderDisablingAction(provider.name, KotlinLanguage.INSTANCE, project, provider.key), + ShowInlayHintsSettings() + ) + }, left = 1 + ) + } - private fun mergeAdjacentTextInlayInfoDetails(details: List): List { - val result = mutableListOf() - val iterator = details.iterator() - var builder: StringBuilder? = null - while (iterator.hasNext()) { - when (val next = iterator.next()) { - is TextInlayInfoDetail -> { - builder = builder ?: StringBuilder() - builder.append(next.text) - } - else -> { - builder?.let { - result.add(TextInlayInfoDetail(it.toString())) - builder = null - } - result.add(next) + private fun mergeAdjacentTextInlayInfoDetails(details: List): List { + val result = mutableListOf() + val iterator = details.iterator() + var builder: StringBuilder? = null + while (iterator.hasNext()) { + when (val next = iterator.next()) { + is TextInlayInfoDetail -> { + builder = builder ?: StringBuilder() + builder.append(next.text) + } + else -> { + builder?.let { + result.add(TextInlayInfoDetail(it.toString())) + builder = null } + result.add(next) } } - builder?.let { - result.add(TextInlayInfoDetail(it.toString())) - builder = null - } - return result } - - private fun convert( - details: InlayInfoDetail, - f: PresentationFactory, - project: Project - ): InlayPresentation { - val textPresentation = f.smallText(details.text) - val navigationElement = when(details) { - is PsiInlayInfoDetail -> details.element - is TypeInlayInfoDetail -> details.fqName?.run { - project.resolveClass(this)?.navigationElement - } - else -> null - } - val basePresentation = navigationElement?.let { - factory.psiSingleReference(textPresentation, withDebugToString = true) { it } - } ?: textPresentation - return basePresentation + builder?.let { + result.add(TextInlayInfoDetail(it.toString())) + builder = null } + return result + } + private fun getInlayPresentationForInlayInfoDetail( + details: InlayInfoDetail, + factory: PresentationFactory, + project: Project + ): InlayPresentation { + val textPresentation = factory.smallText(details.text) + val navigationElement = when(details) { + is PsiInlayInfoDetail -> details.element + is TypeInlayInfoDetail -> details.fqName?.run { + project.resolveClass(this)?.navigationElement + } + else -> null + } + val basePresentation = navigationElement?.let { + factory.psiSingleReference(textPresentation, withDebugToString = true) { it } + } ?: textPresentation + return basePresentation } }