Rewrote coroutines lowering to use symbols

This commit is contained in:
Igor Chevdar
2017-05-16 16:33:17 +03:00
parent 827f92305c
commit c048fcecce
3 changed files with 416 additions and 364 deletions
@@ -24,28 +24,28 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.*
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.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.util.createParameterDeclarations import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
abstract class DescriptorWithIrBuilder<out D: DeclarationDescriptor, out B: IrDeclaration> { abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
protected abstract fun buildDescriptor(): D protected abstract fun buildSymbol(): S
protected open fun doInitialize() { } protected open fun doInitialize() { }
protected abstract fun buildIr(): B protected abstract fun buildIr(): D
val descriptor by lazy { buildDescriptor() } val symbol by lazy { buildSymbol() }
private val builtIr by lazy { buildIr() } private val builtIr by lazy { buildIr() }
private var initialized: Boolean = false private var initialized: Boolean = false
@@ -55,7 +55,7 @@ abstract class DescriptorWithIrBuilder<out D: DeclarationDescriptor, out B: IrDe
initialized = true initialized = true
} }
val ir: B val ir: D
get() { get() {
if (!initialized) if (!initialized)
throw Error("Access to IR before initialization") throw Error("Access to IR before initialization")
@@ -64,23 +64,26 @@ abstract class DescriptorWithIrBuilder<out D: DeclarationDescriptor, out B: IrDe
} }
fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
symbol: IrFieldSymbol, type: KotlinType) fieldSymbol: IrFieldSymbol, type: KotlinType)
= object: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>() { = object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
override fun buildDescriptor() = PropertyGetterDescriptorImpl( override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
/* correspondingProperty = */ symbol.descriptor, PropertyGetterDescriptorImpl(
/* annotations = */ Annotations.EMPTY, /* correspondingProperty = */ fieldSymbol.descriptor,
/* modality = */ Modality.FINAL, /* annotations = */ Annotations.EMPTY,
/* visibility = */ Visibilities.PRIVATE, /* modality = */ Modality.FINAL,
/* isDefault = */ false, /* visibility = */ Visibilities.PRIVATE,
/* isExternal = */ false, /* isDefault = */ false,
/* isInline = */ false, /* isExternal = */ false,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION, /* isInline = */ false,
/* original = */ null, /* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* source = */ SourceElement.NO_SOURCE /* original = */ null,
/* source = */ SourceElement.NO_SOURCE
)
) )
override fun doInitialize() { override fun doInitialize() {
val descriptor = symbol.descriptor as PropertyGetterDescriptorImpl
descriptor.apply { descriptor.apply {
initialize(type) initialize(type)
} }
@@ -90,36 +93,39 @@ fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int,
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
origin = origin, origin = origin,
descriptor = descriptor).apply { symbol = symbol).apply {
createParameterDeclarations() createParameterDeclarations()
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody { body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
+irReturn(irGetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), symbol)) +irReturn(irGetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol))
} }
} }
} }
private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
symbol: IrFieldSymbol, type: KotlinType) fieldSymbol: IrFieldSymbol, type: KotlinType)
= object: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>() { = object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
override fun buildDescriptor() = PropertySetterDescriptorImpl( override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
/* correspondingProperty = */ symbol.descriptor, PropertySetterDescriptorImpl(
/* annotations = */ Annotations.EMPTY, /* correspondingProperty = */ fieldSymbol.descriptor,
/* modality = */ Modality.FINAL, /* annotations = */ Annotations.EMPTY,
/* visibility = */ Visibilities.PRIVATE, /* modality = */ Modality.FINAL,
/* isDefault = */ false, /* visibility = */ Visibilities.PRIVATE,
/* isExternal = */ false, /* isDefault = */ false,
/* isInline = */ false, /* isExternal = */ false,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION, /* isInline = */ false,
/* original = */ null, /* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* source = */ SourceElement.NO_SOURCE /* original = */ null,
/* source = */ SourceElement.NO_SOURCE
)
) )
lateinit var valueParameterDescriptor: ValueParameterDescriptor lateinit var valueParameterDescriptor: ValueParameterDescriptor
override fun doInitialize() { override fun doInitialize() {
val descriptor = symbol.descriptor as PropertySetterDescriptorImpl
descriptor.apply { descriptor.apply {
valueParameterDescriptor = ValueParameterDescriptorImpl( valueParameterDescriptor = ValueParameterDescriptorImpl(
containingDeclaration = this, containingDeclaration = this,
@@ -143,46 +149,50 @@ private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffs
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
origin = origin, origin = origin,
descriptor = descriptor).apply { symbol = symbol).apply {
createParameterDeclarations() createParameterDeclarations()
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody { body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
+irSetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), symbol, irGet(this@apply.valueParameters.single().symbol)) +irSetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol, irGet(this@apply.valueParameters.single().symbol))
} }
} }
} }
fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
owner: ClassDescriptor, name: Name, type: KotlinType, isMutable: Boolean) owner: ClassDescriptor, name: Name, type: KotlinType, isMutable: Boolean)
= object: DescriptorWithIrBuilder<PropertyDescriptorImpl, IrProperty>() { = object: SymbolWithIrBuilder<IrFieldSymbol, IrProperty>() {
private lateinit var getterBuilder: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction> private lateinit var getterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>
private var setterBuilder: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>? = null private var setterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>? = null
private lateinit var fieldSymbol: IrFieldSymbol
override fun buildDescriptor() = PropertyDescriptorImpl.create( override fun buildSymbol() = IrFieldSymbolImpl(
/* containingDeclaration = */ owner, PropertyDescriptorImpl.create(
/* annotations = */ Annotations.EMPTY, /* containingDeclaration = */ owner,
/* modality = */ Modality.FINAL, /* annotations = */ Annotations.EMPTY,
/* visibility = */ Visibilities.PRIVATE, /* modality = */ Modality.FINAL,
/* isVar = */ isMutable, /* visibility = */ Visibilities.PRIVATE,
/* name = */ name, /* isVar = */ isMutable,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION, /* name = */ name,
/* source = */ SourceElement.NO_SOURCE, /* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* lateInit = */ false, /* source = */ SourceElement.NO_SOURCE,
/* isConst = */ false, /* lateInit = */ false,
/* isHeader = */ false, /* isConst = */ false,
/* isImpl = */ false, /* isHeader = */ false,
/* isExternal = */ false, /* isImpl = */ false,
/* isDelegated = */ false) /* isExternal = */ false,
/* isDelegated = */ false
)
)
override fun doInitialize() { override fun doInitialize() {
fieldSymbol = IrFieldSymbolImpl(descriptor) val descriptor = symbol.descriptor as PropertyDescriptorImpl
getterBuilder = createPropertyGetterBuilder(startOffset, endOffset, origin, fieldSymbol, type).apply { initialize() } getterBuilder = createPropertyGetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
if (isMutable) if (isMutable)
setterBuilder = createPropertySetterBuilder(startOffset, endOffset, origin, fieldSymbol, type).apply { initialize() } setterBuilder = createPropertySetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
descriptor.initialize(getterBuilder.descriptor, setterBuilder?.descriptor) descriptor.initialize(
/* getter = */ getterBuilder.symbol.descriptor as PropertyGetterDescriptorImpl,
/* setter = */ setterBuilder?.symbol?.descriptor as? PropertySetterDescriptorImpl)
val receiverType: KotlinType? = null val receiverType: KotlinType? = null
descriptor.setType(type, emptyList(), owner.thisAsReceiverParameter, receiverType) descriptor.setType(type, emptyList(), owner.thisAsReceiverParameter, receiverType)
} }
@@ -192,13 +202,13 @@ fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOf
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
origin = origin, origin = origin,
symbol = fieldSymbol) symbol = symbol)
return IrPropertyImpl( return IrPropertyImpl(
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
origin = origin, origin = origin,
isDelegated = false, isDelegated = false,
descriptor = descriptor, descriptor = symbol.descriptor,
backingField = backingField, backingField = backingField,
getter = getterBuilder.ir, getter = getterBuilder.ir,
setter = setterBuilder?.ir) setter = setterBuilder?.ir)
@@ -38,8 +38,12 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.util.createParameterDeclarations import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.ir.util.getArguments
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -171,9 +175,10 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
.map { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) } .map { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) }
.filterNotNull() .filterNotNull()
val contributedDescriptors = ( val contributedDescriptors = (
inheritedKFunctionImpl + invokeMethodBuilder.descriptor inheritedKFunctionImpl + invokeMethodBuilder.symbol.descriptor
).toList() ).toList()
functionReferenceClassDescriptor.initialize(SimpleMemberScope(contributedDescriptors), setOf(constructorBuilder.descriptor), null) functionReferenceClassDescriptor.initialize(
SimpleMemberScope(contributedDescriptors), setOf(constructorBuilder.symbol.descriptor), null)
constructorBuilder.initialize() constructorBuilder.initialize()
functionReferenceClass.declarations.add(constructorBuilder.ir) functionReferenceClass.declarations.add(constructorBuilder.ir)
@@ -185,20 +190,21 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
} }
private fun createConstructorBuilder() private fun createConstructorBuilder()
= object : DescriptorWithIrBuilder<ClassConstructorDescriptorImpl, IrConstructor>() { = object : SymbolWithIrBuilder<IrConstructorSymbol, IrConstructor>() {
private val kFunctionImplConstructorDescriptor = kFunctionImplClassDescriptor.constructors.single() private val kFunctionImplConstructorDescriptor = kFunctionImplClassDescriptor.constructors.single()
override fun buildDescriptor(): ClassConstructorDescriptorImpl { override fun buildSymbol() = IrConstructorSymbolImpl(
return ClassConstructorDescriptorImpl.create( ClassConstructorDescriptorImpl.create(
/* containingDeclaration = */ functionReferenceClassDescriptor, /* containingDeclaration = */ functionReferenceClassDescriptor,
/* annotations = */ Annotations.EMPTY, /* annotations = */ Annotations.EMPTY,
/* isPrimary = */ false, /* isPrimary = */ false,
/* source = */ SourceElement.NO_SOURCE /* source = */ SourceElement.NO_SOURCE
) )
} )
override fun doInitialize() { override fun doInitialize() {
val descriptor = symbol.descriptor as ClassConstructorDescriptorImpl
val constructorParameters = boundFunctionParameters.mapIndexed { index, parameter -> val constructorParameters = boundFunctionParameters.mapIndexed { index, parameter ->
parameter.copyAsValueParameter(descriptor, index) parameter.copyAsValueParameter(descriptor, index)
} }
@@ -217,7 +223,7 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
descriptor = descriptor).apply { symbol = symbol).apply {
val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset)
@@ -261,20 +267,24 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
} }
private fun createInvokeMethodBuilder(functionInvokeFunctionDescriptor: FunctionDescriptor) private fun createInvokeMethodBuilder(functionInvokeFunctionDescriptor: FunctionDescriptor)
= object : DescriptorWithIrBuilder<SimpleFunctionDescriptorImpl, IrFunction>() { = object : SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
override fun buildDescriptor() = SimpleFunctionDescriptorImpl.create( override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
/* containingDeclaration = */ functionReferenceClassDescriptor, SimpleFunctionDescriptorImpl.create(
/* annotations = */ Annotations.EMPTY, /* containingDeclaration = */ functionReferenceClassDescriptor,
/* name = */ Name.identifier("invoke"), /* annotations = */ Annotations.EMPTY,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION, /* name = */ Name.identifier("invoke"),
/* source = */ SourceElement.NO_SOURCE) /* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* source = */ SourceElement.NO_SOURCE
)
)
override fun doInitialize() { override fun doInitialize() {
val descriptor = symbol.descriptor as SimpleFunctionDescriptorImpl
val valueParameters = functionInvokeFunctionDescriptor.valueParameters val valueParameters = functionInvokeFunctionDescriptor.valueParameters
.map { it.copyAsValueParameter(this.descriptor, it.index) } .map { it.copyAsValueParameter(descriptor, it.index) }
this.descriptor.initialize( descriptor.initialize(
/* receiverParameterType = */ null, /* receiverParameterType = */ null,
/* dispatchReceiverParameter = */ functionReferenceClassDescriptor.thisAsReceiverParameter, /* dispatchReceiverParameter = */ functionReferenceClassDescriptor.thisAsReceiverParameter,
/* typeParameters = */ emptyList(), /* typeParameters = */ emptyList(),
@@ -286,15 +296,14 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
} }
} }
override fun buildIr(): IrFunction { override fun buildIr(): IrSimpleFunction {
val startOffset = functionReference.startOffset val startOffset = functionReference.startOffset
val endOffset = functionReference.endOffset val endOffset = functionReference.endOffset
val ourDescriptor = this.descriptor
return IrFunctionImpl( return IrFunctionImpl(
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
descriptor = this.descriptor).apply { symbol = symbol).apply {
val function = this val function = this
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
@@ -317,8 +326,7 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
else -> putValueArgument((it as ValueParameterDescriptor).index, argument) else -> putValueArgument((it as ValueParameterDescriptor).index, argument)
} }
} }
assert(unboundIndex == ourDescriptor.valueParameters.size, assert(unboundIndex == valueParameters.size, { "Not all arguments of <invoke> are used" })
{ "Not all arguments of <invoke> are used" })
} }
) )
} }