[FE, IR] Support deserialization
This commit is contained in:
committed by
TeamCityServer
parent
2fbfee3e11
commit
617af898b0
+12
@@ -15975,6 +15975,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionClasses/simple.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/simple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("useFromAnotherModule.kt")
|
||||||
|
public void testUseFromAnotherModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionClasses/useFromAnotherModule.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@@ -16217,6 +16223,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/this.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/this.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("useFromAnotherModule.kt")
|
||||||
|
public void testUseFromAnotherModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/useFromAnotherModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/extensionFunctions/contextReceivers/fromKEEP")
|
@TestMetadata("compiler/testData/codegen/box/extensionFunctions/contextReceivers/fromKEEP")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+14
-3
@@ -8,11 +8,13 @@ package org.jetbrains.kotlin.ir.declarations.lazy
|
|||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import kotlin.properties.ReadWriteProperty
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
interface IrLazyFunctionBase : IrLazyDeclarationBase, IrTypeParametersContainer {
|
interface IrLazyFunctionBase : IrLazyDeclarationBase, IrTypeParametersContainer {
|
||||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||||
@@ -28,8 +30,17 @@ interface IrLazyFunctionBase : IrLazyDeclarationBase, IrTypeParametersContainer
|
|||||||
|
|
||||||
fun createValueParameters(): List<IrValueParameter> =
|
fun createValueParameters(): List<IrValueParameter> =
|
||||||
typeTranslator.buildWithScope(this) {
|
typeTranslator.buildWithScope(this) {
|
||||||
descriptor.valueParameters.mapTo(arrayListOf()) {
|
val result = arrayListOf<IrValueParameter>()
|
||||||
stubGenerator.generateValueParameterStub(it).apply { parent = this@IrLazyFunctionBase }
|
descriptor.contextReceiverParameters.mapIndexedTo(result) { i, contextReceiverParameter ->
|
||||||
|
factory.createValueParameter(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, IrValueParameterSymbolImpl(contextReceiverParameter),
|
||||||
|
Name.identifier("contextReceiverParameter$i"), i, contextReceiverParameter.type.toIrType(),
|
||||||
|
null, isCrossinline = false, isNoinline = false, isHidden = false, isAssignable = false
|
||||||
|
).apply { parent = this@IrLazyFunctionBase }
|
||||||
|
}
|
||||||
|
descriptor.valueParameters.mapTo(result) {
|
||||||
|
stubGenerator.generateValueParameterStub(it, it.index + descriptor.contextReceiverParameters.size)
|
||||||
|
.apply { parent = this@IrLazyFunctionBase }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ abstract class DeclarationStubGenerator(
|
|||||||
|
|
||||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||||
|
|
||||||
internal fun generateValueParameterStub(descriptor: ValueParameterDescriptor): IrValueParameter = with(descriptor) {
|
internal fun generateValueParameterStub(descriptor: ValueParameterDescriptor, index: Int): IrValueParameter = with(descriptor) {
|
||||||
IrLazyValueParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, computeOrigin(this), IrValueParameterSymbolImpl(this), this, name, index,
|
IrLazyValueParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, computeOrigin(this), IrValueParameterSymbolImpl(this), this, name, index,
|
||||||
type.toIrType(), varargElementType?.toIrType(), isCrossinline, isNoinline, isHidden = false, isAssignable = false, this@DeclarationStubGenerator, typeTranslator)
|
type.toIrType(), varargElementType?.toIrType(), isCrossinline, isNoinline, isHidden = false, isAssignable = false, this@DeclarationStubGenerator, typeTranslator)
|
||||||
.also { irValueParameter ->
|
.also { irValueParameter ->
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: A.kt
|
||||||
|
|
||||||
|
package a
|
||||||
|
|
||||||
|
class O(val o: String)
|
||||||
|
|
||||||
|
context(O)
|
||||||
|
class OK(val k: String) {
|
||||||
|
val result = o + k
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: B.kt
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return with(a.O("O")) {
|
||||||
|
val ok = a.OK("K")
|
||||||
|
ok.result
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: A.kt
|
||||||
|
|
||||||
|
package a
|
||||||
|
|
||||||
|
context(Int)
|
||||||
|
fun one(dummy: Any?) = this@Int
|
||||||
|
|
||||||
|
context(Int)
|
||||||
|
val two get() = this@Int
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
context(Int)
|
||||||
|
val three get() = this@Int
|
||||||
|
|
||||||
|
context(Int)
|
||||||
|
fun four(dummy: Any?) = this@Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: B.kt
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return with(1) {
|
||||||
|
if (a.one(null) + a.two + a.Foo().three + a.Foo().four(null) == 4) "OK" else "fail"
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -15975,6 +15975,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionClasses/simple.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/simple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("useFromAnotherModule.kt")
|
||||||
|
public void testUseFromAnotherModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionClasses/useFromAnotherModule.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@@ -16217,6 +16223,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/this.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/this.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("useFromAnotherModule.kt")
|
||||||
|
public void testUseFromAnotherModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/useFromAnotherModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/extensionFunctions/contextReceivers/fromKEEP")
|
@TestMetadata("compiler/testData/codegen/box/extensionFunctions/contextReceivers/fromKEEP")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+12
-2
@@ -60,7 +60,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
proto.receiverType(c.typeTable)?.let(local.typeDeserializer::type)?.let { receiverType ->
|
proto.receiverType(c.typeTable)?.let(local.typeDeserializer::type)?.let { receiverType ->
|
||||||
DescriptorFactory.createExtensionReceiverParameterForCallable(property, receiverType, receiverAnnotations)
|
DescriptorFactory.createExtensionReceiverParameterForCallable(property, receiverType, receiverAnnotations)
|
||||||
},
|
},
|
||||||
emptyList()
|
proto.contextReceiverTypeList.map { it.toContextReceiver(local, property) }
|
||||||
)
|
)
|
||||||
|
|
||||||
// Per documentation on Property.getter_flags in metadata.proto, if an accessor flags field is absent, its value should be computed
|
// Per documentation on Property.getter_flags in metadata.proto, if an accessor flags field is absent, its value should be computed
|
||||||
@@ -152,6 +152,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
private fun DeserializedSimpleFunctionDescriptor.initializeWithCoroutinesExperimentalityStatus(
|
private fun DeserializedSimpleFunctionDescriptor.initializeWithCoroutinesExperimentalityStatus(
|
||||||
extensionReceiverParameter: ReceiverParameterDescriptor?,
|
extensionReceiverParameter: ReceiverParameterDescriptor?,
|
||||||
dispatchReceiverParameter: ReceiverParameterDescriptor?,
|
dispatchReceiverParameter: ReceiverParameterDescriptor?,
|
||||||
|
contextReceiverParameters: List<ReceiverParameterDescriptor>,
|
||||||
typeParameters: List<TypeParameterDescriptor>,
|
typeParameters: List<TypeParameterDescriptor>,
|
||||||
unsubstitutedValueParameters: List<ValueParameterDescriptor>,
|
unsubstitutedValueParameters: List<ValueParameterDescriptor>,
|
||||||
unsubstitutedReturnType: KotlinType?,
|
unsubstitutedReturnType: KotlinType?,
|
||||||
@@ -162,7 +163,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
initialize(
|
initialize(
|
||||||
extensionReceiverParameter,
|
extensionReceiverParameter,
|
||||||
dispatchReceiverParameter,
|
dispatchReceiverParameter,
|
||||||
emptyList(), // TODO
|
contextReceiverParameters,
|
||||||
typeParameters,
|
typeParameters,
|
||||||
unsubstitutedValueParameters,
|
unsubstitutedValueParameters,
|
||||||
unsubstitutedReturnType,
|
unsubstitutedReturnType,
|
||||||
@@ -202,6 +203,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
DescriptorFactory.createExtensionReceiverParameterForCallable(function, receiverType, receiverAnnotations)
|
DescriptorFactory.createExtensionReceiverParameterForCallable(function, receiverType, receiverAnnotations)
|
||||||
},
|
},
|
||||||
getDispatchReceiverParameter(),
|
getDispatchReceiverParameter(),
|
||||||
|
proto.contextReceiverTypeList.mapNotNull { it.toContextReceiver(local, function) },
|
||||||
local.typeDeserializer.ownTypeParameters,
|
local.typeDeserializer.ownTypeParameters,
|
||||||
local.memberDeserializer.valueParameters(proto.valueParameterList, proto, AnnotatedCallableKind.FUNCTION),
|
local.memberDeserializer.valueParameters(proto.valueParameterList, proto, AnnotatedCallableKind.FUNCTION),
|
||||||
local.typeDeserializer.type(proto.returnType(c.typeTable)),
|
local.typeDeserializer.type(proto.returnType(c.typeTable)),
|
||||||
@@ -341,4 +343,12 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
is DeserializedClassDescriptor -> thisAsProtoContainer
|
is DeserializedClassDescriptor -> thisAsProtoContainer
|
||||||
else -> null // TODO: support annotations on lambdas and their parameters
|
else -> null // TODO: support annotations on lambdas and their parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ProtoBuf.Type.toContextReceiver(
|
||||||
|
deserializationContext: DeserializationContext,
|
||||||
|
callableDescriptor: CallableDescriptor
|
||||||
|
): ReceiverParameterDescriptor? {
|
||||||
|
val contextReceiverType = deserializationContext.typeDeserializer.type(this)
|
||||||
|
return DescriptorFactory.createContextReceiverParameterForCallable(callableDescriptor, contextReceiverType, Annotations.EMPTY)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.incremental.record
|
import org.jetbrains.kotlin.incremental.record
|
||||||
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum
|
import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ContextClassReceiver
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||||
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
|
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -140,6 +142,15 @@ class DeserializedClassDescriptor(
|
|||||||
|
|
||||||
override fun getConstructors() = constructors()
|
override fun getConstructors() = constructors()
|
||||||
|
|
||||||
|
override fun getContextReceivers(): List<ReceiverParameterDescriptor> = classProto.contextReceiverTypeList.map {
|
||||||
|
val contextReceiverType = c.typeDeserializer.type(it)
|
||||||
|
ReceiverParameterDescriptorImpl(
|
||||||
|
thisAsReceiverParameter,
|
||||||
|
ContextClassReceiver(this, contextReceiverType, null),
|
||||||
|
Annotations.EMPTY
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private fun computeCompanionObjectDescriptor(): ClassDescriptor? {
|
private fun computeCompanionObjectDescriptor(): ClassDescriptor? {
|
||||||
if (!classProto.hasCompanionObjectName()) return null
|
if (!classProto.hasCompanionObjectName()) return null
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user