Show more correct type hints
- Don't show hints containing error type as type parameter - Do not expand type aliases - Show base type for types of anonymous objects #KT-18369 Fixed #KT-18341 Fixed #KT-18343 Fixed
This commit is contained in:
@@ -23,18 +23,21 @@ import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
||||||
import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention
|
import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention
|
||||||
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.renderer.RenderingFormat
|
import org.jetbrains.kotlin.renderer.RenderingFormat
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.isError
|
import org.jetbrains.kotlin.types.typeUtil.containsError
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
|
||||||
|
|
||||||
//hack to separate type presentation from param info presentation
|
//hack to separate type presentation from param info presentation
|
||||||
const val TYPE_INFO_PREFIX = "@TYPE@"
|
const val TYPE_INFO_PREFIX = "@TYPE@"
|
||||||
private val typeRenderer = DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.withOptions {
|
private val typeRenderer = DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.withOptions {
|
||||||
textFormat = RenderingFormat.PLAIN
|
textFormat = RenderingFormat.PLAIN
|
||||||
|
renderUnabbreviatedType = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun providePropertyTypeHint(elem: PsiElement): List<InlayInfo> {
|
fun providePropertyTypeHint(elem: PsiElement): List<InlayInfo> {
|
||||||
@@ -47,8 +50,17 @@ fun providePropertyTypeHint(elem: PsiElement): List<InlayInfo> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun provideTypeHint(element: KtCallableDeclaration, offset: Int): List<InlayInfo> {
|
fun provideTypeHint(element: KtCallableDeclaration, offset: Int): List<InlayInfo> {
|
||||||
val type = SpecifyTypeExplicitlyIntention.getTypeForDeclaration(element)
|
var type: KotlinType = SpecifyTypeExplicitlyIntention.getTypeForDeclaration(element).unwrap()
|
||||||
return if (!type.isError && isUnclearType(type, element)) {
|
if (type.containsError()) return emptyList()
|
||||||
|
val name = type.constructor.declarationDescriptor?.name
|
||||||
|
if (name == SpecialNames.NO_NAME_PROVIDED) {
|
||||||
|
type = type.immediateSupertypes().singleOrNull() ?: return emptyList()
|
||||||
|
}
|
||||||
|
else if (name?.isSpecial == true) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (isUnclearType(type, element)) {
|
||||||
val settings = CodeStyleSettingsManager.getInstance(element.project).currentSettings
|
val settings = CodeStyleSettingsManager.getInstance(element.project).currentSettings
|
||||||
.getCustomSettings(KotlinCodeStyleSettings::class.java)
|
.getCustomSettings(KotlinCodeStyleSettings::class.java)
|
||||||
|
|
||||||
|
|||||||
@@ -56,4 +56,24 @@ class InlayTypeHintsTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
HintType.LOCAL_VARIABLE_HINT.option.set(true)
|
HintType.LOCAL_VARIABLE_HINT.option.set(true)
|
||||||
check("""fun foo() { for (x: String in listOf("a")) { } }""")
|
check("""fun foo() { for (x: String in listOf("a")) { } }""")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testErrorType() {
|
||||||
|
HintType.PROPERTY_HINT.option.set(true)
|
||||||
|
check("""val x = arrayListOf<>()""")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testExpandedTypeAlias() {
|
||||||
|
HintType.PROPERTY_HINT.option.set(true)
|
||||||
|
check("""val x<hint text=": ArrayList<Int>" /> = arrayListOf(1)""")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testAnonymousObject() {
|
||||||
|
HintType.FUNCTION_HINT.option.set(true)
|
||||||
|
check("""val o = object : Iterable<Int> {
|
||||||
|
override fun iterator()<hint text=": Iterator<Int>" /> = object : Iterator<Int> {
|
||||||
|
override fun next()<hint text=": Int" /> = 1
|
||||||
|
override fun hasNext()<hint text=": Boolean" /> = true
|
||||||
|
}
|
||||||
|
}""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user