From dead2c8be82f3869c9834f28cf28f11aa994d53a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 26 Apr 2023 13:26:01 +0200 Subject: [PATCH] [LL] stubBased provider: deserialize fir from stubs build from decompiled text if the compiled code is opened in the editor, 1. it's decompiled 2. stub is build over decompiled text 3. this stub replaces the stub built from classes. This process leads to missed information in resulted FIR, e.g. half correct classId. On the other side, this FIR is used only for this opened editor. --- .../kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt | 2 +- .../kotlin/analysis/decompiler/stub/clsStubBuilding.kt | 4 ++-- .../deserialization/StubBasedFirTypeDeserializer.kt | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt index 778b3b27d98..9438d565136 100644 --- a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt @@ -94,7 +94,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { createStubForTypeName(classId, leftReference, { upperBoundType }) val rightReference = KotlinPlaceHolderStubImpl(intersectionType, KtStubElementTypes.TYPE_REFERENCE) val userType = KotlinUserTypeStubImpl(rightReference) - KotlinNameReferenceExpressionStubImpl(userType, StandardNames.FqNames.any.shortName().ref()) + KotlinNameReferenceExpressionStubImpl(userType, StandardNames.FqNames.any.shortName().ref(), true) } private fun createClassReferenceTypeStub(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List) { diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/clsStubBuilding.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/clsStubBuilding.kt index d1d3378dba7..4a5f2ff7877 100644 --- a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/clsStubBuilding.kt +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/clsStubBuilding.kt @@ -141,7 +141,7 @@ fun createStubForTypeName( val segments = fqName.pathSegments().asReversed() assert(segments.isNotEmpty()) - val packageLength = if (substituteWithAny) 1 else typeClassId.packageFqName.pathSegments().size + val classesNestedLevel = segments.size - if (substituteWithAny) 1 else typeClassId.packageFqName.pathSegments().size fun recCreateStubForType(current: StubElement, level: Int): KotlinUserTypeStub { val lastSegment = segments[level] @@ -149,7 +149,7 @@ fun createStubForTypeName( if (level + 1 < segments.size) { recCreateStubForType(userTypeStub, level + 1) } - KotlinNameReferenceExpressionStubImpl(userTypeStub, lastSegment.ref(), level < segments.size - packageLength) + KotlinNameReferenceExpressionStubImpl(userTypeStub, lastSegment.ref(), level < classesNestedLevel) if (!substituteWithAny) { bindTypeArguments(userTypeStub, level) } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt index ae796ed2ab8..f13ed51175e 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt @@ -290,6 +290,14 @@ internal fun KtUserType.classId(): ClassId { } } collectFragments(this) + if (classFragments.isEmpty()) { + //stub is re-built from decompiled text and additional information is already missed + return ClassId( + FqName.fromSegments(packageFragments).parent(), + FqName(packageFragments.last()), + false + ) + } return ClassId( FqName.fromSegments(packageFragments), FqName.fromSegments(classFragments),