Moved common code for IR building to IrBuildUtils
This commit is contained in:
+203
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
-4
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
@@ -260,3 +261,22 @@ 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")
|
||||||
|
}
|
||||||
|
|||||||
+10
-185
@@ -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
|
||||||
|
|||||||
+16
-193
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user