From 08831c08672a3c89a2f815bcdb61226601d03e8e Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Fri, 3 Feb 2023 23:17:12 +0100 Subject: [PATCH] [Analysis API] KTIJ-24192 Use only lowerBound on flexible types when looking for decompiled PSI Otherwise, decompiled declarations with flexible types in them cannot be properly resolved by the Analysis API Examples of such declarations: ```kt fun foo()/*: ImplicitTypeFromJava! */ = var bar/*: ImplicitTypeFromJava! */ = foo() // set(value: ImplicitTypeFromJava!) { ... } ``` ^KTIJ-24192 Fixed --- ...tDeclarationAndFirDeclarationEqualityChecker.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/KtDeclarationAndFirDeclarationEqualityChecker.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/KtDeclarationAndFirDeclarationEqualityChecker.kt index c48358ccb36..4686a662c2b 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/KtDeclarationAndFirDeclarationEqualityChecker.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/KtDeclarationAndFirDeclarationEqualityChecker.kt @@ -193,13 +193,21 @@ object KtDeclarationAndFirDeclarationEqualityChecker { } is ConeTypeVariableType -> lookupTag.name.asString() is ConeLookupTagBasedType -> lookupTag.name.asString() + + // NOTE: Flexible types can occur not only as implicit return types, + // but also as implicit parameter types, for example in setters with implicit types is ConeFlexibleType -> { - // Can be present as return type - "${lowerBound.renderTypeAsKotlinType()}..${upperBound.renderTypeAsKotlinType()}" + // since Kotlin decompiler always "renders" flexible types as their lower bound, we can do the same here + lowerBound.renderTypeAsKotlinType() } + else -> errorWithFirSpecificEntries("Type should not be present in Kotlin declaration", coneType = this) }.replace('/', '.') - return rendered + nullability.suffix + + // UNKNOWN nullability occurs only on flexible types + val nullabilitySuffix = nullability.takeUnless { it == ConeNullability.UNKNOWN }?.suffix.orEmpty() + + return rendered + nullabilitySuffix } private fun ConeTypeProjection.renderTypeAsKotlinType(): String = when (this) {