Moved common code for IR building to IrBuildUtils

This commit is contained in:
Igor Chevdar
2017-05-12 19:36:19 +03:00
parent a41552b3c8
commit 9120e0b998
4 changed files with 254 additions and 383 deletions
@@ -0,0 +1,203 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.konan.lower.SuspendFunctionsLowering
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
abstract class DescriptorWithIrBuilder<out D: DeclarationDescriptor, out B: IrDeclaration> {
protected abstract fun buildDescriptor(): D
protected open fun doInitialize() { }
protected abstract fun buildIr(): B
val descriptor by lazy { buildDescriptor() }
private val builtIr by lazy { buildIr() }
private var initialized: Boolean = false
fun initialize() {
doInitialize()
initialized = true
}
val ir: B
get() {
if (!initialized)
throw Error("Access to IR before initialization")
return builtIr
}
}
fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
propertyDescriptor: PropertyDescriptor, type: KotlinType)
= object: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>() {
override fun buildDescriptor() = PropertyGetterDescriptorImpl(
/* correspondingProperty = */ propertyDescriptor,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isDefault = */ false,
/* isExternal = */ false,
/* isInline = */ false,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* original = */ null,
/* source = */ SourceElement.NO_SOURCE
)
override fun doInitialize() {
descriptor.apply {
initialize(type)
}
}
override fun buildIr() = IrFunctionImpl(
startOffset = startOffset,
endOffset = endOffset,
origin = origin,
descriptor = descriptor).apply {
createParameterDeclarations()
body = createIrBuilder(descriptor, startOffset, endOffset).irBlockBody {
+irReturn(irGetField(irThis(), propertyDescriptor))
}
}
}
private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
propertyDescriptor: PropertyDescriptor, type: KotlinType)
= object: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>() {
override fun buildDescriptor() = PropertySetterDescriptorImpl(
/* correspondingProperty = */ propertyDescriptor,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isDefault = */ false,
/* isExternal = */ false,
/* isInline = */ false,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* original = */ null,
/* source = */ SourceElement.NO_SOURCE
)
lateinit var valueParameterDescriptor: ValueParameterDescriptor
override fun doInitialize() {
descriptor.apply {
valueParameterDescriptor = ValueParameterDescriptorImpl(
containingDeclaration = this,
original = null,
index = 0,
annotations = Annotations.EMPTY,
name = Name.identifier("value"),
outType = type,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = SourceElement.NO_SOURCE
)
initialize(valueParameterDescriptor)
}
}
override fun buildIr() = IrFunctionImpl(
startOffset = startOffset,
endOffset = endOffset,
origin = origin,
descriptor = descriptor).apply {
createParameterDeclarations()
body = createIrBuilder(descriptor, startOffset, endOffset).irBlockBody {
+irSetField(irThis(), propertyDescriptor, irGet(valueParameterDescriptor))
}
}
}
fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
owner: ClassDescriptor, name: Name, type: KotlinType, isMutable: Boolean)
= object: DescriptorWithIrBuilder<PropertyDescriptorImpl, IrProperty>() {
private lateinit var getterBuilder: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>
private var setterBuilder: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>? = null
override fun buildDescriptor() = PropertyDescriptorImpl.create(
/* containingDeclaration = */ owner,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isVar = */ isMutable,
/* name = */ name,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* source = */ SourceElement.NO_SOURCE,
/* lateInit = */ false,
/* isConst = */ false,
/* isHeader = */ false,
/* isImpl = */ false,
/* isExternal = */ false,
/* isDelegated = */ false)
override fun doInitialize() {
getterBuilder = createPropertyGetterBuilder(startOffset, endOffset, origin, descriptor, type).apply { initialize() }
if (isMutable)
setterBuilder = createPropertySetterBuilder(startOffset, endOffset, origin, descriptor, type).apply { initialize() }
descriptor.initialize(getterBuilder.descriptor, setterBuilder?.descriptor)
val receiverType: KotlinType? = null
descriptor.setType(type, emptyList(), owner.thisAsReceiverParameter, receiverType)
}
override fun buildIr(): IrProperty {
val backingField = IrFieldImpl(
startOffset = startOffset,
endOffset = endOffset,
origin = origin,
descriptor = descriptor)
return IrPropertyImpl(
startOffset = startOffset,
endOffset = endOffset,
origin = origin,
isDelegated = false,
descriptor = descriptor,
backingField = backingField,
getter = getterBuilder.ir,
setter = setterBuilder?.ir)
}
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.konan.util.atMostOne import org.jetbrains.kotlin.backend.konan.util.atMostOne
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
@@ -76,13 +77,13 @@ class DeclarationIrBuilder : IrBuilderWithScope {
@Deprecated("Creates unbound symbol") @Deprecated("Creates unbound symbol")
fun BackendContext.createIrBuilder(declarationDescriptor: DeclarationDescriptor, fun BackendContext.createIrBuilder(declarationDescriptor: DeclarationDescriptor,
startOffset : Int = UNDEFINED_OFFSET, startOffset: Int = UNDEFINED_OFFSET,
endOffset : Int = UNDEFINED_OFFSET) = endOffset: Int = UNDEFINED_OFFSET) =
DeclarationIrBuilder(this, declarationDescriptor, startOffset, endOffset) DeclarationIrBuilder(this, declarationDescriptor, startOffset, endOffset)
fun BackendContext.createIrBuilder(symbol: IrSymbol, fun BackendContext.createIrBuilder(symbol: IrSymbol,
startOffset : Int = UNDEFINED_OFFSET, startOffset: Int = UNDEFINED_OFFSET,
endOffset : Int = UNDEFINED_OFFSET) = endOffset: Int = UNDEFINED_OFFSET) =
DeclarationIrBuilder(this, symbol, startOffset, endOffset) DeclarationIrBuilder(this, symbol, startOffset, endOffset)
@@ -259,4 +260,23 @@ fun IrConstructor.callsSuper(): Boolean {
}) })
assert(numberOfCalls == 1, { "Expected exactly one delegating constructor call but none encountered: $descriptor" }) assert(numberOfCalls == 1, { "Expected exactly one delegating constructor call but none encountered: $descriptor" })
return callsSuper return callsSuper
} }
fun ParameterDescriptor.copyAsValueParameter(newOwner: CallableDescriptor, index: Int)
= when (this) {
is ValueParameterDescriptor -> this.copy(newOwner, name, index)
is ReceiverParameterDescriptor -> ValueParameterDescriptorImpl(
containingDeclaration = newOwner,
original = null,
index = index,
annotations = annotations,
name = name,
outType = type,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = source
)
else -> throw Error("Unexpected parameter descriptor: $this")
}
@@ -103,32 +103,6 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
return listOf(declaration) + createdClasses return listOf(declaration) + createdClasses
} }
private abstract class DescriptorWithIrBuilder<out D : DeclarationDescriptor, out B : IrDeclaration> {
protected abstract fun buildDescriptor(): D
protected open fun doInitialize() {}
protected abstract fun buildIr(): B
val descriptor by lazy { buildDescriptor() }
private val builtIr by lazy { buildIr() }
private var initialized: Boolean = false
fun initialize() {
doInitialize()
initialized = true
}
val ir: B
get() {
if (!initialized)
throw Error("Access to IR before initialization")
return builtIr
}
}
private class BuiltFunctionReference(val functionReferenceClass: IrClass, private class BuiltFunctionReference(val functionReferenceClass: IrClass,
val functionReferenceConstructorDescriptor: ClassConstructorDescriptor) val functionReferenceConstructorDescriptor: ClassConstructorDescriptor)
@@ -208,25 +182,6 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
return BuiltFunctionReference(functionReferenceClass, constructorBuilder.descriptor) return BuiltFunctionReference(functionReferenceClass, constructorBuilder.descriptor)
} }
private fun ParameterDescriptor.copyAsValueParameter(newOwner: CallableDescriptor, index: Int)
= when (this) {
is ValueParameterDescriptor -> this.copy(newOwner, name, index)
is ReceiverParameterDescriptor -> ValueParameterDescriptorImpl(
containingDeclaration = newOwner,
original = null,
index = index,
annotations = annotations,
name = name,
outType = type,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = source
)
else -> throw Error("Unexpected parameter descriptor: $this")
}
private fun createConstructorBuilder() private fun createConstructorBuilder()
= object : DescriptorWithIrBuilder<ClassConstructorDescriptorImpl, IrConstructor>() { = object : DescriptorWithIrBuilder<ClassConstructorDescriptorImpl, IrConstructor>() {
@@ -367,147 +322,17 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
} }
} }
private fun createPropertyGetterBuilder(propertyDescriptor: PropertyDescriptor, type: KotlinType)
= object : DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>() {
override fun buildDescriptor() = PropertyGetterDescriptorImpl(
/* correspondingProperty = */ propertyDescriptor,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isDefault = */ false,
/* isExternal = */ false,
/* isInline = */ false,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* original = */ null,
/* source = */ SourceElement.NO_SOURCE
)
override fun doInitialize() {
descriptor.apply {
initialize(type)
}
}
override fun buildIr() = IrFunctionImpl(
startOffset = functionReference.startOffset,
endOffset = functionReference.endOffset,
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
descriptor = descriptor).apply {
createParameterDeclarations()
body = context.createIrBuilder(descriptor, startOffset, endOffset).irBlockBody {
+irReturn(irGetField(irThis(), propertyDescriptor))
}
}
}
private fun createPropertySetterBuilder(propertyDescriptor: PropertyDescriptor, type: KotlinType)
= object : DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>() {
override fun buildDescriptor() = PropertySetterDescriptorImpl(
/* correspondingProperty = */ propertyDescriptor,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isDefault = */ false,
/* isExternal = */ false,
/* isInline = */ false,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* original = */ null,
/* source = */ SourceElement.NO_SOURCE
)
lateinit var valueParameterDescriptor: ValueParameterDescriptor
override fun doInitialize() {
descriptor.apply {
valueParameterDescriptor = ValueParameterDescriptorImpl(
containingDeclaration = this,
original = null,
index = 0,
annotations = Annotations.EMPTY,
name = Name.identifier("value"),
outType = type,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = SourceElement.NO_SOURCE
)
initialize(valueParameterDescriptor)
}
}
override fun buildIr() = IrFunctionImpl(
startOffset = functionReference.startOffset,
endOffset = functionReference.endOffset,
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
descriptor = descriptor).apply {
createParameterDeclarations()
body = context.createIrBuilder(descriptor, startOffset, endOffset).irBlockBody {
+irSetField(irThis(), propertyDescriptor, irGet(valueParameterDescriptor))
}
}
}
private fun createPropertyWithBackingFieldBuilder(name: Name, type: KotlinType, isMutable: Boolean)
= object : DescriptorWithIrBuilder<PropertyDescriptorImpl, IrProperty>() {
private lateinit var getterBuilder: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>
private var setterBuilder: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>? = null
override fun buildDescriptor() = PropertyDescriptorImpl.create(
/* containingDeclaration = */ functionReferenceClassDescriptor,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isVar = */ isMutable,
/* name = */ name,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* source = */ SourceElement.NO_SOURCE,
/* lateInit = */ false,
/* isConst = */ false,
/* isHeader = */ false,
/* isImpl = */ false,
/* isExternal = */ false,
/* isDelegated = */ false)
override fun doInitialize() {
getterBuilder = createPropertyGetterBuilder(descriptor, type).apply { initialize() }
if (isMutable)
setterBuilder = createPropertySetterBuilder(descriptor, type).apply { initialize() }
descriptor.initialize(getterBuilder.descriptor, setterBuilder?.descriptor)
val receiverType: KotlinType? = null
descriptor.setType(type, emptyList(), functionReferenceClassDescriptor.thisAsReceiverParameter, receiverType)
}
override fun buildIr(): IrProperty {
val startOffset = functionReference.startOffset
val endOffset = functionReference.endOffset
val backingField = IrFieldImpl(
startOffset = startOffset,
endOffset = endOffset,
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
descriptor = descriptor)
return IrPropertyImpl(
startOffset = startOffset,
endOffset = endOffset,
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
isDelegated = false,
descriptor = descriptor,
backingField = backingField,
getter = getterBuilder.ir,
setter = setterBuilder?.ir)
}
}
private fun buildPropertyWithBackingField(name: Name, type: KotlinType, isMutable: Boolean): PropertyDescriptor { private fun buildPropertyWithBackingField(name: Name, type: KotlinType, isMutable: Boolean): PropertyDescriptor {
val propertyBuilder = createPropertyWithBackingFieldBuilder(name, type, isMutable).apply { initialize() } val propertyBuilder = context.createPropertyWithBackingFieldBuilder(
startOffset = functionReference.startOffset,
endOffset = functionReference.endOffset,
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
owner = functionReferenceClassDescriptor,
name = name,
type = type,
isMutable = isMutable).apply {
initialize()
}
functionReferenceMembers.add(propertyBuilder.ir) functionReferenceMembers.add(propertyBuilder.ir)
return propertyBuilder.descriptor return propertyBuilder.descriptor
@@ -121,8 +121,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
override fun visitCall(expression: IrCall): IrExpression { override fun visitCall(expression: IrCall): IrExpression {
expression.transformChildrenVoid(this) expression.transformChildrenVoid(this)
val descriptor = expression.descriptor as? FunctionDescriptor val descriptor = expression.descriptor
?: return expression
if (!descriptor.isSuspendFunctionInvoke || descriptor.extensionReceiverParameter == null) if (!descriptor.isSuspendFunctionInvoke || descriptor.extensionReceiverParameter == null)
return expression return expression
@@ -130,8 +129,8 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
val invokeFunctionDescriptor = descriptor.dispatchReceiverParameter!!.type.memberScope val invokeFunctionDescriptor = descriptor.dispatchReceiverParameter!!.type.memberScope
.getContributedFunctions(Name.identifier("invoke"), NoLookupLocation.FROM_BACKEND).single() .getContributedFunctions(Name.identifier("invoke"), NoLookupLocation.FROM_BACKEND).single()
return IrCallImpl( return IrCallImpl(
startOffset = expression.startOffset, startOffset = expression.startOffset,
endOffset = expression.endOffset, endOffset = expression.endOffset,
calleeDescriptor = invokeFunctionDescriptor calleeDescriptor = invokeFunctionDescriptor
).apply { ).apply {
dispatchReceiver = expression.dispatchReceiver dispatchReceiver = expression.dispatchReceiver
@@ -165,11 +164,11 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
} }
SuspendFunctionKind.NEEDS_STATE_MACHINE -> { SuspendFunctionKind.NEEDS_STATE_MACHINE -> {
val coroutine: IrDeclaration = buildCoroutine(irFunction, callableReference) // Coroutine implementation. val coroutine = buildCoroutine(irFunction, callableReference) // Coroutine implementation.
if (suspendLambdas.contains(irFunction.descriptor)) // Suspend lambdas are called through factory method <create>, if (suspendLambdas.contains(irFunction.descriptor)) // Suspend lambdas are called through factory method <create>,
listOf(coroutine) // thus we can eliminate original body. listOf(coroutine) // thus we can eliminate original body.
else else
listOf( listOf<IrDeclaration>(
coroutine, coroutine,
irFunction irFunction
) )
@@ -182,8 +181,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
return SuspendFunctionKind.NEEDS_STATE_MACHINE // Suspend lambdas always need coroutine implementation. return SuspendFunctionKind.NEEDS_STATE_MACHINE // Suspend lambdas always need coroutine implementation.
val body = irFunction.body val body = irFunction.body
if (body == null) ?: return SuspendFunctionKind.NO_SUSPEND_CALLS
return SuspendFunctionKind.NO_SUSPEND_CALLS
var numberOfSuspendCalls = 0 var numberOfSuspendCalls = 0
body.acceptVoid(object: IrElementVisitorVoid { body.acceptVoid(object: IrElementVisitorVoid {
@@ -285,32 +283,6 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
return coroutine.coroutineClass return coroutine.coroutineClass
} }
private abstract class DescriptorWithIrBuilder<out D: DeclarationDescriptor, out B: IrDeclaration> {
protected abstract fun buildDescriptor(): D
protected open fun doInitialize() { }
protected abstract fun buildIr(): B
val descriptor by lazy { buildDescriptor() }
private val builtIr by lazy { buildIr() }
private var initialized: Boolean = false
fun initialize() {
doInitialize()
initialized = true
}
val ir: B
get() {
if (!initialized)
throw Error("Access to IR before initialization")
return builtIr
}
}
private class BuiltCoroutine(val coroutineClass: IrClass, private class BuiltCoroutine(val coroutineClass: IrClass,
val coroutineConstructorDescriptor: ClassConstructorDescriptor, val coroutineConstructorDescriptor: ClassConstructorDescriptor,
val doResumeFunctionDescriptor: FunctionDescriptor) val doResumeFunctionDescriptor: FunctionDescriptor)
@@ -522,25 +494,6 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
} }
} }
private fun ParameterDescriptor.copyAsValueParameter(newOwner: CallableDescriptor, index: Int)
= when (this) {
is ValueParameterDescriptor -> this.copy(newOwner, name, index)
is ReceiverParameterDescriptor -> ValueParameterDescriptorImpl(
containingDeclaration = newOwner,
original = null,
index = index,
annotations = annotations,
name = name,
outType = type,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = source
)
else -> throw Error("Unexpected parameter descriptor: $this")
}
private fun createFactoryConstructorBuilder(boundParams: List<ParameterDescriptor>) private fun createFactoryConstructorBuilder(boundParams: List<ParameterDescriptor>)
= object : DescriptorWithIrBuilder<ClassConstructorDescriptorImpl, IrConstructor>() { = object : DescriptorWithIrBuilder<ClassConstructorDescriptorImpl, IrConstructor>() {
@@ -725,147 +678,17 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
} }
} }
private fun createPropertyGetterBuilder(propertyDescriptor: PropertyDescriptor, type: KotlinType)
= object: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>() {
override fun buildDescriptor() = PropertyGetterDescriptorImpl(
/* correspondingProperty = */ propertyDescriptor,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isDefault = */ false,
/* isExternal = */ false,
/* isInline = */ false,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* original = */ null,
/* source = */ SourceElement.NO_SOURCE
)
override fun doInitialize() {
descriptor.apply {
initialize(type)
}
}
override fun buildIr() = IrFunctionImpl(
startOffset = irFunction.startOffset,
endOffset = irFunction.endOffset,
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
descriptor = descriptor).apply {
createParameterDeclarations()
body = context.createIrBuilder(descriptor, startOffset, endOffset).irBlockBody {
+irReturn(irGetField(irThis(), propertyDescriptor))
}
}
}
private fun createPropertySetterBuilder(propertyDescriptor: PropertyDescriptor, type: KotlinType)
= object: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>() {
override fun buildDescriptor() = PropertySetterDescriptorImpl(
/* correspondingProperty = */ propertyDescriptor,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isDefault = */ false,
/* isExternal = */ false,
/* isInline = */ false,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* original = */ null,
/* source = */ SourceElement.NO_SOURCE
)
lateinit var valueParameterDescriptor: ValueParameterDescriptor
override fun doInitialize() {
descriptor.apply {
valueParameterDescriptor = ValueParameterDescriptorImpl(
containingDeclaration = this,
original = null,
index = 0,
annotations = Annotations.EMPTY,
name = Name.identifier("value"),
outType = type,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = SourceElement.NO_SOURCE
)
initialize(valueParameterDescriptor)
}
}
override fun buildIr() = IrFunctionImpl(
startOffset = irFunction.startOffset,
endOffset = irFunction.endOffset,
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
descriptor = descriptor).apply {
createParameterDeclarations()
body = context.createIrBuilder(descriptor, startOffset, endOffset).irBlockBody {
+irSetField(irThis(), propertyDescriptor, irGet(valueParameterDescriptor))
}
}
}
private fun createPropertyWithBackingFieldBuilder(name: Name, type: KotlinType, isMutable: Boolean)
= object: DescriptorWithIrBuilder<PropertyDescriptorImpl, IrProperty>() {
private lateinit var getterBuilder: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>
private var setterBuilder: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>? = null
override fun buildDescriptor() = PropertyDescriptorImpl.create(
/* containingDeclaration = */ coroutineClassDescriptor,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isVar = */ isMutable,
/* name = */ name,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* source = */ SourceElement.NO_SOURCE,
/* lateInit = */ false,
/* isConst = */ false,
/* isHeader = */ false,
/* isImpl = */ false,
/* isExternal = */ false,
/* isDelegated = */ false)
override fun doInitialize() {
getterBuilder = createPropertyGetterBuilder(descriptor, type).apply { initialize() }
if (isMutable)
setterBuilder = createPropertySetterBuilder(descriptor, type).apply { initialize() }
descriptor.initialize(getterBuilder.descriptor, setterBuilder?.descriptor)
val receiverType: KotlinType? = null
descriptor.setType(type, emptyList(), coroutineClassDescriptor.thisAsReceiverParameter, receiverType)
}
override fun buildIr(): IrProperty {
val startOffset = irFunction.startOffset
val endOffset = irFunction.endOffset
val backingField = IrFieldImpl(
startOffset = startOffset,
endOffset = endOffset,
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
descriptor = descriptor)
return IrPropertyImpl(
startOffset = startOffset,
endOffset = endOffset,
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
isDelegated = false,
descriptor = descriptor,
backingField = backingField,
getter = getterBuilder.ir,
setter = setterBuilder?.ir)
}
}
private fun buildPropertyWithBackingField(name: Name, type: KotlinType, isMutable: Boolean): PropertyDescriptor { private fun buildPropertyWithBackingField(name: Name, type: KotlinType, isMutable: Boolean): PropertyDescriptor {
val propertyBuilder = createPropertyWithBackingFieldBuilder(name, type, isMutable).apply { initialize() } val propertyBuilder = context.createPropertyWithBackingFieldBuilder(
startOffset = irFunction.startOffset,
endOffset = irFunction.endOffset,
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
owner = coroutineClassDescriptor,
name = name,
type = type,
isMutable = isMutable).apply {
initialize()
}
coroutineMembers.add(propertyBuilder.ir) coroutineMembers.add(propertyBuilder.ir)
return propertyBuilder.descriptor return propertyBuilder.descriptor