diff --git a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/TypeHints.kt b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/TypeHints.kt index a9ab23444b1..65d8dddb0dc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/TypeHints.kt +++ b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/TypeHints.kt @@ -127,28 +127,51 @@ private fun isUnclearType(type: KotlinType, element: KtCallableDeclaration): Boo val initializer = element.initializer ?: return true if (initializer is KtConstantExpression || initializer is KtStringTemplateExpression) return false if (initializer is KtUnaryExpression && initializer.baseExpression is KtConstantExpression) return false - if (initializer is KtCallExpression) { - val resolvedCall = initializer.resolveToCall(BodyResolveMode.FULL) - val resolvedDescriptor = resolvedCall?.candidateDescriptor - if (resolvedDescriptor is SamConstructorDescriptor) { - return false - } - if (resolvedDescriptor is ConstructorDescriptor && - (resolvedDescriptor.constructedClass.declaredTypeParameters.isEmpty() || initializer.typeArgumentList != null) - ) { - return false - } + + if (isConstructorCall(initializer)) { + return false } - if (type.isEnum() && initializer is KtDotQualifiedExpression) { - // Do not show type for enums if initializer has enum entry with explicit enum name: val p = Enum.ENTRY - val enumEntrySelector = initializer.selectorExpression - val enumEntryDescriptor: DeclarationDescriptor? = enumEntrySelector?.resolveMainReferenceToDescriptors()?.singleOrNull() + if (initializer is KtDotQualifiedExpression) { + val selectorExpression = initializer.selectorExpression + if (type.isEnum()) { + // Do not show type for enums if initializer has enum entry with explicit enum name: val p = Enum.ENTRY + val enumEntryDescriptor: DeclarationDescriptor? = selectorExpression?.resolveMainReferenceToDescriptors()?.singleOrNull() - if (enumEntryDescriptor != null && DescriptorUtils.isEnumEntry(enumEntryDescriptor)) { + if (enumEntryDescriptor != null && DescriptorUtils.isEnumEntry(enumEntryDescriptor)) { + return false + } + } + + if (initializer.receiverExpression.isClassOrPackageReference() && isConstructorCall(selectorExpression)) { return false } } return true } + +private fun isConstructorCall(initializer: KtExpression?): Boolean { + if (initializer is KtCallExpression) { + val resolvedCall = initializer.resolveToCall(BodyResolveMode.FULL) + val resolvedDescriptor = resolvedCall?.candidateDescriptor + if (resolvedDescriptor is SamConstructorDescriptor) { + return true + } + if (resolvedDescriptor is ConstructorDescriptor && + (resolvedDescriptor.constructedClass.declaredTypeParameters.isEmpty() || initializer.typeArgumentList != null) + ) { + return true + } + return false + } + + return false +} + +private fun KtExpression.isClassOrPackageReference(): Boolean = + when (this) { + is KtNameReferenceExpression -> this.resolveMainReferenceToDescriptors().singleOrNull().let { it is ClassDescriptor || it is PackageViewDescriptor } + is KtDotQualifiedExpression -> this.selectorExpression?.isClassOrPackageReference() ?: false + else -> false + } diff --git a/idea/tests/org/jetbrains/kotlin/idea/parameterInfo/InlayTypeHintsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/parameterInfo/InlayTypeHintsTest.kt index d400704b12b..2808105ed58 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/parameterInfo/InlayTypeHintsTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/parameterInfo/InlayTypeHintsTest.kt @@ -33,6 +33,29 @@ class InlayTypeHintsTest : KotlinLightCodeInsightFixtureTestCase() { checkLocalVariable("""fun foo() { val (i, s) = 1 to "" }""") } + fun testQualifiedReferences() { + checkLocalVariable(""" + package p + class A { + class B { + class C { + class D + } + } + inner class E + enum class F { enumCase } + } + fun foo() { + val v1 = A.B.C.D() + val v2 = p.A.B.C.D() + val v3 = A().E() + val v4 = p.A.F.enumCase + val v5 = A.F.enumCase + val v6 = p.A() + } + """) + } + fun testPropertyType() { checkPropertyHint("""val a = listOf("a")""") }