IrTypes: migrate some code from backend.common
(cherry picked from commit 3788130)
This commit is contained in:
committed by
Dmitry Petrov
parent
f1bdb48a76
commit
b11abeed6a
+7
-5
@@ -22,10 +22,11 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||||
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
|
||||||
|
|
||||||
typealias ReportError = (element: IrElement, message: String) -> Unit
|
typealias ReportError = (element: IrElement, message: String) -> Unit
|
||||||
|
|
||||||
@@ -43,8 +44,9 @@ class CheckIrElementVisitor(val builtIns: KotlinBuiltIns, val reportError: Repor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun IrExpression.ensureTypeIs(expectedType: KotlinType) {
|
private fun IrExpression.ensureTypeIs(expectedType: KotlinType) {
|
||||||
if (expectedType != type) {
|
// TODO: compare IR types instead.
|
||||||
reportError(this, "unexpected expression.type: expected $expectedType, got ${type}")
|
if (expectedType != type.toKotlinType()) {
|
||||||
|
reportError(this, "unexpected expression.type: expected $expectedType, got ${type.toKotlinType()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,9 +156,9 @@ class CheckIrElementVisitor(val builtIns: KotlinBuiltIns, val reportError: Repor
|
|||||||
IrTypeOperator.IMPLICIT_CAST,
|
IrTypeOperator.IMPLICIT_CAST,
|
||||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
IrTypeOperator.IMPLICIT_NOTNULL,
|
||||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> typeOperand
|
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> typeOperand.toKotlinType()
|
||||||
|
|
||||||
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable()
|
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable().toKotlinType()
|
||||||
|
|
||||||
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> builtIns.booleanType
|
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> builtIns.booleanType
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||||
import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
|
import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
|
||||||
|
import org.jetbrains.kotlin.ir.util.DeepCopyTypeRemapper
|
||||||
import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
|
import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
|
||||||
@@ -41,8 +42,10 @@ fun <T : IrElement> T.deepCopyWithVariables(): T {
|
|||||||
val symbolsRemapper = DeepCopySymbolRemapper(descriptorsRemapper)
|
val symbolsRemapper = DeepCopySymbolRemapper(descriptorsRemapper)
|
||||||
acceptVoid(symbolsRemapper)
|
acceptVoid(symbolsRemapper)
|
||||||
|
|
||||||
|
val typesRemapper = DeepCopyTypeRemapper(symbolsRemapper)
|
||||||
|
|
||||||
return this.transform(
|
return this.transform(
|
||||||
object : DeepCopyIrTreeWithReturnableBlockSymbols(symbolsRemapper) {
|
object : DeepCopyIrTreeWithReturnableBlockSymbols(symbolsRemapper, typesRemapper) {
|
||||||
override fun getNonTransformedLoop(irLoop: IrLoop): IrLoop {
|
override fun getNonTransformedLoop(irLoop: IrLoop): IrLoop {
|
||||||
return irLoop
|
return irLoop
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -5,6 +5,7 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.renderer.*
|
import org.jetbrains.kotlin.renderer.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -285,7 +286,7 @@ class DumpIrTreeWithDescriptorsVisitor(out: Appendable): IrElementVisitor<Unit,
|
|||||||
for (typeParameter in expression.descriptor.original.typeParameters) {
|
for (typeParameter in expression.descriptor.original.typeParameters) {
|
||||||
val typeArgument = expression.getTypeArgument(typeParameter) ?: continue
|
val typeArgument = expression.getTypeArgument(typeParameter) ?: continue
|
||||||
val renderedParameter = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.render(typeParameter)
|
val renderedParameter = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.render(typeParameter)
|
||||||
val renderedType = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.renderType(typeArgument)
|
val renderedType = typeArgument.render()
|
||||||
printer.println("$renderedParameter: $renderedType")
|
printer.println("$renderedParameter: $renderedType")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
|
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolRemapper
|
import org.jetbrains.kotlin.ir.util.SymbolRemapper
|
||||||
|
import org.jetbrains.kotlin.ir.util.TypeRemapper
|
||||||
|
|
||||||
open class DeepCopyIrTreeWithReturnableBlockSymbols(
|
open class DeepCopyIrTreeWithReturnableBlockSymbols(
|
||||||
private val symbolRemapper: SymbolRemapper
|
symbolRemapper: SymbolRemapper,
|
||||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper) {
|
typeRemapper: TypeRemapper
|
||||||
|
) : DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) {
|
||||||
|
|
||||||
private inline fun <reified T : IrElement> T.transform() =
|
private inline fun <reified T : IrElement> T.transform() =
|
||||||
transform(this@DeepCopyIrTreeWithReturnableBlockSymbols, null) as T
|
transform(this@DeepCopyIrTreeWithReturnableBlockSymbols, null) as T
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.ir
|
package org.jetbrains.kotlin.backend.common.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
|
||||||
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
@@ -26,14 +25,12 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
||||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
|
|
||||||
|
|
||||||
@@ -77,75 +74,62 @@ fun FunctionDescriptor.createOverriddenDescriptor(owner: ClassDescriptor, final:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(
|
|
||||||
superConstructorDescriptor: ClassConstructorDescriptor,
|
|
||||||
isPrimary: Boolean = false
|
|
||||||
)
|
|
||||||
: ClassConstructorDescriptor {
|
|
||||||
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
|
||||||
/* containingDeclaration = */ this,
|
|
||||||
/* annotations = */ Annotations.EMPTY,
|
|
||||||
/* isPrimary = */ isPrimary,
|
|
||||||
/* source = */ SourceElement.NO_SOURCE
|
|
||||||
)
|
|
||||||
val valueParameters = superConstructorDescriptor.valueParameters.map {
|
|
||||||
it.copy(constructorDescriptor, it.name, it.index)
|
|
||||||
}
|
|
||||||
constructorDescriptor.initialize(valueParameters, superConstructorDescriptor.visibility)
|
|
||||||
constructorDescriptor.returnType = superConstructorDescriptor.returnType
|
|
||||||
return constructorDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrClass.addSimpleDelegatingConstructor(
|
fun IrClass.addSimpleDelegatingConstructor(
|
||||||
superConstructorSymbol: IrConstructorSymbol,
|
superConstructor: IrConstructor,
|
||||||
constructorDescriptor: ClassConstructorDescriptor,
|
irBuiltIns: IrBuiltIns,
|
||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin,
|
||||||
)
|
isPrimary: Boolean = false
|
||||||
: IrConstructor {
|
): IrConstructor {
|
||||||
|
val superConstructorDescriptor = superConstructor.descriptor
|
||||||
|
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||||
|
/* containingDeclaration = */ this.descriptor,
|
||||||
|
/* annotations = */ Annotations.EMPTY,
|
||||||
|
/* isPrimary = */ isPrimary,
|
||||||
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
|
)
|
||||||
|
val valueParameters = superConstructor.valueParameters.map {
|
||||||
|
val descriptor = it.descriptor as ValueParameterDescriptor
|
||||||
|
val newDescriptor = descriptor.copy(constructorDescriptor, descriptor.name, descriptor.index)
|
||||||
|
IrValueParameterImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
IrDeclarationOrigin.DEFINED,
|
||||||
|
newDescriptor,
|
||||||
|
it.type,
|
||||||
|
it.varargElementType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
constructorDescriptor.initialize(
|
||||||
|
valueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||||
|
superConstructorDescriptor.visibility
|
||||||
|
)
|
||||||
|
constructorDescriptor.returnType = superConstructorDescriptor.returnType
|
||||||
|
|
||||||
return IrConstructorImpl(startOffset, endOffset, origin, constructorDescriptor).also { constructor ->
|
return IrConstructorImpl(startOffset, endOffset, origin, constructorDescriptor).also { constructor ->
|
||||||
constructor.createParameterDeclarations()
|
|
||||||
|
assert(superConstructor.dispatchReceiverParameter == null) // Inner classes aren't supported.
|
||||||
|
|
||||||
|
constructor.valueParameters += valueParameters
|
||||||
|
constructor.returnType = this.defaultType
|
||||||
|
|
||||||
constructor.body = IrBlockBodyImpl(
|
constructor.body = IrBlockBodyImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
listOf(
|
listOf(
|
||||||
IrDelegatingConstructorCallImpl(
|
IrDelegatingConstructorCallImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset, irBuiltIns.unitType,
|
||||||
superConstructorSymbol, superConstructorSymbol.descriptor
|
superConstructor.symbol, superConstructor.descriptor
|
||||||
).apply {
|
).apply {
|
||||||
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
||||||
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.symbol))
|
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol)
|
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol, irBuiltIns.unitType)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
constructor.parent = this
|
constructor.parent = this
|
||||||
this.declarations.add(constructor)
|
this.declarations.add(constructor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CommonBackendContext.createArrayOfExpression(
|
|
||||||
arrayElementType: KotlinType,
|
|
||||||
arrayElements: List<IrExpression>,
|
|
||||||
startOffset: Int, endOffset: Int
|
|
||||||
): IrExpression {
|
|
||||||
|
|
||||||
val genericArrayOfFunSymbol = ir.symbols.arrayOf
|
|
||||||
val genericArrayOfFun = genericArrayOfFunSymbol.descriptor
|
|
||||||
val typeParameter0 = genericArrayOfFun.typeParameters[0]
|
|
||||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType)))
|
|
||||||
val substitutedArrayOfFun = genericArrayOfFun.substitute(typeSubstitutor)!!
|
|
||||||
|
|
||||||
val typeArguments = mapOf(typeParameter0 to arrayElementType)
|
|
||||||
|
|
||||||
val valueParameter0 = substitutedArrayOfFun.valueParameters[0]
|
|
||||||
val arg0VarargType = valueParameter0.type
|
|
||||||
val arg0VarargElementType = valueParameter0.varargElementType!!
|
|
||||||
val arg0 = IrVarargImpl(startOffset, endOffset, arg0VarargType, arg0VarargElementType, arrayElements)
|
|
||||||
|
|
||||||
return IrCallImpl(startOffset, endOffset, genericArrayOfFunSymbol, substitutedArrayOfFun, typeArguments).apply {
|
|
||||||
putValueArgument(0, arg0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+115
-103
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
|||||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
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.ClassConstructorDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||||
@@ -33,8 +32,8 @@ import org.jetbrains.kotlin.ir.builders.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
@@ -42,18 +41,13 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
|
||||||
|
|
||||||
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
||||||
DeclarationContainerLoweringPass {
|
DeclarationContainerLoweringPass {
|
||||||
@@ -82,34 +76,31 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
|||||||
log { "detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions" }
|
log { "detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions" }
|
||||||
functionDescriptor.overriddenDescriptors.forEach { context.log { "DEFAULT-REPLACER: $it" } }
|
functionDescriptor.overriddenDescriptors.forEach { context.log { "DEFAULT-REPLACER: $it" } }
|
||||||
if (bodies.isNotEmpty()) {
|
if (bodies.isNotEmpty()) {
|
||||||
val newIrFunction = functionDescriptor.generateDefaultsFunction(context)
|
val newIrFunction = irFunction.generateDefaultsFunction(context)
|
||||||
newIrFunction.parent = irFunction.parent
|
newIrFunction.parent = irFunction.parent
|
||||||
val descriptor = newIrFunction.descriptor
|
val descriptor = newIrFunction.descriptor
|
||||||
log { "$functionDescriptor -> $descriptor" }
|
log { "$functionDescriptor -> $descriptor" }
|
||||||
val builder = context.createIrBuilder(newIrFunction.symbol)
|
val builder = context.createIrBuilder(newIrFunction.symbol)
|
||||||
newIrFunction.body = builder.irBlockBody(newIrFunction) {
|
newIrFunction.body = builder.irBlockBody(newIrFunction) {
|
||||||
val params = mutableListOf<IrVariableSymbol>()
|
val params = mutableListOf<IrVariable>()
|
||||||
val variables = mutableMapOf<ValueDescriptor, IrValueSymbol>()
|
val variables = mutableMapOf<ValueDescriptor, IrValueDeclaration>()
|
||||||
|
|
||||||
irFunction.dispatchReceiverParameter?.let {
|
irFunction.dispatchReceiverParameter?.let {
|
||||||
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!.symbol
|
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor.extensionReceiverParameter != null) {
|
if (descriptor.extensionReceiverParameter != null) {
|
||||||
variables[functionDescriptor.extensionReceiverParameter!!] =
|
variables[functionDescriptor.extensionReceiverParameter!!] =
|
||||||
newIrFunction.extensionReceiverParameter!!.symbol
|
newIrFunction.extensionReceiverParameter!!
|
||||||
}
|
}
|
||||||
|
|
||||||
for (valueParameter in functionDescriptor.valueParameters) {
|
for (valueParameter in functionDescriptor.valueParameters) {
|
||||||
val parameterSymbol = newIrFunction.valueParameters[valueParameter.index].symbol
|
val parameter = newIrFunction.valueParameters[valueParameter.index]
|
||||||
val temporaryVariableSymbol =
|
|
||||||
IrVariableSymbolImpl(scope.createTemporaryVariableDescriptor(parameterSymbol.descriptor))
|
val argument = if (valueParameter.hasDefaultValue()) {
|
||||||
params.add(temporaryVariableSymbol)
|
val kIntAnd = symbols.intAnd.owner
|
||||||
variables.put(valueParameter, temporaryVariableSymbol)
|
|
||||||
if (valueParameter.hasDefaultValue()) {
|
|
||||||
val kIntAnd = symbols.intAnd
|
|
||||||
val condition = irNotEquals(irCall(kIntAnd).apply {
|
val condition = irNotEquals(irCall(kIntAnd).apply {
|
||||||
dispatchReceiver = irGet(maskParameterSymbol(newIrFunction, valueParameter.index / 32))
|
dispatchReceiver = irGet(maskParameter(newIrFunction, valueParameter.index / 32))
|
||||||
putValueArgument(0, irInt(1 shl (valueParameter.index % 32)))
|
putValueArgument(0, irInt(1 shl (valueParameter.index % 32)))
|
||||||
}, irInt(0))
|
}, irInt(0))
|
||||||
val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
|
val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
|
||||||
@@ -122,41 +113,40 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
|||||||
return irGet(valueSymbol)
|
return irGet(valueSymbol)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
val variableInitialization = irIfThenElse(
|
irIfThenElse(
|
||||||
type = temporaryVariableSymbol.descriptor.type,
|
type = parameter.type,
|
||||||
condition = condition,
|
condition = condition,
|
||||||
thenPart = expressionBody.expression,
|
thenPart = expressionBody.expression,
|
||||||
elsePart = irGet(parameterSymbol)
|
elsePart = irGet(parameter)
|
||||||
)
|
|
||||||
+scope.createTemporaryVariable(
|
|
||||||
symbol = temporaryVariableSymbol,
|
|
||||||
initializer = variableInitialization
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Mapping calculated values with its origin variables. */
|
/* Mapping calculated values with its origin variables. */
|
||||||
} else {
|
} else {
|
||||||
+scope.createTemporaryVariable(
|
irGet(parameter)
|
||||||
symbol = temporaryVariableSymbol,
|
|
||||||
initializer = irGet(parameterSymbol)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
val temporaryVariable = irTemporary(argument, nameHint = parameter.name.asString())
|
||||||
|
|
||||||
|
params.add(temporaryVariable)
|
||||||
|
variables.put(valueParameter, temporaryVariable)
|
||||||
}
|
}
|
||||||
if (irFunction is IrConstructor) {
|
if (irFunction is IrConstructor) {
|
||||||
+IrDelegatingConstructorCallImpl(
|
+IrDelegatingConstructorCallImpl(
|
||||||
startOffset = irFunction.startOffset,
|
startOffset = irFunction.startOffset,
|
||||||
endOffset = irFunction.endOffset,
|
endOffset = irFunction.endOffset,
|
||||||
|
type = context.irBuiltIns.unitType,
|
||||||
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor
|
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor
|
||||||
).apply {
|
).apply {
|
||||||
params.forEachIndexed { i, variable ->
|
params.forEachIndexed { i, variable ->
|
||||||
putValueArgument(i, irGet(variable))
|
putValueArgument(i, irGet(variable))
|
||||||
}
|
}
|
||||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!.symbol)
|
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
+irReturn(irCall(irFunction.symbol).apply {
|
+irReturn(irCall(irFunction).apply {
|
||||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!.symbol)
|
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
|
||||||
}
|
}
|
||||||
if (functionDescriptor.extensionReceiverParameter != null) {
|
if (functionDescriptor.extensionReceiverParameter != null) {
|
||||||
extensionReceiver = irGet(variables[functionDescriptor.extensionReceiverParameter!!]!!)
|
extensionReceiver = irGet(variables[functionDescriptor.extensionReceiverParameter!!]!!)
|
||||||
@@ -181,50 +171,29 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
|||||||
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
|
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Scope.createTemporaryVariableDescriptor(parameterDescriptor: ParameterDescriptor?): VariableDescriptor =
|
|
||||||
IrTemporaryVariableDescriptorImpl(
|
|
||||||
containingDeclaration = this.scopeOwner,
|
|
||||||
name = parameterDescriptor!!.name.asString().synthesizedName,
|
|
||||||
outType = parameterDescriptor.type,
|
|
||||||
isMutable = false
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun Scope.createTemporaryVariable(symbol: IrVariableSymbol, initializer: IrExpression) =
|
|
||||||
IrVariableImpl(
|
|
||||||
startOffset = initializer.startOffset,
|
|
||||||
endOffset = initializer.endOffset,
|
|
||||||
origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
|
||||||
symbol = symbol
|
|
||||||
).apply {
|
|
||||||
|
|
||||||
this.initializer = initializer
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParameter: ValueParameterDescriptor): IrExpressionBody {
|
private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParameter: ValueParameterDescriptor): IrExpressionBody {
|
||||||
return irFunction.getDefault(valueParameter) ?: TODO("FIXME!!!")
|
return irFunction.getDefault(valueParameter) ?: TODO("FIXME!!!")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun maskParameterDescriptor(function: IrFunction, number: Int) =
|
private fun maskParameterDescriptor(function: IrFunction, number: Int) =
|
||||||
maskParameterSymbol(function, number).descriptor as ValueParameterDescriptor
|
maskParameter(function, number).descriptor as ValueParameterDescriptor
|
||||||
|
|
||||||
private fun maskParameterSymbol(function: IrFunction, number: Int) =
|
private fun maskParameter(function: IrFunction, number: Int) =
|
||||||
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }.symbol
|
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }
|
||||||
|
|
||||||
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) =
|
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) =
|
||||||
descriptor.valueParameters.single { it.name == kConstructorMarkerName }
|
descriptor.valueParameters.single { it.name == kConstructorMarkerName }
|
||||||
|
|
||||||
private fun nullConst(expression: IrElement, type: KotlinType): IrExpression? {
|
private fun nullConst(expression: IrElement, type: IrType, context: CommonBackendContext) = when {
|
||||||
when {
|
type.isFloat() -> IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
|
||||||
KotlinBuiltIns.isFloat(type) -> return IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
|
type.isDouble() -> IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
|
||||||
KotlinBuiltIns.isDouble(type) -> return IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
|
type.isBoolean() -> IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
|
||||||
KotlinBuiltIns.isBoolean(type) -> return IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
|
type.isByte() -> IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
|
||||||
KotlinBuiltIns.isByte(type) -> return IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
|
type.isChar() -> IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
|
||||||
KotlinBuiltIns.isChar(type) -> return IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
|
type.isShort() -> IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
|
||||||
KotlinBuiltIns.isShort(type) -> return IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
|
type.isInt() -> IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
|
||||||
KotlinBuiltIns.isInt(type) -> return IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
|
type.isLong() -> IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
|
||||||
KotlinBuiltIns.isLong(type) -> return IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
|
else -> IrConstImpl.constNull(expression.startOffset, expression.endOffset, context.irBuiltIns.nothingNType)
|
||||||
else -> return IrConstImpl.constNull(expression.startOffset, expression.endOffset, type.builtIns.nullableNothingType)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultParameterInjector constructor(val context: CommonBackendContext, private val skipInline: Boolean = true) : BodyLoweringPass {
|
class DefaultParameterInjector constructor(val context: CommonBackendContext, private val skipInline: Boolean = true) : BodyLoweringPass {
|
||||||
@@ -240,10 +209,12 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
|||||||
if (argumentsCount == descriptor.valueParameters.size)
|
if (argumentsCount == descriptor.valueParameters.size)
|
||||||
return expression
|
return expression
|
||||||
val (symbolForCall, params) = parametersForCall(expression)
|
val (symbolForCall, params) = parametersForCall(expression)
|
||||||
|
symbolForCall as IrConstructorSymbol
|
||||||
return IrDelegatingConstructorCallImpl(
|
return IrDelegatingConstructorCallImpl(
|
||||||
startOffset = expression.startOffset,
|
startOffset = expression.startOffset,
|
||||||
endOffset = expression.endOffset,
|
endOffset = expression.endOffset,
|
||||||
symbol = symbolForCall as IrConstructorSymbol,
|
type = context.irBuiltIns.unitType,
|
||||||
|
symbol = symbolForCall,
|
||||||
descriptor = symbolForCall.descriptor
|
descriptor = symbolForCall.descriptor
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
@@ -273,13 +244,14 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
|||||||
return IrCallImpl(
|
return IrCallImpl(
|
||||||
startOffset = expression.startOffset,
|
startOffset = expression.startOffset,
|
||||||
endOffset = expression.endOffset,
|
endOffset = expression.endOffset,
|
||||||
|
type = symbol.owner.returnType,
|
||||||
symbol = symbol,
|
symbol = symbol,
|
||||||
descriptor = descriptor,
|
descriptor = descriptor,
|
||||||
typeArguments = expression.descriptor.typeParameters.map {
|
typeArgumentsCount = expression.typeArgumentsCount
|
||||||
it to (expression.getTypeArgument(it) ?: it.defaultType)
|
|
||||||
}.toMap()
|
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
|
this.copyTypeArgumentsFrom(expression)
|
||||||
|
|
||||||
params.forEach {
|
params.forEach {
|
||||||
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
|
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
|
||||||
putValueArgument(it.first.index, it.second)
|
putValueArgument(it.first.index, it.second)
|
||||||
@@ -310,8 +282,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
|||||||
private fun parametersForCall(expression: IrFunctionAccessExpression): Pair<IrFunctionSymbol, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
|
private fun parametersForCall(expression: IrFunctionAccessExpression): Pair<IrFunctionSymbol, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
|
||||||
val descriptor = expression.descriptor
|
val descriptor = expression.descriptor
|
||||||
val keyFunction = expression.symbol.owner.findSuperMethodWithDefaultArguments()!!
|
val keyFunction = expression.symbol.owner.findSuperMethodWithDefaultArguments()!!
|
||||||
val keyDescriptor = keyFunction.descriptor
|
val realFunction = keyFunction.generateDefaultsFunction(context)
|
||||||
val realFunction = keyDescriptor.generateDefaultsFunction(context)
|
|
||||||
realFunction.parent = keyFunction.parent
|
realFunction.parent = keyFunction.parent
|
||||||
val realDescriptor = realFunction.descriptor
|
val realDescriptor = realFunction.descriptor
|
||||||
|
|
||||||
@@ -325,15 +296,18 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
|||||||
maskValues[maskIndex] = maskValues[maskIndex] or (1 shl (i % 32))
|
maskValues[maskIndex] = maskValues[maskIndex] or (1 shl (i % 32))
|
||||||
}
|
}
|
||||||
val valueParameterDescriptor = realDescriptor.valueParameters[i]
|
val valueParameterDescriptor = realDescriptor.valueParameters[i]
|
||||||
val defaultValueArgument =
|
val defaultValueArgument = if (valueParameterDescriptor.isVararg) {
|
||||||
if (valueParameterDescriptor.isVararg) null else nullConst(expression, valueParameterDescriptor.type)
|
null
|
||||||
|
} else {
|
||||||
|
nullConst(expression, realFunction.valueParameters[i].type, context)
|
||||||
|
}
|
||||||
valueParameterDescriptor to (valueArgument ?: defaultValueArgument)
|
valueParameterDescriptor to (valueArgument ?: defaultValueArgument)
|
||||||
})
|
})
|
||||||
maskValues.forEachIndexed { i, maskValue ->
|
maskValues.forEachIndexed { i, maskValue ->
|
||||||
params += maskParameterDescriptor(realFunction, i) to IrConstImpl.int(
|
params += maskParameterDescriptor(realFunction, i) to IrConstImpl.int(
|
||||||
startOffset = irBody.startOffset,
|
startOffset = irBody.startOffset,
|
||||||
endOffset = irBody.endOffset,
|
endOffset = irBody.endOffset,
|
||||||
type = descriptor.builtIns.intType,
|
type = context.irBuiltIns.intType,
|
||||||
value = maskValue
|
value = maskValue
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -347,7 +321,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
|||||||
)
|
)
|
||||||
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
|
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
|
||||||
params += realDescriptor.valueParameters.last() to
|
params += realDescriptor.valueParameters.last() to
|
||||||
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.builtIns.any.defaultType)
|
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.irBuiltIns.anyType)
|
||||||
}
|
}
|
||||||
params.forEach {
|
params.forEach {
|
||||||
log { "descriptor::${realDescriptor.name.asString()}#${it.first.index}: ${it.first.name.asString()}" }
|
log { "descriptor::${realDescriptor.name.asString()}#${it.first.index}: ${it.first.name.asString()}" }
|
||||||
@@ -366,7 +340,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
|||||||
private fun CallableMemberDescriptor.needsDefaultArgumentsLowering(skipInlineMethods: Boolean) =
|
private fun CallableMemberDescriptor.needsDefaultArgumentsLowering(skipInlineMethods: Boolean) =
|
||||||
valueParameters.any { it.hasDefaultValue() } && !(this is FunctionDescriptor && isInline && skipInlineMethods)
|
valueParameters.any { it.hasDefaultValue() } && !(this is FunctionDescriptor && isInline && skipInlineMethods)
|
||||||
|
|
||||||
private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendContext): IrFunction {
|
private fun IrFunction.generateDefaultsFunction(context: CommonBackendContext): IrFunction = with(this.descriptor) {
|
||||||
return context.ir.defaultParameterDeclarationsCache.getOrPut(this) {
|
return context.ir.defaultParameterDeclarationsCache.getOrPut(this) {
|
||||||
val descriptor = when (this) {
|
val descriptor = when (this) {
|
||||||
is ClassConstructorDescriptor ->
|
is ClassConstructorDescriptor ->
|
||||||
@@ -389,8 +363,10 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val function = this@generateDefaultsFunction
|
||||||
|
|
||||||
val syntheticParameters = MutableList((valueParameters.size + 31) / 32) { i ->
|
val syntheticParameters = MutableList((valueParameters.size + 31) / 32) { i ->
|
||||||
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), descriptor.builtIns.intType)
|
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), context.irBuiltIns.intType)
|
||||||
}
|
}
|
||||||
if (this is ClassConstructorDescriptor) {
|
if (this is ClassConstructorDescriptor) {
|
||||||
syntheticParameters += valueParameter(
|
syntheticParameters += valueParameter(
|
||||||
@@ -402,10 +378,29 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
|||||||
syntheticParameters += valueParameter(
|
syntheticParameters += valueParameter(
|
||||||
descriptor, syntheticParameters.last().index + 1,
|
descriptor, syntheticParameters.last().index + 1,
|
||||||
"handler".synthesizedName,
|
"handler".synthesizedName,
|
||||||
context.ir.symbols.any.owner.defaultType
|
context.irBuiltIns.anyType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val newValueParameters = function.valueParameters.map {
|
||||||
|
val parameterDescriptor = ValueParameterDescriptorImpl(
|
||||||
|
containingDeclaration = descriptor,
|
||||||
|
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
|
||||||
|
index = it.index,
|
||||||
|
annotations = it.descriptor.annotations,
|
||||||
|
name = it.name,
|
||||||
|
outType = it.descriptor.type,
|
||||||
|
declaresDefaultValue = false,
|
||||||
|
isCrossinline = it.isCrossinline,
|
||||||
|
isNoinline = it.isNoinline,
|
||||||
|
varargElementType = (it.descriptor as ValueParameterDescriptor).varargElementType,
|
||||||
|
source = it.descriptor.source
|
||||||
|
)
|
||||||
|
|
||||||
|
it.copy(parameterDescriptor)
|
||||||
|
|
||||||
|
} + syntheticParameters
|
||||||
|
|
||||||
descriptor.initialize(
|
descriptor.initialize(
|
||||||
/* receiverParameterType = */ extensionReceiverParameter?.type,
|
/* receiverParameterType = */ extensionReceiverParameter?.type,
|
||||||
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
|
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
|
||||||
@@ -425,24 +420,11 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
|||||||
setInitialized()
|
setInitialized()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* unsubstitutedValueParameters = */ valueParameters.map {
|
/* unsubstitutedValueParameters = */ newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||||
ValueParameterDescriptorImpl(
|
|
||||||
containingDeclaration = descriptor,
|
|
||||||
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
|
|
||||||
index = it.index,
|
|
||||||
annotations = it.annotations,
|
|
||||||
name = it.name,
|
|
||||||
outType = it.type,
|
|
||||||
declaresDefaultValue = false,
|
|
||||||
isCrossinline = it.isCrossinline,
|
|
||||||
isNoinline = it.isNoinline,
|
|
||||||
varargElementType = it.varargElementType,
|
|
||||||
source = it.source
|
|
||||||
)
|
|
||||||
} + syntheticParameters,
|
|
||||||
/* unsubstitutedReturnType = */ returnType,
|
/* unsubstitutedReturnType = */ returnType,
|
||||||
/* modality = */ Modality.FINAL,
|
/* modality = */ Modality.FINAL,
|
||||||
/* visibility = */ this.visibility)
|
/* visibility = */ this.visibility
|
||||||
|
)
|
||||||
descriptor.isSuspend = this.isSuspend
|
descriptor.isSuspend = this.isSuspend
|
||||||
context.log { "adds to cache[$this] = $descriptor" }
|
context.log { "adds to cache[$this] = $descriptor" }
|
||||||
|
|
||||||
@@ -463,7 +445,29 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.createParameterDeclarations()
|
result.returnType = function.returnType
|
||||||
|
|
||||||
|
function.typeParameters.mapTo(result.typeParameters) {
|
||||||
|
assert(function.descriptor.typeParameters[it.index] == it.descriptor)
|
||||||
|
IrTypeParameterImpl(
|
||||||
|
startOffset, endOffset, origin, descriptor.typeParameters[it.index]
|
||||||
|
).apply { this.superTypes += it.superTypes }
|
||||||
|
}
|
||||||
|
result.parent = function.parent
|
||||||
|
result.createDispatchReceiverParameter()
|
||||||
|
|
||||||
|
function.extensionReceiverParameter?.let {
|
||||||
|
result.extensionReceiverParameter = IrValueParameterImpl(
|
||||||
|
it.startOffset,
|
||||||
|
it.endOffset,
|
||||||
|
it.origin,
|
||||||
|
descriptor.extensionReceiverParameter!!,
|
||||||
|
it.type,
|
||||||
|
it.varargElementType
|
||||||
|
).apply { parent = result }
|
||||||
|
}
|
||||||
|
|
||||||
|
result.valueParameters += newValueParameters.also { it.forEach { it.parent = result } }
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@@ -472,20 +476,28 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
|||||||
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
|
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
|
||||||
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
|
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
|
||||||
|
|
||||||
private fun valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: KotlinType): ValueParameterDescriptor {
|
private fun IrFunction.valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: IrType): IrValueParameter {
|
||||||
return ValueParameterDescriptorImpl(
|
val parameterDescriptor = ValueParameterDescriptorImpl(
|
||||||
containingDeclaration = descriptor,
|
containingDeclaration = descriptor,
|
||||||
original = null,
|
original = null,
|
||||||
index = index,
|
index = index,
|
||||||
annotations = Annotations.EMPTY,
|
annotations = Annotations.EMPTY,
|
||||||
name = name,
|
name = name,
|
||||||
outType = type,
|
outType = type.toKotlinType(),
|
||||||
declaresDefaultValue = false,
|
declaresDefaultValue = false,
|
||||||
isCrossinline = false,
|
isCrossinline = false,
|
||||||
isNoinline = false,
|
isNoinline = false,
|
||||||
varargElementType = null,
|
varargElementType = null,
|
||||||
source = SourceElement.NO_SOURCE
|
source = SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
|
return IrValueParameterImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
IrDeclarationOrigin.DEFINED,
|
||||||
|
parameterDescriptor,
|
||||||
|
type,
|
||||||
|
null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val kConstructorMarkerName = "marker".synthesizedName
|
internal val kConstructorMarkerName = "marker".synthesizedName
|
||||||
|
|||||||
+3
-2
@@ -68,7 +68,7 @@ class InitializersLowering(
|
|||||||
if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField
|
if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField
|
||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
|
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
|
||||||
irClass.thisReceiver!!.symbol
|
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
|
||||||
)
|
)
|
||||||
else null
|
else null
|
||||||
val irSetField = IrSetFieldImpl(
|
val irSetField = IrSetFieldImpl(
|
||||||
@@ -76,6 +76,7 @@ class InitializersLowering(
|
|||||||
declaration.symbol,
|
declaration.symbol,
|
||||||
receiver,
|
receiver,
|
||||||
irFieldInitializer,
|
irFieldInitializer,
|
||||||
|
context.irBuiltIns.unitType,
|
||||||
null, null
|
null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ class InitializersLowering(
|
|||||||
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
|
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
|
||||||
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
|
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
|
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
|
||||||
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.builtIns.unitType, null,
|
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null,
|
||||||
instanceInitializerStatements.map { it.copy(irClass) })
|
instanceInitializerStatements.map { it.copy(irClass) })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
+1
-171
@@ -16,26 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
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.*
|
|
||||||
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.symbols.IrFieldSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
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.name.Name
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
|
|
||||||
abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
||||||
|
|
||||||
@@ -62,155 +44,3 @@ abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
|||||||
return builtIr
|
return builtIr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
|
||||||
fieldSymbol: IrFieldSymbol, type: KotlinType)
|
|
||||||
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
|
||||||
|
|
||||||
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
|
||||||
PropertyGetterDescriptorImpl(
|
|
||||||
/* correspondingProperty = */ fieldSymbol.descriptor,
|
|
||||||
/* 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() {
|
|
||||||
val descriptor = symbol.descriptor as PropertyGetterDescriptorImpl
|
|
||||||
descriptor.apply {
|
|
||||||
initialize(type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun buildIr() = IrFunctionImpl(
|
|
||||||
startOffset = startOffset,
|
|
||||||
endOffset = endOffset,
|
|
||||||
origin = origin,
|
|
||||||
symbol = symbol).apply {
|
|
||||||
|
|
||||||
createParameterDeclarations()
|
|
||||||
|
|
||||||
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
|
||||||
+irReturn(irGetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
|
||||||
fieldSymbol: IrFieldSymbol, type: KotlinType)
|
|
||||||
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
|
||||||
|
|
||||||
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
|
||||||
PropertySetterDescriptorImpl(
|
|
||||||
/* correspondingProperty = */ fieldSymbol.descriptor,
|
|
||||||
/* 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() {
|
|
||||||
val descriptor = symbol.descriptor as PropertySetterDescriptorImpl
|
|
||||||
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,
|
|
||||||
symbol = symbol).apply {
|
|
||||||
|
|
||||||
createParameterDeclarations()
|
|
||||||
|
|
||||||
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
|
||||||
+irSetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol, irGet(this@apply.valueParameters.single().symbol))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
|
||||||
owner: ClassDescriptor, name: Name, type: KotlinType, isMutable: Boolean)
|
|
||||||
= object: SymbolWithIrBuilder<IrFieldSymbol, IrProperty>() {
|
|
||||||
|
|
||||||
private lateinit var getterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>
|
|
||||||
private var setterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>? = null
|
|
||||||
|
|
||||||
override fun buildSymbol() = IrFieldSymbolImpl(
|
|
||||||
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,
|
|
||||||
/* isExpect = */ false,
|
|
||||||
/* isActual = */ false,
|
|
||||||
/* isExternal = */ false,
|
|
||||||
/* isDelegated = */ false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun doInitialize() {
|
|
||||||
val descriptor = symbol.descriptor as PropertyDescriptorImpl
|
|
||||||
getterBuilder = createPropertyGetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
|
|
||||||
if (isMutable)
|
|
||||||
setterBuilder = createPropertySetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
|
|
||||||
descriptor.initialize(
|
|
||||||
/* getter = */ getterBuilder.symbol.descriptor as PropertyGetterDescriptorImpl,
|
|
||||||
/* setter = */ setterBuilder?.symbol?.descriptor as? PropertySetterDescriptorImpl)
|
|
||||||
val receiverType: KotlinType? = null
|
|
||||||
descriptor.setType(type, emptyList(), owner.thisAsReceiverParameter, receiverType)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun buildIr(): IrProperty {
|
|
||||||
val backingField = IrFieldImpl(
|
|
||||||
startOffset = startOffset,
|
|
||||||
endOffset = endOffset,
|
|
||||||
origin = origin,
|
|
||||||
symbol = symbol)
|
|
||||||
return IrPropertyImpl(
|
|
||||||
startOffset = startOffset,
|
|
||||||
endOffset = endOffset,
|
|
||||||
origin = origin,
|
|
||||||
isDelegated = false,
|
|
||||||
descriptor = symbol.descriptor,
|
|
||||||
backingField = backingField,
|
|
||||||
getter = getterBuilder.ir,
|
|
||||||
setter = setterBuilder?.ir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-2
@@ -58,7 +58,7 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
|||||||
|
|
||||||
return lower.context.createIrBuilder(expression.symbol, expression.startOffset, expression.endOffset).run {
|
return lower.context.createIrBuilder(expression.symbol, expression.startOffset, expression.endOffset).run {
|
||||||
|
|
||||||
IrCompositeImpl(startOffset, endOffset, context.builtIns.stringType).apply {
|
IrCompositeImpl(startOffset, endOffset, context.irBuiltIns.stringType).apply {
|
||||||
receiver?.let {
|
receiver?.let {
|
||||||
//put receiver for bound callable reference
|
//put receiver for bound callable reference
|
||||||
statements.add(it)
|
statements.add(it)
|
||||||
@@ -68,7 +68,7 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
|||||||
IrConstImpl.string(
|
IrConstImpl.string(
|
||||||
expression.startOffset,
|
expression.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
context.builtIns.stringType,
|
context.irBuiltIns.stringType,
|
||||||
callableReference.descriptor.name.asString()
|
callableReference.descriptor.name.asString()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
+10
-8
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.ir.expressions.IrBlock
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -45,20 +47,20 @@ class LateinitLowering(
|
|||||||
|
|
||||||
private fun transformGetter(backingField: IrField, getter: IrFunction) {
|
private fun transformGetter(backingField: IrField, getter: IrFunction) {
|
||||||
val type = backingField.type
|
val type = backingField.type
|
||||||
assert(!KotlinBuiltIns.isPrimitiveType(type)) { "'lateinit' modifier is not allowed on primitive types" }
|
assert(!type.isPrimitiveType()) { "'lateinit' modifier is not allowed on primitive types" }
|
||||||
val startOffset = getter.startOffset
|
val startOffset = getter.startOffset
|
||||||
val endOffset = getter.endOffset
|
val endOffset = getter.endOffset
|
||||||
val irBuilder = context.createIrBuilder(getter.symbol, startOffset, endOffset)
|
val irBuilder = context.createIrBuilder(getter.symbol, startOffset, endOffset)
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
val block = irBlock(type)
|
val block = irBlock(type)
|
||||||
val resultVar = scope.createTemporaryVariable(
|
val resultVar = scope.createTemporaryVariable(
|
||||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it.symbol) }, backingField.symbol)
|
irGetField(getter.dispatchReceiverParameter?.let { irGet(it) }, backingField)
|
||||||
)
|
)
|
||||||
block.statements.add(resultVar)
|
block.statements.add(resultVar)
|
||||||
val throwIfNull = irIfThenElse(
|
val throwIfNull = irIfThenElse(
|
||||||
context.builtIns.nothingType,
|
context.irBuiltIns.nothingType,
|
||||||
irNotEquals(irGet(resultVar.symbol), irNull()),
|
irNotEquals(irGet(resultVar), irNull()),
|
||||||
irReturn(irGet(resultVar.symbol)),
|
irReturn(irGet(resultVar)),
|
||||||
throwUninitializedPropertyAccessException(backingField)
|
throwUninitializedPropertyAccessException(backingField)
|
||||||
)
|
)
|
||||||
block.statements.add(throwIfNull)
|
block.statements.add(throwIfNull)
|
||||||
@@ -76,15 +78,15 @@ class LateinitLowering(
|
|||||||
IrConstImpl.string(
|
IrConstImpl.string(
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET,
|
||||||
context.builtIns.stringType,
|
context.irBuiltIns.stringType,
|
||||||
backingField.name.asString()
|
backingField.name.asString()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val throwErrorFunction = context.ir.symbols.ThrowUninitializedPropertyAccessException
|
private val throwErrorFunction = context.ir.symbols.ThrowUninitializedPropertyAccessException.owner
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irBlock(type: KotlinType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
private fun IrBuilderWithScope.irBlock(type: IrType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||||
|
|
||||||
}
|
}
|
||||||
+115
-70
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.ir.visitors.*
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
|
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
interface LocalNameProvider {
|
interface LocalNameProvider {
|
||||||
@@ -98,12 +97,12 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
abstract val transformedDescriptor: FunctionDescriptor
|
abstract val transformedDescriptor: FunctionDescriptor
|
||||||
abstract val transformedDeclaration: IrFunction
|
abstract val transformedDeclaration: IrFunction
|
||||||
|
|
||||||
val capturedValueToParameter: MutableMap<ValueDescriptor, IrValueParameterSymbol> = HashMap()
|
val capturedValueToParameter: MutableMap<ValueDescriptor, IrValueParameter> = HashMap()
|
||||||
|
|
||||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||||
val newSymbol = capturedValueToParameter[descriptor] ?: return null
|
val parameter = capturedValueToParameter[descriptor] ?: return null
|
||||||
|
|
||||||
return IrGetValueImpl(startOffset, endOffset, newSymbol)
|
return IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,9 +140,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||||
val field = capturedValueToField[descriptor] ?: return null
|
val field = capturedValueToField[descriptor] ?: return null
|
||||||
|
|
||||||
|
val receiver = declaration.thisReceiver!!
|
||||||
return IrGetFieldImpl(
|
return IrGetFieldImpl(
|
||||||
startOffset, endOffset, field.symbol,
|
startOffset, endOffset, field.symbol, field.type,
|
||||||
receiver = IrGetValueImpl(startOffset, endOffset, declaration.thisReceiver!!.symbol)
|
receiver = IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,9 +155,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||||
val field = classContext.capturedValueToField[descriptor] ?: return null
|
val field = classContext.capturedValueToField[descriptor] ?: return null
|
||||||
|
|
||||||
|
val receiver = member.dispatchReceiverParameter!!
|
||||||
return IrGetFieldImpl(
|
return IrGetFieldImpl(
|
||||||
startOffset, endOffset, field.symbol,
|
startOffset, endOffset, field.symbol, field.type,
|
||||||
receiver = IrGetValueImpl(startOffset, endOffset, member.dispatchReceiverParameter!!.symbol)
|
receiver = IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,12 +169,12 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
val localClasses: MutableMap<ClassDescriptor, LocalClassContext> = LinkedHashMap()
|
val localClasses: MutableMap<ClassDescriptor, LocalClassContext> = LinkedHashMap()
|
||||||
val localClassConstructors: MutableMap<ClassConstructorDescriptor, LocalClassConstructorContext> = LinkedHashMap()
|
val localClassConstructors: MutableMap<ClassConstructorDescriptor, LocalClassConstructorContext> = LinkedHashMap()
|
||||||
|
|
||||||
val transformedDeclarations = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
val transformedDeclarations = mutableMapOf<DeclarationDescriptor, IrDeclaration>()
|
||||||
|
|
||||||
val FunctionDescriptor.transformed: IrFunctionSymbol?
|
val FunctionDescriptor.transformed: IrFunction?
|
||||||
get() = transformedDeclarations[this] as IrFunctionSymbol?
|
get() = transformedDeclarations[this] as IrFunction?
|
||||||
|
|
||||||
val oldParameterToNew: MutableMap<ParameterDescriptor, IrValueParameterSymbol> = HashMap()
|
val oldParameterToNew: MutableMap<ParameterDescriptor, IrValueParameter> = HashMap()
|
||||||
val newParameterToOld: MutableMap<ParameterDescriptor, ParameterDescriptor> = HashMap()
|
val newParameterToOld: MutableMap<ParameterDescriptor, ParameterDescriptor> = HashMap()
|
||||||
val newParameterToCaptured: MutableMap<ValueParameterDescriptor, IrValueSymbol> = HashMap()
|
val newParameterToCaptured: MutableMap<ValueParameterDescriptor, IrValueSymbol> = HashMap()
|
||||||
|
|
||||||
@@ -200,7 +201,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
|
|
||||||
original.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
original.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
||||||
val body = original.getDefault(argument)!!
|
val body = original.getDefault(argument)!!
|
||||||
oldParameterToNew[argument]!!.owner.defaultValue = body
|
oldParameterToNew[argument]!!.defaultValue = body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +219,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
override fun visitClass(declaration: IrClass): IrStatement {
|
override fun visitClass(declaration: IrClass): IrStatement {
|
||||||
if (declaration.descriptor in localClasses) {
|
if (declaration.descriptor in localClasses) {
|
||||||
// Replace local class definition with an empty composite.
|
// Replace local class definition with an empty composite.
|
||||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType)
|
||||||
} else {
|
} else {
|
||||||
return super.visitClass(declaration)
|
return super.visitClass(declaration)
|
||||||
}
|
}
|
||||||
@@ -227,7 +228,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||||
if (declaration.descriptor in localFunctions) {
|
if (declaration.descriptor in localFunctions) {
|
||||||
// Replace local function definition with an empty composite.
|
// Replace local function definition with an empty composite.
|
||||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType)
|
||||||
} else {
|
} else {
|
||||||
if (localContext is LocalClassContext && declaration.parent == localContext.declaration) {
|
if (localContext is LocalClassContext && declaration.parent == localContext.declaration) {
|
||||||
return declaration.apply {
|
return declaration.apply {
|
||||||
@@ -250,7 +251,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
|
|
||||||
declaration.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
declaration.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
||||||
val body = declaration.getDefault(argument)!!
|
val body = declaration.getDefault(argument)!!
|
||||||
oldParameterToNew[argument]!!.owner.defaultValue = body
|
oldParameterToNew[argument]!!.defaultValue = body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -266,7 +267,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
}
|
}
|
||||||
|
|
||||||
oldParameterToNew[descriptor]?.let {
|
oldParameterToNew[descriptor]?.let {
|
||||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, it)
|
return IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
@@ -287,14 +288,17 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
val oldCallee = expression.descriptor.original
|
val oldCallee = expression.descriptor.original
|
||||||
val newCallee = transformedDeclarations[oldCallee] as IrConstructorSymbol? ?: return expression
|
val newCallee = transformedDeclarations[oldCallee] as IrConstructor? ?: return expression
|
||||||
|
|
||||||
return IrDelegatingConstructorCallImpl(
|
return IrDelegatingConstructorCallImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
newCallee,
|
context.irBuiltIns.unitType,
|
||||||
newCallee.descriptor,
|
newCallee.symbol,
|
||||||
remapTypeArguments(expression, newCallee.descriptor)
|
newCallee.descriptor
|
||||||
).fillArguments(expression)
|
).also {
|
||||||
|
it.fillArguments(expression)
|
||||||
|
it.copyTypeArgumentsFrom(expression)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : IrMemberAccessExpression> T.fillArguments(oldExpression: IrMemberAccessExpression): T {
|
private fun <T : IrMemberAccessExpression> T.fillArguments(oldExpression: IrMemberAccessExpression): T {
|
||||||
@@ -310,16 +314,17 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
newParameterToCaptured[newValueParameterDescriptor]
|
newParameterToCaptured[newValueParameterDescriptor]
|
||||||
?: throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
?: throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
||||||
|
|
||||||
|
val capturedValue = capturedValueSymbol.owner
|
||||||
|
|
||||||
val capturedValueDescriptor = capturedValueSymbol.descriptor
|
val capturedValueDescriptor = capturedValueSymbol.descriptor
|
||||||
localContext?.irGet(
|
localContext?.irGet(
|
||||||
oldExpression.startOffset, oldExpression.endOffset,
|
oldExpression.startOffset, oldExpression.endOffset,
|
||||||
capturedValueDescriptor
|
capturedValueDescriptor
|
||||||
) ?:
|
) ?: run {
|
||||||
// Captured value is directly available for the caller.
|
// Captured value is directly available for the caller.
|
||||||
IrGetValueImpl(
|
val value = oldParameterToNew[capturedValueDescriptor] ?: capturedValue
|
||||||
oldExpression.startOffset, oldExpression.endOffset,
|
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset, value.type, value.symbol)
|
||||||
oldParameterToNew[capturedValueDescriptor] ?: capturedValueSymbol
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -339,11 +344,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
val newCallableReference = IrFunctionReferenceImpl(
|
val newCallableReference = IrFunctionReferenceImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
expression.type, // TODO functional type for transformed descriptor
|
expression.type, // TODO functional type for transformed descriptor
|
||||||
newCallee,
|
newCallee.symbol,
|
||||||
newCallee.descriptor,
|
newCallee.descriptor,
|
||||||
remapTypeArguments(expression, newCallee.descriptor),
|
expression.typeArgumentsCount,
|
||||||
expression.origin
|
expression.origin
|
||||||
).fillArguments(expression)
|
).also {
|
||||||
|
it.fillArguments(expression)
|
||||||
|
it.copyTypeArgumentsFrom(expression)
|
||||||
|
}
|
||||||
|
|
||||||
return newCallableReference
|
return newCallableReference
|
||||||
}
|
}
|
||||||
@@ -354,7 +362,11 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
val oldReturnTarget = expression.returnTarget
|
val oldReturnTarget = expression.returnTarget
|
||||||
val newReturnTarget = oldReturnTarget.transformed ?: return expression
|
val newReturnTarget = oldReturnTarget.transformed ?: return expression
|
||||||
|
|
||||||
return IrReturnImpl(expression.startOffset, expression.endOffset, newReturnTarget, expression.value)
|
return IrReturnImpl(
|
||||||
|
expression.startOffset, expression.endOffset,
|
||||||
|
context.irBuiltIns.nothingType,
|
||||||
|
newReturnTarget.symbol, expression.value
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDeclarationReference(expression: IrDeclarationReference): IrExpression {
|
override fun visitDeclarationReference(expression: IrDeclarationReference): IrExpression {
|
||||||
@@ -398,8 +410,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
0,
|
0,
|
||||||
IrSetFieldImpl(
|
IrSetFieldImpl(
|
||||||
startOffset, endOffset, field.symbol,
|
startOffset, endOffset, field.symbol,
|
||||||
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
|
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol),
|
||||||
capturedValueExpression, STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
|
capturedValueExpression,
|
||||||
|
context.irBuiltIns.unitType,
|
||||||
|
STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -422,31 +436,19 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
rewriteFunctionBody(memberDeclaration, null)
|
rewriteFunctionBody(memberDeclaration, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNewCall(oldCall: IrCall, newCallee: IrFunctionSymbol) =
|
private fun createNewCall(oldCall: IrCall, newCallee: IrFunction) =
|
||||||
if (oldCall is IrCallWithShallowCopy)
|
if (oldCall is IrCallWithShallowCopy)
|
||||||
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifierSymbol)
|
oldCall.shallowCopy(oldCall.origin, newCallee.symbol, oldCall.superQualifierSymbol)
|
||||||
else
|
else
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
oldCall.startOffset, oldCall.endOffset,
|
oldCall.startOffset, oldCall.endOffset,
|
||||||
newCallee,
|
newCallee.returnType,
|
||||||
|
newCallee.symbol,
|
||||||
newCallee.descriptor,
|
newCallee.descriptor,
|
||||||
remapTypeArguments(oldCall, newCallee.descriptor),
|
|
||||||
oldCall.origin, oldCall.superQualifierSymbol
|
oldCall.origin, oldCall.superQualifierSymbol
|
||||||
)
|
).also {
|
||||||
|
it.copyTypeArgumentsFrom(oldCall)
|
||||||
private fun remapTypeArguments(
|
}
|
||||||
oldExpression: IrMemberAccessExpression,
|
|
||||||
newCallee: CallableDescriptor
|
|
||||||
): Map<TypeParameterDescriptor, KotlinType>? {
|
|
||||||
val oldCallee = oldExpression.descriptor.original
|
|
||||||
|
|
||||||
return if (oldCallee.typeParameters.isEmpty())
|
|
||||||
null
|
|
||||||
else oldCallee.typeParameters.associateBy(
|
|
||||||
{ newCallee.typeParameters[it.index] },
|
|
||||||
{ oldExpression.getTypeArgumentOrDefault(it) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun transformDescriptors() {
|
private fun transformDescriptors() {
|
||||||
localFunctions.values.forEach {
|
localFunctions.values.forEach {
|
||||||
@@ -519,7 +521,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
oldDescriptor.extensionReceiverParameter?.type,
|
oldDescriptor.extensionReceiverParameter?.type,
|
||||||
newDispatchReceiverParameter,
|
newDispatchReceiverParameter,
|
||||||
newTypeParameters,
|
newTypeParameters,
|
||||||
newValueParameters,
|
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||||
oldDescriptor.returnType,
|
oldDescriptor.returnType,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
Visibilities.PRIVATE
|
Visibilities.PRIVATE
|
||||||
@@ -533,9 +535,26 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
IrFunctionImpl(startOffset, endOffset, origin, newDescriptor)
|
IrFunctionImpl(startOffset, endOffset, origin, newDescriptor)
|
||||||
}.apply {
|
}.apply {
|
||||||
parent = memberDeclaration.parent
|
parent = memberDeclaration.parent
|
||||||
createParameterDeclarations()
|
returnType = localFunctionContext.declaration.returnType
|
||||||
|
|
||||||
|
localFunctionContext.declaration.typeParameters.mapTo(this.typeParameters) {
|
||||||
|
IrTypeParameterImpl(it.startOffset, it.endOffset, it.origin, it.descriptor)
|
||||||
|
.apply { superTypes += it.superTypes }
|
||||||
|
}
|
||||||
|
|
||||||
|
localFunctionContext.declaration.extensionReceiverParameter?.let {
|
||||||
|
this.extensionReceiverParameter = IrValueParameterImpl(
|
||||||
|
it.startOffset,
|
||||||
|
it.endOffset,
|
||||||
|
it.origin,
|
||||||
|
descriptor.extensionReceiverParameter!!,
|
||||||
|
it.type,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
this.valueParameters += newValueParameters
|
||||||
recordTransformedValueParameters(localFunctionContext)
|
recordTransformedValueParameters(localFunctionContext)
|
||||||
transformedDeclarations[oldDescriptor] = this.symbol
|
transformedDeclarations[oldDescriptor] = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +562,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
localContext: LocalContextWithClosureAsParameters,
|
localContext: LocalContextWithClosureAsParameters,
|
||||||
capturedValues: List<IrValueSymbol>
|
capturedValues: List<IrValueSymbol>
|
||||||
)
|
)
|
||||||
: List<ValueParameterDescriptor> {
|
: List<IrValueParameter> {
|
||||||
|
|
||||||
val oldDescriptor = localContext.descriptor
|
val oldDescriptor = localContext.descriptor
|
||||||
val newDescriptor = localContext.transformedDescriptor
|
val newDescriptor = localContext.transformedDescriptor
|
||||||
@@ -551,17 +570,23 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
val closureParametersCount = capturedValues.size
|
val closureParametersCount = capturedValues.size
|
||||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
||||||
|
|
||||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
val newValueParameters = ArrayList<IrValueParameter>(newValueParametersCount).apply {
|
||||||
capturedValues.mapIndexedTo(this) { i, capturedValue ->
|
capturedValues.mapIndexedTo(this) { i, capturedValue ->
|
||||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValue.descriptor, i).apply {
|
val parameterDescriptor = createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValue.descriptor, i).apply {
|
||||||
newParameterToCaptured[this] = capturedValue
|
newParameterToCaptured[this] = capturedValue
|
||||||
}
|
}
|
||||||
|
capturedValue.owner.copy(parameterDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
localContext.declaration.valueParameters.mapIndexedTo(this) { i, oldValueParameter ->
|
||||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
val parameterDescriptor = createUnsubstitutedParameter(
|
||||||
newParameterToOld.putAbsentOrSame(this, oldValueParameterDescriptor)
|
newDescriptor,
|
||||||
|
oldValueParameter.descriptor as ValueParameterDescriptor,
|
||||||
|
closureParametersCount + i
|
||||||
|
).apply {
|
||||||
|
newParameterToOld.putAbsentOrSame(this, oldValueParameter.descriptor)
|
||||||
}
|
}
|
||||||
|
oldValueParameter.copy(parameterDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newValueParameters
|
return newValueParameters
|
||||||
@@ -572,14 +597,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
valueParameters.forEach {
|
valueParameters.forEach {
|
||||||
val capturedValue = newParameterToCaptured[it.descriptor]
|
val capturedValue = newParameterToCaptured[it.descriptor]
|
||||||
if (capturedValue != null) {
|
if (capturedValue != null) {
|
||||||
localContext.capturedValueToParameter[capturedValue.descriptor] = it.symbol
|
localContext.capturedValueToParameter[capturedValue.descriptor] = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters).forEach {
|
(listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters).forEach {
|
||||||
val oldParameter = newParameterToOld[it.descriptor]
|
val oldParameter = newParameterToOld[it.descriptor]
|
||||||
if (oldParameter != null) {
|
if (oldParameter != null) {
|
||||||
oldParameterToNew.putAbsentOrSame(oldParameter, it.symbol)
|
oldParameterToNew.putAbsentOrSame(oldParameter, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,7 +628,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
val newValueParameters = createTransformedValueParameters(constructorContext, capturedValues)
|
val newValueParameters = createTransformedValueParameters(constructorContext, capturedValues)
|
||||||
|
|
||||||
newDescriptor.initialize(
|
newDescriptor.initialize(
|
||||||
newValueParameters,
|
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||||
Visibilities.PRIVATE,
|
Visibilities.PRIVATE,
|
||||||
newTypeParameters
|
newTypeParameters
|
||||||
)
|
)
|
||||||
@@ -618,12 +643,23 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructorContext.transformedDeclaration = with(constructorContext.declaration) {
|
constructorContext.transformedDeclaration = with(constructorContext.declaration) {
|
||||||
IrConstructorImpl(startOffset, endOffset, origin, newDescriptor)
|
IrConstructorImpl(startOffset, endOffset, origin, newDescriptor).also { it.returnType = returnType }
|
||||||
}.apply {
|
}.apply {
|
||||||
parent = constructorContext.declaration.parent
|
parent = constructorContext.declaration.parent
|
||||||
createParameterDeclarations()
|
constructorContext.declaration.dispatchReceiverParameter?.let {
|
||||||
|
this.dispatchReceiverParameter = IrValueParameterImpl(
|
||||||
|
it.startOffset,
|
||||||
|
it.endOffset,
|
||||||
|
it.origin,
|
||||||
|
descriptor.dispatchReceiverParameter!!,
|
||||||
|
it.type,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.valueParameters += newValueParameters
|
||||||
recordTransformedValueParameters(constructorContext)
|
recordTransformedValueParameters(constructorContext)
|
||||||
transformedDeclarations[oldDescriptor] = this.symbol
|
transformedDeclarations[oldDescriptor] = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,7 +698,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
localClassContext.capturedValueToField[capturedValue.descriptor] = IrFieldImpl(
|
localClassContext.capturedValueToField[capturedValue.descriptor] = IrFieldImpl(
|
||||||
localClassContext.declaration.startOffset, localClassContext.declaration.endOffset,
|
localClassContext.declaration.startOffset, localClassContext.declaration.endOffset,
|
||||||
DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE,
|
DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE,
|
||||||
fieldDescriptor
|
fieldDescriptor, capturedValue.owner.type
|
||||||
).apply {
|
).apply {
|
||||||
parent = localClassContext.declaration
|
parent = localClassContext.declaration
|
||||||
}
|
}
|
||||||
@@ -775,4 +811,13 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrValueDeclaration.copy(newDescriptor: ParameterDescriptor): IrValueParameter = IrValueParameterImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
IrDeclarationOrigin.DEFINED,
|
||||||
|
newDescriptor,
|
||||||
|
type,
|
||||||
|
(this as? IrValueParameter)?.varargElementType
|
||||||
|
)
|
||||||
|
|||||||
+9
-15
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -60,7 +61,7 @@ abstract class AbstractVariableRemapper : IrElementTransformerVoid() {
|
|||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression =
|
override fun visitGetValue(expression: IrGetValue): IrExpression =
|
||||||
remapVariable(expression.descriptor)?.let {
|
remapVariable(expression.descriptor)?.let {
|
||||||
IrGetValueImpl(expression.startOffset, expression.endOffset, it.symbol, expression.origin)
|
IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.origin)
|
||||||
} ?: expression
|
} ?: expression
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +85,7 @@ fun <T : IrBuilder> T.at(element: IrElement) = this.at(element.startOffset, elem
|
|||||||
*/
|
*/
|
||||||
inline fun IrGeneratorWithScope.irBlock(
|
inline fun IrGeneratorWithScope.irBlock(
|
||||||
expression: IrExpression, origin: IrStatementOrigin? = null,
|
expression: IrExpression, origin: IrStatementOrigin? = null,
|
||||||
resultType: KotlinType? = expression.type,
|
resultType: IrType? = expression.type,
|
||||||
body: IrBlockBuilder.() -> Unit
|
body: IrBlockBuilder.() -> Unit
|
||||||
) =
|
) =
|
||||||
this.irBlock(expression.startOffset, expression.endOffset, origin, resultType, body)
|
this.irBlock(expression.startOffset, expression.endOffset, origin, resultType, body)
|
||||||
@@ -93,13 +94,15 @@ inline fun IrGeneratorWithScope.irBlockBody(irElement: IrElement, body: IrBlockB
|
|||||||
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
|
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression) =
|
fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression) =
|
||||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, thenPart, null)
|
IrIfThenElseImpl(startOffset, endOffset, context.irBuiltIns.unitType).apply {
|
||||||
|
branches += IrBranchImpl(condition, thenPart)
|
||||||
|
}
|
||||||
|
|
||||||
fun IrBuilderWithScope.irNot(arg: IrExpression) =
|
fun IrBuilderWithScope.irNot(arg: IrExpression) =
|
||||||
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL, arg)
|
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL, arg)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
|
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
|
||||||
IrThrowImpl(startOffset, endOffset, context.builtIns.nothingType, arg)
|
IrThrowImpl(startOffset, endOffset, context.irBuiltIns.nothingType, arg)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
||||||
IrCatchImpl(
|
IrCatchImpl(
|
||||||
@@ -107,21 +110,12 @@ fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
|||||||
catchParameter
|
catchParameter
|
||||||
)
|
)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCast(arg: IrExpression, type: KotlinType, typeOperand: KotlinType) =
|
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, typeOperand, arg)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
|
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
|
||||||
IrTypeOperatorCallImpl(
|
IrTypeOperatorCallImpl(
|
||||||
startOffset, endOffset, context.builtIns.unitType,
|
startOffset, endOffset, context.irBuiltIns.unitType,
|
||||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.builtIns.unitType, arg
|
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.irBuiltIns.unitType, context.irBuiltIns.unitClass, arg
|
||||||
)
|
)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression, symbol: IrFieldSymbol) =
|
|
||||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irSetField(receiver: IrExpression, symbol: IrFieldSymbol, value: IrExpression) =
|
|
||||||
IrSetFieldImpl(startOffset, endOffset, symbol, receiver, value)
|
|
||||||
|
|
||||||
open class IrBuildingTransformer(private val context: BackendContext) : IrElementTransformerVoid() {
|
open class IrBuildingTransformer(private val context: BackendContext) : IrElementTransformerVoid() {
|
||||||
private var currentBuilder: IrBuilderWithScope? = null
|
private var currentBuilder: IrBuilderWithScope? = null
|
||||||
|
|
||||||
|
|||||||
+14
-12
@@ -27,10 +27,12 @@ import org.jetbrains.kotlin.ir.builders.irGet
|
|||||||
import org.jetbrains.kotlin.ir.builders.irTemporary
|
import org.jetbrains.kotlin.ir.builders.irTemporary
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrSymbolDeclaration
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||||
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.ir.util.constructors
|
import org.jetbrains.kotlin.ir.util.constructors
|
||||||
import org.jetbrains.kotlin.ir.util.functions
|
import org.jetbrains.kotlin.ir.util.functions
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
@@ -60,33 +62,33 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
|||||||
private val nameToString = Name.identifier("toString")
|
private val nameToString = Name.identifier("toString")
|
||||||
private val nameAppend = Name.identifier("append")
|
private val nameAppend = Name.identifier("append")
|
||||||
|
|
||||||
private val stringBuilder = context.ir.symbols.stringBuilder
|
private val stringBuilder = context.ir.symbols.stringBuilder.owner
|
||||||
|
|
||||||
//TODO: calculate and pass string length to the constructor.
|
//TODO: calculate and pass string length to the constructor.
|
||||||
private val constructor = stringBuilder.constructors.single {
|
private val constructor = stringBuilder.constructors.single {
|
||||||
it.owner.valueParameters.size == 0
|
it.valueParameters.size == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private val toStringFunction = stringBuilder.functions.single {
|
private val toStringFunction = stringBuilder.functions.single {
|
||||||
it.owner.valueParameters.size == 0 && it.descriptor.name == nameToString
|
it.valueParameters.size == 0 && it.name == nameToString
|
||||||
}
|
}
|
||||||
private val defaultAppendFunction = stringBuilder.functions.single {
|
private val defaultAppendFunction = stringBuilder.functions.single {
|
||||||
it.descriptor.name == nameAppend &&
|
it.descriptor.name == nameAppend &&
|
||||||
it.owner.valueParameters.size == 1 &&
|
it.valueParameters.size == 1 &&
|
||||||
it.owner.valueParameters.single().type == builtIns.nullableAnyType
|
it.valueParameters.single().type.isNullableAny()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private val appendFunctions: Map<KotlinType, IrFunctionSymbol?> =
|
private val appendFunctions: Map<KotlinType, IrSimpleFunction?> =
|
||||||
typesWithSpecialAppendFunction.map { type ->
|
typesWithSpecialAppendFunction.map { type ->
|
||||||
type to stringBuilder.functions.toList().atMostOne {
|
type to stringBuilder.functions.toList().atMostOne {
|
||||||
it.descriptor.name == nameAppend &&
|
it.descriptor.name == nameAppend &&
|
||||||
it.owner.valueParameters.size == 1 &&
|
it.valueParameters.size == 1 &&
|
||||||
it.owner.valueParameters.single().type == type
|
it.valueParameters.single().type.toKotlinType() == type
|
||||||
}
|
}
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
private fun typeToAppendFunction(type: KotlinType): IrFunctionSymbol {
|
private fun typeToAppendFunction(type: KotlinType): IrSimpleFunction {
|
||||||
return appendFunctions[type] ?: defaultAppendFunction
|
return appendFunctions[type] ?: defaultAppendFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,9 +98,9 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
|||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
val blockBuilder = buildersStack.last()
|
val blockBuilder = buildersStack.last()
|
||||||
return blockBuilder.irBlock(expression) {
|
return blockBuilder.irBlock(expression) {
|
||||||
val stringBuilderImpl = irTemporary(irCall(constructor)).symbol
|
val stringBuilderImpl = irTemporary(irCall(constructor))
|
||||||
expression.arguments.forEach { arg ->
|
expression.arguments.forEach { arg ->
|
||||||
val appendFunction = typeToAppendFunction(arg.type)
|
val appendFunction = typeToAppendFunction(arg.type.toKotlinType())
|
||||||
+irCall(appendFunction).apply {
|
+irCall(appendFunction).apply {
|
||||||
dispatchReceiver = irGet(stringBuilderImpl)
|
dispatchReceiver = irGet(stringBuilderImpl)
|
||||||
putValueArgument(0, arg)
|
putValueArgument(0, arg)
|
||||||
|
|||||||
+15
-17
@@ -18,14 +18,12 @@ package org.jetbrains.kotlin.backend.common.lower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.*
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.util.explicitParameters
|
import org.jetbrains.kotlin.ir.util.explicitParameters
|
||||||
import org.jetbrains.kotlin.ir.util.getArgumentsWithSymbols
|
import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
@@ -55,7 +53,7 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
|||||||
irFunction.body = builder.irBlockBody {
|
irFunction.body = builder.irBlockBody {
|
||||||
// Define variables containing current values of parameters:
|
// Define variables containing current values of parameters:
|
||||||
val parameterToVariable = parameters.associate {
|
val parameterToVariable = parameters.associate {
|
||||||
it to irTemporaryVar(irGet(it), nameHint = it.suggestVariableName()).symbol
|
it to irTemporaryVar(irGet(it), nameHint = it.symbol.suggestVariableName())
|
||||||
}
|
}
|
||||||
// (these variables are to be updated on any tail call).
|
// (these variables are to be updated on any tail call).
|
||||||
|
|
||||||
@@ -63,11 +61,11 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
|||||||
val loop = this
|
val loop = this
|
||||||
condition = irTrue()
|
condition = irTrue()
|
||||||
|
|
||||||
body = irBlock(startOffset, endOffset, resultType = context.builtIns.unitType) {
|
body = irBlock(startOffset, endOffset, resultType = context.irBuiltIns.unitType) {
|
||||||
// Read variables containing current values of parameters:
|
// Read variables containing current values of parameters:
|
||||||
val parameterToNew = parameters.associate {
|
val parameterToNew = parameters.associate {
|
||||||
val variable = parameterToVariable[it]!!
|
val variable = parameterToVariable[it]!!
|
||||||
it to irTemporary(irGet(variable), nameHint = it.suggestVariableName()).symbol
|
it to irTemporary(irGet(variable), nameHint = it.symbol.suggestVariableName())
|
||||||
}
|
}
|
||||||
|
|
||||||
val transformer = BodyTransformer(
|
val transformer = BodyTransformer(
|
||||||
@@ -89,8 +87,8 @@ private class BodyTransformer(
|
|||||||
val builder: IrBuilderWithScope,
|
val builder: IrBuilderWithScope,
|
||||||
val irFunction: IrFunction,
|
val irFunction: IrFunction,
|
||||||
val loop: IrLoop,
|
val loop: IrLoop,
|
||||||
val parameterToNew: Map<IrValueParameterSymbol, IrValueSymbol>,
|
val parameterToNew: Map<IrValueParameter, IrValueDeclaration>,
|
||||||
val parameterToVariable: Map<IrValueParameterSymbol, IrVariableSymbol>,
|
val parameterToVariable: Map<IrValueParameter, IrVariable>,
|
||||||
val tailRecursionCalls: Set<IrCall>
|
val tailRecursionCalls: Set<IrCall>
|
||||||
) : IrElementTransformerVoid() {
|
) : IrElementTransformerVoid() {
|
||||||
|
|
||||||
@@ -98,7 +96,7 @@ private class BodyTransformer(
|
|||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
val value = parameterToNew[expression.symbol] ?: return expression
|
val value = parameterToNew[expression.symbol.owner] ?: return expression
|
||||||
return builder.at(expression).irGet(value)
|
return builder.at(expression).irGet(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +111,7 @@ private class BodyTransformer(
|
|||||||
|
|
||||||
private fun IrBuilderWithScope.genTailCall(expression: IrCall) = this.irBlock(expression) {
|
private fun IrBuilderWithScope.genTailCall(expression: IrCall) = this.irBlock(expression) {
|
||||||
// Get all specified arguments:
|
// Get all specified arguments:
|
||||||
val parameterToArgument = expression.getArgumentsWithSymbols().map { (parameter, argument) ->
|
val parameterToArgument = expression.getArgumentsWithIr().map { (parameter, argument) ->
|
||||||
parameter to argument
|
parameter to argument
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +120,7 @@ private class BodyTransformer(
|
|||||||
at(argument)
|
at(argument)
|
||||||
// Note that argument can use values of parameters, so it is important that
|
// Note that argument can use values of parameters, so it is important that
|
||||||
// references to parameters are mapped using `parameterToNew`, not `parameterToVariable`.
|
// references to parameters are mapped using `parameterToNew`, not `parameterToVariable`.
|
||||||
+irSetVar(parameterToVariable[parameter]!!, argument)
|
+irSetVar(parameterToVariable[parameter]!!.symbol, argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
val specifiedParameters = parameterToArgument.map { (parameter, _) -> parameter }.toSet()
|
val specifiedParameters = parameterToArgument.map { (parameter, _) -> parameter }.toSet()
|
||||||
@@ -130,7 +128,7 @@ private class BodyTransformer(
|
|||||||
// For each unspecified argument set the corresponding variable to default:
|
// For each unspecified argument set the corresponding variable to default:
|
||||||
parameters.filter { it !in specifiedParameters }.forEach { parameter ->
|
parameters.filter { it !in specifiedParameters }.forEach { parameter ->
|
||||||
|
|
||||||
val originalDefaultValue = parameter.owner.defaultValue?.expression ?: throw Error("no argument specified for $parameter")
|
val originalDefaultValue = parameter.defaultValue?.expression ?: throw Error("no argument specified for $parameter")
|
||||||
|
|
||||||
// Copy default value, mapping parameters to variables containing freshly computed arguments:
|
// Copy default value, mapping parameters to variables containing freshly computed arguments:
|
||||||
val defaultValue = originalDefaultValue
|
val defaultValue = originalDefaultValue
|
||||||
@@ -140,15 +138,15 @@ private class BodyTransformer(
|
|||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
val variableSymbol = parameterToVariable[expression.symbol] ?: return expression
|
val variable = parameterToVariable[expression.symbol.owner] ?: return expression
|
||||||
return IrGetValueImpl(
|
return IrGetValueImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset, variable.type,
|
||||||
variableSymbol, expression.origin
|
variable.symbol, expression.origin
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, data = null)
|
}, data = null)
|
||||||
|
|
||||||
+irSetVar(parameterToVariable[parameter]!!, defaultValue)
|
+irSetVar(parameterToVariable[parameter]!!.symbol, defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jump to the entry:
|
// Jump to the entry:
|
||||||
|
|||||||
+60
-63
@@ -32,14 +32,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.constructors
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
|
||||||
import org.jetbrains.kotlin.ir.util.functions
|
|
||||||
import org.jetbrains.kotlin.ir.util.getPropertyGetter
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
|
|
||||||
@@ -68,20 +64,25 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
|||||||
element?.transformChildrenVoid(object: IrElementTransformerVoid() {
|
element?.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||||
val transformer = this
|
val transformer = this
|
||||||
|
|
||||||
private fun replaceEmptyParameterWithEmptyArray(expression: IrMemberAccessExpression) {
|
private fun replaceEmptyParameterWithEmptyArray(expression: IrFunctionAccessExpression) {
|
||||||
log { "call of: ${expression.descriptor}" }
|
log { "call of: ${expression.descriptor}" }
|
||||||
context.createIrBuilder(owner, expression.startOffset, expression.endOffset).apply {
|
context.createIrBuilder(owner, expression.startOffset, expression.endOffset).apply {
|
||||||
expression.descriptor.valueParameters.forEach {
|
expression.descriptor.valueParameters.forEach {
|
||||||
log { "varargElementType: ${it.varargElementType} expr: ${ir2string(expression.getValueArgument(it))}" }
|
log { "varargElementType: ${it.varargElementType} expr: ${ir2string(expression.getValueArgument(it))}" }
|
||||||
}
|
}
|
||||||
expression.descriptor.valueParameters.filter { it.varargElementType != null && expression.getValueArgument(it) == null }.forEach {
|
expression.symbol.owner.valueParameters
|
||||||
expression.putValueArgument(it.index,
|
.filter { it.varargElementType != null && expression.getValueArgument(it.index) == null }
|
||||||
IrVarargImpl(startOffset = startOffset,
|
.forEach {
|
||||||
endOffset = endOffset,
|
expression.putValueArgument(
|
||||||
type = it.type,
|
it.index,
|
||||||
varargElementType = it.varargElementType!!)
|
IrVarargImpl(
|
||||||
)
|
startOffset = startOffset,
|
||||||
}
|
endOffset = endOffset,
|
||||||
|
type = it.type,
|
||||||
|
varargElementType = it.varargElementType!!
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
}
|
}
|
||||||
@@ -99,28 +100,27 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
|||||||
override fun visitVararg(expression: IrVararg): IrExpression {
|
override fun visitVararg(expression: IrVararg): IrExpression {
|
||||||
expression.transformChildrenVoid(transformer)
|
expression.transformChildrenVoid(transformer)
|
||||||
val hasSpreadElement = hasSpreadElement(expression)
|
val hasSpreadElement = hasSpreadElement(expression)
|
||||||
if (!hasSpreadElement && expression.elements.all { it is IrConst<*> && KotlinBuiltIns.isString(it.type) }) {
|
if (!hasSpreadElement && expression.elements.all { it is IrConst<*> && it.type.isString() }) {
|
||||||
log { "skipped vararg expression because it's string array literal" }
|
log { "skipped vararg expression because it's string array literal" }
|
||||||
return expression
|
return expression
|
||||||
}
|
}
|
||||||
val irBuilder = context.createIrBuilder(owner, expression.startOffset, expression.endOffset)
|
val irBuilder = context.createIrBuilder(owner, expression.startOffset, expression.endOffset)
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
val type = expression.varargElementType
|
val type = expression.varargElementType
|
||||||
log { "$expression: array type:$type, is array of primitives ${!KotlinBuiltIns.isArray(expression.type)}" }
|
log { "$expression: array type:$type, is array of primitives ${!expression.type.isArray()}" }
|
||||||
val arrayHandle = arrayType(expression.type)
|
val arrayHandle = arrayType(expression.type)
|
||||||
val arrayConstructor = arrayHandle.arraySymbol.constructors.find { it.owner.valueParameters.size == 1 }!!
|
val arrayConstructor = arrayHandle.arraySymbol.owner.constructors.find { it.valueParameters.size == 1 }!!
|
||||||
val block = irBlock(arrayHandle.arraySymbol.owner.defaultType)
|
val block = irBlock(expression.type)
|
||||||
val arrayConstructorCall = if (arrayConstructor.owner.typeParameters.isEmpty()) {
|
val arrayConstructorCall = irCall(arrayConstructor)
|
||||||
irCall(arrayConstructor)
|
|
||||||
} else {
|
|
||||||
irCall(arrayConstructor, listOf(type))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (arrayConstructor.typeParameters.isNotEmpty()) {
|
||||||
|
arrayConstructorCall.putTypeArgument(0, expression.varargElementType)
|
||||||
|
}
|
||||||
|
|
||||||
val vars = expression.elements.map {
|
val vars = expression.elements.map {
|
||||||
val initVar = scope.createTemporaryVariable(
|
val initVar = scope.createTemporaryVariable(
|
||||||
(it as? IrSpreadElement)?.expression ?: it as IrExpression,
|
(it as? IrSpreadElement)?.expression ?: it as IrExpression,
|
||||||
"elem".synthesizedString, true)
|
"elem".synthesizedString, true)
|
||||||
block.statements.add(initVar)
|
block.statements.add(initVar)
|
||||||
it to initVar
|
it to initVar
|
||||||
}.toMap()
|
}.toMap()
|
||||||
@@ -138,32 +138,31 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
|||||||
log { "element:$i> ${ir2string(element)}" }
|
log { "element:$i> ${ir2string(element)}" }
|
||||||
val dst = vars[element]!!
|
val dst = vars[element]!!
|
||||||
if (element !is IrSpreadElement) {
|
if (element !is IrSpreadElement) {
|
||||||
val setArrayElementCall = irCall(arrayHandle.setMethodSymbol)
|
val setArrayElementCall = irCall(arrayHandle.setMethodSymbol.owner)
|
||||||
setArrayElementCall.dispatchReceiver = irGet(arrayTmpVariable.symbol)
|
setArrayElementCall.dispatchReceiver = irGet(arrayTmpVariable)
|
||||||
setArrayElementCall.putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable.symbol) else irConstInt(i))
|
setArrayElementCall.putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable) else irConstInt(i))
|
||||||
setArrayElementCall.putValueArgument(1, irGet(dst.symbol))
|
setArrayElementCall.putValueArgument(1, irGet(dst))
|
||||||
block.statements.add(setArrayElementCall)
|
block.statements.add(setArrayElementCall)
|
||||||
if (hasSpreadElement) {
|
if (hasSpreadElement) {
|
||||||
block.statements.add(incrementVariable(indexTmpVariable.symbol, kIntOne))
|
block.statements.add(incrementVariable(indexTmpVariable, kIntOne))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val arraySizeVariable = scope.createTemporaryVariable(irArraySize(arrayHandle, irGet(dst.symbol)), "length".synthesizedString)
|
val arraySizeVariable = scope.createTemporaryVariable(irArraySize(arrayHandle, irGet(dst)), "length".synthesizedString)
|
||||||
block.statements.add(arraySizeVariable)
|
block.statements.add(arraySizeVariable)
|
||||||
val copyCall = irCall(arrayHandle.copyRangeToSymbol).apply {
|
val copyCall = irCall(arrayHandle.copyRangeToSymbol.owner).apply {
|
||||||
extensionReceiver = irGet(dst.symbol)
|
extensionReceiver = irGet(dst)
|
||||||
putValueArgument(0, irGet(arrayTmpVariable.symbol)) /* destination */
|
putValueArgument(0, irGet(arrayTmpVariable)) /* destination */
|
||||||
putValueArgument(1, kIntZero) /* fromIndex */
|
putValueArgument(1, kIntZero) /* fromIndex */
|
||||||
putValueArgument(2, irGet(arraySizeVariable.symbol)) /* toIndex */
|
putValueArgument(2, irGet(arraySizeVariable)) /* toIndex */
|
||||||
putValueArgument(3, irGet(indexTmpVariable.symbol)) /* destinationIndex */
|
putValueArgument(3, irGet(indexTmpVariable)) /* destinationIndex */
|
||||||
}
|
}
|
||||||
block.statements.add(copyCall)
|
block.statements.add(copyCall)
|
||||||
block.statements.add(incrementVariable(indexTmpVariable.symbol,
|
block.statements.add(incrementVariable(indexTmpVariable, irGet(arraySizeVariable)))
|
||||||
irGet(arraySizeVariable.symbol)))
|
|
||||||
log { "element:$i:spread element> ${ir2string(element.expression)}" }
|
log { "element:$i:spread element> ${ir2string(element.expression)}" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block.statements.add(irGet(arrayTmpVariable.symbol))
|
block.statements.add(irGet(arrayTmpVariable))
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,24 +170,21 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val symbols = context.ir.symbols
|
private val symbols = context.ir.symbols
|
||||||
private val intPlusInt = symbols.intPlusInt
|
private val intPlusInt = symbols.intPlusInt.owner
|
||||||
|
|
||||||
private fun arrayType(type: KotlinType): ArrayHandle = when {
|
private fun arrayType(type: IrType): ArrayHandle {
|
||||||
KotlinBuiltIns.isPrimitiveArray(type) -> {
|
val primitiveType = KotlinBuiltIns.getPrimitiveArrayType(type.classifierOrFail.descriptor)
|
||||||
val primitiveType = KotlinBuiltIns.getPrimitiveArrayType(type.constructor.declarationDescriptor!!)
|
return when (primitiveType) {
|
||||||
when (primitiveType) {
|
PrimitiveType.BYTE -> kByteArrayHandler
|
||||||
PrimitiveType.BYTE -> kByteArrayHandler
|
PrimitiveType.SHORT -> kShortArrayHandler
|
||||||
PrimitiveType.SHORT -> kShortArrayHandler
|
PrimitiveType.CHAR -> kCharArrayHandler
|
||||||
PrimitiveType.CHAR -> kCharArrayHandler
|
PrimitiveType.INT -> kIntArrayHandler
|
||||||
PrimitiveType.INT -> kIntArrayHandler
|
PrimitiveType.LONG -> kLongArrayHandler
|
||||||
PrimitiveType.LONG -> kLongArrayHandler
|
PrimitiveType.FLOAT -> kFloatArrayHandler
|
||||||
PrimitiveType.FLOAT -> kFloatArrayHandler
|
PrimitiveType.DOUBLE -> kDoubleArrayHandler
|
||||||
PrimitiveType.DOUBLE -> kDoubleArrayHandler
|
PrimitiveType.BOOLEAN -> kBooleanArrayHandler
|
||||||
PrimitiveType.BOOLEAN -> kBooleanArrayHandler
|
else -> kArrayHandler
|
||||||
else -> TODO("unsupported type: $primitiveType")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> kArrayHandler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.intPlus() = irCall(intPlusInt)
|
private fun IrBuilderWithScope.intPlus() = irCall(intPlusInt)
|
||||||
@@ -199,9 +195,9 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.incrementVariable(symbol: IrVariableSymbol, value: IrExpression): IrExpression {
|
private fun IrBuilderWithScope.incrementVariable(variable: IrVariable, value: IrExpression): IrExpression {
|
||||||
return irSetVar(symbol, intPlus().apply {
|
return irSetVar(variable.symbol, intPlus().apply {
|
||||||
dispatchReceiver = irGet(symbol)
|
dispatchReceiver = irGet(variable)
|
||||||
putValueArgument(0, value)
|
putValueArgument(0, value)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -212,14 +208,14 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
|||||||
val notSpreadElementCount = expression.elements.filter { it !is IrSpreadElement}.size
|
val notSpreadElementCount = expression.elements.filter { it !is IrSpreadElement}.size
|
||||||
val initialValue = irConstInt(notSpreadElementCount) as IrExpression
|
val initialValue = irConstInt(notSpreadElementCount) as IrExpression
|
||||||
return vars.filter{it.key is IrSpreadElement}.toList().fold( initial = initialValue) { result, it ->
|
return vars.filter{it.key is IrSpreadElement}.toList().fold( initial = initialValue) { result, it ->
|
||||||
val arraySize = irArraySize(arrayHandle, irGet(it.second.symbol))
|
val arraySize = irArraySize(arrayHandle, irGet(it.second))
|
||||||
increment(result, arraySize)
|
increment(result, arraySize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irArraySize(arrayHandle: ArrayHandle, expression: IrExpression): IrExpression {
|
private fun IrBuilderWithScope.irArraySize(arrayHandle: ArrayHandle, expression: IrExpression): IrExpression {
|
||||||
val arraySize = irCall(arrayHandle.sizeGetterSymbol).apply {
|
val arraySize = irCall(arrayHandle.sizeGetterSymbol.owner).apply {
|
||||||
dispatchReceiver = expression
|
dispatchReceiver = expression
|
||||||
}
|
}
|
||||||
return arraySize
|
return arraySize
|
||||||
@@ -256,7 +252,8 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irConstInt(value: Int): IrConst<Int> = IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, value)
|
private fun IrBuilderWithScope.irConstInt(value: Int): IrConst<Int> =
|
||||||
private fun IrBuilderWithScope.irBlock(type: KotlinType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, value)
|
||||||
|
private fun IrBuilderWithScope.irBlock(type: IrType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||||
private val IrBuilderWithScope.kIntZero get() = irConstInt(0)
|
private val IrBuilderWithScope.kIntZero get() = irConstInt(0)
|
||||||
private val IrBuilderWithScope.kIntOne get() = irConstInt(1)
|
private val IrBuilderWithScope.kIntOne get() = irConstInt(1)
|
||||||
|
|||||||
@@ -16,17 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.builders
|
package org.jetbrains.kotlin.ir.builders
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.substitute
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irWhile(origin: IrStatementOrigin? = null) =
|
fun IrBuilderWithScope.irWhile(origin: IrStatementOrigin? = null) =
|
||||||
IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, origin)
|
IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, origin)
|
||||||
@@ -37,18 +31,5 @@ fun IrBuilderWithScope.irBreak(loop: IrLoop) =
|
|||||||
fun IrBuilderWithScope.irContinue(loop: IrLoop) =
|
fun IrBuilderWithScope.irContinue(loop: IrLoop) =
|
||||||
IrContinueImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop)
|
IrContinueImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irTrue() = IrConstImpl.boolean(startOffset, endOffset, context.irBuiltIns.booleanType, true)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irFalse() = IrConstImpl.boolean(startOffset, endOffset, context.irBuiltIns.booleanType, false)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: Map<TypeParameterDescriptor, KotlinType>) =
|
|
||||||
IrCallImpl(this.startOffset, this.endOffset, symbol, symbol.descriptor.substitute(typeArguments), typeArguments)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: List<KotlinType>) =
|
|
||||||
irCall(symbol, symbol.descriptor.typeParameters.zip(typeArguments).toMap())
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGetObject(classSymbol: IrClassSymbol) =
|
fun IrBuilderWithScope.irGetObject(classSymbol: IrClassSymbol) =
|
||||||
IrGetObjectValueImpl(startOffset, endOffset, classSymbol.owner.defaultType, classSymbol)
|
IrGetObjectValueImpl(startOffset, endOffset, IrSimpleTypeImpl(classSymbol, false, emptyList(), emptyList()), classSymbol)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, symbol: IrFieldSymbol) =
|
|
||||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver)
|
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
@@ -128,9 +131,14 @@ fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) =
|
|||||||
fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
|
fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
|
||||||
IrGetValueImpl(startOffset, endOffset, type, variable)
|
IrGetValueImpl(startOffset, endOffset, type, variable)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irGet(variable: IrValueDeclaration) = irGet(variable.type, variable.symbol)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irSetVar(variable: IrVariableSymbol, value: IrExpression) =
|
fun IrBuilderWithScope.irSetVar(variable: IrVariableSymbol, value: IrExpression) =
|
||||||
IrSetVariableImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, IrStatementOrigin.EQ)
|
IrSetVariableImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, IrStatementOrigin.EQ)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, field: IrField) =
|
||||||
|
IrGetFieldImpl(startOffset, endOffset, field.symbol, field.type, receiver)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irEqeqeq(arg1: IrExpression, arg2: IrExpression) =
|
fun IrBuilderWithScope.irEqeqeq(arg1: IrExpression, arg2: IrExpression) =
|
||||||
context.eqeqeq(startOffset, endOffset, arg1, arg2)
|
context.eqeqeq(startOffset, endOffset, arg1, arg2)
|
||||||
|
|
||||||
@@ -169,6 +177,9 @@ fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, type: IrType): IrCall =
|
|||||||
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, descriptor: FunctionDescriptor, type: IrType): IrCall =
|
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, descriptor: FunctionDescriptor, type: IrType): IrCall =
|
||||||
IrCallImpl(startOffset, endOffset, type, callee, descriptor)
|
IrCallImpl(startOffset, endOffset, type, callee, descriptor)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irCall(callee: IrFunction): IrCall =
|
||||||
|
irCall(callee.symbol, callee.descriptor, callee.returnType)
|
||||||
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCallOp(
|
fun IrBuilderWithScope.irCallOp(
|
||||||
callee: IrFunctionSymbol,
|
callee: IrFunctionSymbol,
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
|||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||||
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ class Scope(val scopeOwnerSymbol: IrSymbol) {
|
|||||||
isMutable: Boolean = false,
|
isMutable: Boolean = false,
|
||||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
|
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
|
||||||
): IrVariable {
|
): IrVariable {
|
||||||
val originalKotlinType = irExpression.type.originalKotlinType ?: throw AssertionError("No originalKotlinType for $irExpression")
|
val originalKotlinType = irExpression.type.originalKotlinType ?: irExpression.type.toKotlinType()
|
||||||
return IrVariableImpl(
|
return IrVariableImpl(
|
||||||
irExpression.startOffset, irExpression.endOffset, origin,
|
irExpression.startOffset, irExpression.endOffset, origin,
|
||||||
createDescriptorForTemporaryVariable(
|
createDescriptorForTemporaryVariable(
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName
|
||||||
|
|
||||||
|
private fun IrType.isBuiltInClassType(descriptorPredicate: (ClassDescriptor) -> Boolean, hasQuestionMark: Boolean): Boolean {
|
||||||
|
if (this !is IrSimpleType) return false
|
||||||
|
if (this.hasQuestionMark != hasQuestionMark) return false
|
||||||
|
val classSymbol = this.classifier as? IrClassSymbol ?: return false
|
||||||
|
return descriptorPredicate(classSymbol.descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrType.isNotNullClassType(fqName: FqNameUnsafe) = isClassType(fqName, hasQuestionMark = false)
|
||||||
|
private fun IrType.isNullableClassType(fqName: FqNameUnsafe) = isClassType(fqName, hasQuestionMark = true)
|
||||||
|
|
||||||
|
private fun IrType.isClassType(fqName: FqNameUnsafe, hasQuestionMark: Boolean): Boolean {
|
||||||
|
if (this !is IrSimpleType) return false
|
||||||
|
if (this.hasQuestionMark != hasQuestionMark) return false
|
||||||
|
val classSymbol = this.classifier as? IrClassSymbol ?: return false
|
||||||
|
return classFqNameEquals(classSymbol.descriptor, fqName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun classFqNameEquals(descriptor: ClassDescriptor, fqName: FqNameUnsafe): Boolean =
|
||||||
|
descriptor.name == fqName.shortName() && fqName == getFqName(descriptor)
|
||||||
|
|
||||||
|
fun IrType.isNullableAny(): Boolean = isBuiltInClassType(KotlinBuiltIns::isAny, hasQuestionMark = true)
|
||||||
|
|
||||||
|
fun IrType.isString(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.string)
|
||||||
|
fun IrType.isArray(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.array)
|
||||||
|
fun IrType.isNothing(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.nothing)
|
||||||
|
fun IrType.isPrimitiveType(): Boolean =
|
||||||
|
isBuiltInClassType(KotlinBuiltIns::isPrimitiveClass, hasQuestionMark = false)
|
||||||
|
|
||||||
|
fun IrType.isNullablePrimitiveType(): Boolean =
|
||||||
|
isBuiltInClassType(KotlinBuiltIns::isPrimitiveClass, hasQuestionMark = true)
|
||||||
|
|
||||||
|
fun IrType.isUnit() = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.unit)
|
||||||
|
fun IrType.isNullableUnit() = isNullableClassType(KotlinBuiltIns.FQ_NAMES.unit)
|
||||||
|
fun IrType.isUnitOrNullableUnit() = this.isUnit() || this.isNullableUnit()
|
||||||
|
|
||||||
|
fun IrType.isBoolean(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES._boolean)
|
||||||
|
fun IrType.isChar(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES._char)
|
||||||
|
fun IrType.isByte(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES._byte)
|
||||||
|
fun IrType.isShort(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES._short)
|
||||||
|
fun IrType.isInt(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES._int)
|
||||||
|
fun IrType.isLong(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES._long)
|
||||||
|
fun IrType.isFloat(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES._float)
|
||||||
|
fun IrType.isDouble(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES._double)
|
||||||
@@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.types
|
package org.jetbrains.kotlin.ir.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -52,4 +53,20 @@ fun IrType.makeNullable() =
|
|||||||
Variance.INVARIANT
|
Variance.INVARIANT
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
this
|
this
|
||||||
|
|
||||||
|
fun IrType.toKotlinType(): KotlinType = when (this) {
|
||||||
|
is IrSimpleType -> {
|
||||||
|
val classifier = this.classifier.descriptor
|
||||||
|
val arguments = this.arguments.mapIndexed { index, it ->
|
||||||
|
when (it) {
|
||||||
|
is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toKotlinType())
|
||||||
|
is IrStarProjection -> StarProjectionImpl((classifier as ClassDescriptor).declaredTypeParameters[index])
|
||||||
|
else -> error(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
classifier.defaultType.replace(newArguments = arguments).makeNullableAsSpecified(this.hasQuestionMark)
|
||||||
|
}
|
||||||
|
else -> TODO(this.toString())
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
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.types.IrType
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
@@ -79,6 +80,36 @@ fun IrFunctionAccessExpression.getArgumentsWithSymbols(): List<Pair<IrValueParam
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds the arguments explicitly represented in the IR to the parameters of the accessed function.
|
||||||
|
* The arguments are to be evaluated in the same order as they appear in the resulting list.
|
||||||
|
*/
|
||||||
|
fun IrMemberAccessExpression.getArgumentsWithIr(): List<Pair<IrValueParameter, IrExpression>> {
|
||||||
|
val res = mutableListOf<Pair<IrValueParameter, IrExpression>>()
|
||||||
|
val irFunction = when (this) {
|
||||||
|
is IrFunctionAccessExpression -> this.symbol.owner
|
||||||
|
is IrFunctionReference -> this.symbol.owner
|
||||||
|
else -> error(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatchReceiver?.let {
|
||||||
|
res += (irFunction.dispatchReceiverParameter!! to it)
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionReceiver?.let {
|
||||||
|
res += (irFunction.extensionReceiverParameter!! to it)
|
||||||
|
}
|
||||||
|
|
||||||
|
irFunction.valueParameters.forEachIndexed { index, it ->
|
||||||
|
val arg = getValueArgument(index)
|
||||||
|
if (arg != null) {
|
||||||
|
res += (it to arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets arguments that are specified by given mapping of parameters.
|
* Sets arguments that are specified by given mapping of parameters.
|
||||||
*/
|
*/
|
||||||
@@ -203,14 +234,20 @@ val DeclarationDescriptorWithSource.endOffsetOrUndefined: Int get() = endOffset
|
|||||||
val IrClassSymbol.functions: Sequence<IrSimpleFunctionSymbol>
|
val IrClassSymbol.functions: Sequence<IrSimpleFunctionSymbol>
|
||||||
get() = this.owner.declarations.asSequence().filterIsInstance<IrSimpleFunction>().map { it.symbol }
|
get() = this.owner.declarations.asSequence().filterIsInstance<IrSimpleFunction>().map { it.symbol }
|
||||||
|
|
||||||
|
val IrClass.functions: Sequence<IrSimpleFunction>
|
||||||
|
get() = this.declarations.asSequence().filterIsInstance<IrSimpleFunction>()
|
||||||
|
|
||||||
val IrClassSymbol.constructors: Sequence<IrConstructorSymbol>
|
val IrClassSymbol.constructors: Sequence<IrConstructorSymbol>
|
||||||
get() = this.owner.declarations.asSequence().filterIsInstance<IrConstructor>().map { it.symbol }
|
get() = this.owner.declarations.asSequence().filterIsInstance<IrConstructor>().map { it.symbol }
|
||||||
|
|
||||||
val IrFunction.explicitParameters: List<IrValueParameterSymbol>
|
val IrClass.constructors: Sequence<IrConstructor>
|
||||||
get() = (listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters).map { it.symbol }
|
get() = this.declarations.asSequence().filterIsInstance<IrConstructor>()
|
||||||
|
|
||||||
val IrClass.defaultType: KotlinType
|
val IrFunction.explicitParameters: List<IrValueParameter>
|
||||||
get() = this.descriptor.defaultType
|
get() = (listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters)
|
||||||
|
|
||||||
|
val IrClass.defaultType: IrType
|
||||||
|
get() = this.thisReceiver!!.type
|
||||||
|
|
||||||
val IrSimpleFunction.isReal: Boolean get() = descriptor.kind.isReal
|
val IrSimpleFunction.isReal: Boolean get() = descriptor.kind.isReal
|
||||||
|
|
||||||
@@ -263,3 +300,31 @@ fun IrAnnotationContainer.hasAnnotation(name: FqName) =
|
|||||||
annotations.any {
|
annotations.any {
|
||||||
it.symbol.owner.parentAsClass.descriptor.fqNameSafe == name
|
it.symbol.owner.parentAsClass.descriptor.fqNameSafe == name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IrValueParameter.copy(newDescriptor: ParameterDescriptor): IrValueParameter {
|
||||||
|
assert(this.descriptor.type == newDescriptor.type)
|
||||||
|
|
||||||
|
return IrValueParameterImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
IrDeclarationOrigin.DEFINED,
|
||||||
|
newDescriptor,
|
||||||
|
type,
|
||||||
|
varargElementType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrFunction.createDispatchReceiverParameter() {
|
||||||
|
assert(this.dispatchReceiverParameter == null)
|
||||||
|
|
||||||
|
val descriptor = this.descriptor.dispatchReceiverParameter ?: return
|
||||||
|
|
||||||
|
this.dispatchReceiverParameter = IrValueParameterImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
IrDeclarationOrigin.DEFINED,
|
||||||
|
descriptor,
|
||||||
|
this.parentAsClass.defaultType,
|
||||||
|
null
|
||||||
|
).also { it.parent = this }
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user