[cls] write contracts information to cls stubs

^ KTIJ-24665
this information would be used to create resolved FirElements from stubs,
so no ProtoBuf would be kept in memory
This commit is contained in:
Anna Kozlova
2023-04-05 17:12:30 +02:00
committed by Space Team
parent 9d4db72d72
commit 4fe239375f
44 changed files with 1182 additions and 534 deletions
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.resolve.DataClassResolver
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.utils.addToStdlib.runIf
fun createPackageDeclarationsStubs(
parentStub: StubElement<out PsiElement>,
@@ -173,6 +174,7 @@ private class FunctionClsStubBuilder(
// Note that arguments passed to stubs here and elsewhere are based on what stabs would be generated based on decompiled code
// As functions are never decompiled to fun f() = 1 form, hasBlockBody is always true
// This info is anyway irrelevant for the purposes these stubs are used
val hasContract = functionProto.hasContract()
return KotlinFunctionStubImpl(
parent,
callableName.ref(),
@@ -182,7 +184,10 @@ private class FunctionClsStubBuilder(
hasBlockBody = true,
hasBody = Flags.MODALITY.get(functionProto.flags) != Modality.ABSTRACT,
hasTypeParameterListBeforeFunctionName = functionProto.typeParameterList.isNotEmpty(),
mayHaveContract = functionProto.hasContract()
mayHaveContract = hasContract,
runIf(hasContract) {
ClsContractBuilder(c, typeStubBuilder).loadContract(functionProto)
}
)
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.decompiler.stub
import org.jetbrains.kotlin.contracts.description.KtBooleanValueParameterReference
import org.jetbrains.kotlin.contracts.description.KtConstantReference
import org.jetbrains.kotlin.contracts.description.KtEffectDeclaration
import org.jetbrains.kotlin.contracts.description.KtValueParameterReference
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.isInstanceType
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.stubs.impl.*
import org.jetbrains.kotlin.psi.stubs.impl.KotlinContractEffectType.Companion.IGNORE_REFERENCE_PARAMETER_NAME
import org.jetbrains.kotlin.serialization.deserialization.ProtoBufContractDeserializer
import org.jetbrains.kotlin.serialization.deserialization.getClassId
class ClsContractBuilder(private val c: ClsStubBuilderContext, private val typeStubBuilder: TypeClsStubBuilder) :
ProtoBufContractDeserializer<KotlinTypeBean, Nothing?, ProtoBuf.Function>() {
fun loadContract(proto: ProtoBuf.Function): List<KtEffectDeclaration<KotlinTypeBean, Nothing?>>? {
return proto.contract.effectList.map { loadPossiblyConditionalEffect(it, proto) ?: return null }
}
override fun extractVariable(valueParameterIndex: Int, owner: ProtoBuf.Function): KtValueParameterReference<KotlinTypeBean, Nothing?> {
val type = if (valueParameterIndex < 0) {
owner.receiverType
} else owner.valueParameterList[valueParameterIndex].type
return if (type.hasClassName() && c.nameResolver.getClassId(type.className) == StandardClassIds.Boolean) {
KtBooleanValueParameterReference(valueParameterIndex, name = IGNORE_REFERENCE_PARAMETER_NAME)
} else KtValueParameterReference(valueParameterIndex, name = IGNORE_REFERENCE_PARAMETER_NAME)
}
override fun extractType(proto: ProtoBuf.Expression): KotlinTypeBean? {
return typeStubBuilder.createKotlinTypeBean(proto.isInstanceType(c.typeTable))
}
override fun loadConstant(value: ProtoBuf.Expression.ConstantValue): KtConstantReference<KotlinTypeBean, Nothing?> {
return when (value) {
ProtoBuf.Expression.ConstantValue.TRUE -> KotlinContractConstantValues.TRUE
ProtoBuf.Expression.ConstantValue.FALSE -> KotlinContractConstantValues.FALSE
ProtoBuf.Expression.ConstantValue.NULL -> KotlinContractConstantValues.NULL
}
}
override fun getNotNull(): KtConstantReference<KotlinTypeBean, Nothing?> {
return KotlinContractConstantValues.NOT_NULL
}
override fun getWildcard(): KtConstantReference<KotlinTypeBean, Nothing?> {
return KotlinContractConstantValues.WILDCARD
}
}
@@ -150,7 +150,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
}
}
private fun createKotlinTypeBean(
fun createKotlinTypeBean(
type: Type?
): KotlinTypeBean? {
if (type == null) return null