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.expressions.*
|
||||
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.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
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) {
|
||||
if (expectedType != type) {
|
||||
reportError(this, "unexpected expression.type: expected $expectedType, got ${type}")
|
||||
// TODO: compare IR types instead.
|
||||
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_NOTNULL,
|
||||
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
|
||||
}
|
||||
|
||||
+4
-1
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
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.visitors.acceptVoid
|
||||
|
||||
@@ -41,8 +42,10 @@ fun <T : IrElement> T.deepCopyWithVariables(): T {
|
||||
val symbolsRemapper = DeepCopySymbolRemapper(descriptorsRemapper)
|
||||
acceptVoid(symbolsRemapper)
|
||||
|
||||
val typesRemapper = DeepCopyTypeRemapper(symbolsRemapper)
|
||||
|
||||
return this.transform(
|
||||
object : DeepCopyIrTreeWithReturnableBlockSymbols(symbolsRemapper) {
|
||||
object : DeepCopyIrTreeWithReturnableBlockSymbols(symbolsRemapper, typesRemapper) {
|
||||
override fun getNonTransformedLoop(irLoop: IrLoop): 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.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.renderer.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -285,7 +286,7 @@ class DumpIrTreeWithDescriptorsVisitor(out: Appendable): IrElementVisitor<Unit,
|
||||
for (typeParameter in expression.descriptor.original.typeParameters) {
|
||||
val typeArgument = expression.getTypeArgument(typeParameter) ?: continue
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.SymbolRemapper
|
||||
import org.jetbrains.kotlin.ir.util.TypeRemapper
|
||||
|
||||
open class DeepCopyIrTreeWithReturnableBlockSymbols(
|
||||
private val symbolRemapper: SymbolRemapper
|
||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper) {
|
||||
symbolRemapper: SymbolRemapper,
|
||||
typeRemapper: TypeRemapper
|
||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) {
|
||||
|
||||
private inline fun <reified T : IrElement> T.transform() =
|
||||
transform(this@DeepCopyIrTreeWithReturnableBlockSymbols, null) as T
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
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.descriptors.*
|
||||
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.IrDeclarationOrigin
|
||||
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.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
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(
|
||||
superConstructorSymbol: IrConstructorSymbol,
|
||||
constructorDescriptor: ClassConstructorDescriptor,
|
||||
origin: IrDeclarationOrigin
|
||||
)
|
||||
: IrConstructor {
|
||||
superConstructor: IrConstructor,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
origin: IrDeclarationOrigin,
|
||||
isPrimary: Boolean = false
|
||||
): 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 ->
|
||||
constructor.createParameterDeclarations()
|
||||
|
||||
assert(superConstructor.dispatchReceiverParameter == null) // Inner classes aren't supported.
|
||||
|
||||
constructor.valueParameters += valueParameters
|
||||
constructor.returnType = this.defaultType
|
||||
|
||||
constructor.body = IrBlockBodyImpl(
|
||||
startOffset, endOffset,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
superConstructorSymbol, superConstructorSymbol.descriptor
|
||||
).apply {
|
||||
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.symbol))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol)
|
||||
)
|
||||
startOffset, endOffset,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset, irBuiltIns.unitType,
|
||||
superConstructor.symbol, superConstructor.descriptor
|
||||
).apply {
|
||||
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol, irBuiltIns.unitType)
|
||||
)
|
||||
)
|
||||
|
||||
constructor.parent = this
|
||||
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.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
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.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
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.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
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) :
|
||||
DeclarationContainerLoweringPass {
|
||||
@@ -82,34 +76,31 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
log { "detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions" }
|
||||
functionDescriptor.overriddenDescriptors.forEach { context.log { "DEFAULT-REPLACER: $it" } }
|
||||
if (bodies.isNotEmpty()) {
|
||||
val newIrFunction = functionDescriptor.generateDefaultsFunction(context)
|
||||
val newIrFunction = irFunction.generateDefaultsFunction(context)
|
||||
newIrFunction.parent = irFunction.parent
|
||||
val descriptor = newIrFunction.descriptor
|
||||
log { "$functionDescriptor -> $descriptor" }
|
||||
val builder = context.createIrBuilder(newIrFunction.symbol)
|
||||
newIrFunction.body = builder.irBlockBody(newIrFunction) {
|
||||
val params = mutableListOf<IrVariableSymbol>()
|
||||
val variables = mutableMapOf<ValueDescriptor, IrValueSymbol>()
|
||||
val params = mutableListOf<IrVariable>()
|
||||
val variables = mutableMapOf<ValueDescriptor, IrValueDeclaration>()
|
||||
|
||||
irFunction.dispatchReceiverParameter?.let {
|
||||
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!.symbol
|
||||
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!
|
||||
}
|
||||
|
||||
if (descriptor.extensionReceiverParameter != null) {
|
||||
variables[functionDescriptor.extensionReceiverParameter!!] =
|
||||
newIrFunction.extensionReceiverParameter!!.symbol
|
||||
newIrFunction.extensionReceiverParameter!!
|
||||
}
|
||||
|
||||
for (valueParameter in functionDescriptor.valueParameters) {
|
||||
val parameterSymbol = newIrFunction.valueParameters[valueParameter.index].symbol
|
||||
val temporaryVariableSymbol =
|
||||
IrVariableSymbolImpl(scope.createTemporaryVariableDescriptor(parameterSymbol.descriptor))
|
||||
params.add(temporaryVariableSymbol)
|
||||
variables.put(valueParameter, temporaryVariableSymbol)
|
||||
if (valueParameter.hasDefaultValue()) {
|
||||
val kIntAnd = symbols.intAnd
|
||||
val parameter = newIrFunction.valueParameters[valueParameter.index]
|
||||
|
||||
val argument = if (valueParameter.hasDefaultValue()) {
|
||||
val kIntAnd = symbols.intAnd.owner
|
||||
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)))
|
||||
}, irInt(0))
|
||||
val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
|
||||
@@ -122,41 +113,40 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
return irGet(valueSymbol)
|
||||
}
|
||||
})
|
||||
val variableInitialization = irIfThenElse(
|
||||
type = temporaryVariableSymbol.descriptor.type,
|
||||
irIfThenElse(
|
||||
type = parameter.type,
|
||||
condition = condition,
|
||||
thenPart = expressionBody.expression,
|
||||
elsePart = irGet(parameterSymbol)
|
||||
)
|
||||
+scope.createTemporaryVariable(
|
||||
symbol = temporaryVariableSymbol,
|
||||
initializer = variableInitialization
|
||||
elsePart = irGet(parameter)
|
||||
)
|
||||
|
||||
/* Mapping calculated values with its origin variables. */
|
||||
} else {
|
||||
+scope.createTemporaryVariable(
|
||||
symbol = temporaryVariableSymbol,
|
||||
initializer = irGet(parameterSymbol)
|
||||
)
|
||||
irGet(parameter)
|
||||
}
|
||||
val temporaryVariable = irTemporary(argument, nameHint = parameter.name.asString())
|
||||
|
||||
params.add(temporaryVariable)
|
||||
variables.put(valueParameter, temporaryVariable)
|
||||
}
|
||||
if (irFunction is IrConstructor) {
|
||||
+IrDelegatingConstructorCallImpl(
|
||||
startOffset = irFunction.startOffset,
|
||||
endOffset = irFunction.endOffset,
|
||||
type = context.irBuiltIns.unitType,
|
||||
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor
|
||||
).apply {
|
||||
params.forEachIndexed { i, variable ->
|
||||
putValueArgument(i, irGet(variable))
|
||||
}
|
||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!.symbol)
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
+irReturn(irCall(irFunction.symbol).apply {
|
||||
+irReturn(irCall(irFunction).apply {
|
||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!.symbol)
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
|
||||
}
|
||||
if (functionDescriptor.extensionReceiverParameter != null) {
|
||||
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 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 {
|
||||
return irFunction.getDefault(valueParameter) ?: TODO("FIXME!!!")
|
||||
}
|
||||
|
||||
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) =
|
||||
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }.symbol
|
||||
private fun maskParameter(function: IrFunction, number: Int) =
|
||||
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }
|
||||
|
||||
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) =
|
||||
descriptor.valueParameters.single { it.name == kConstructorMarkerName }
|
||||
|
||||
private fun nullConst(expression: IrElement, type: KotlinType): IrExpression? {
|
||||
when {
|
||||
KotlinBuiltIns.isFloat(type) -> return IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
|
||||
KotlinBuiltIns.isDouble(type) -> return IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
|
||||
KotlinBuiltIns.isBoolean(type) -> return IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
|
||||
KotlinBuiltIns.isByte(type) -> return IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isChar(type) -> return IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
|
||||
KotlinBuiltIns.isShort(type) -> return IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isInt(type) -> return IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isLong(type) -> return IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
|
||||
else -> return IrConstImpl.constNull(expression.startOffset, expression.endOffset, type.builtIns.nullableNothingType)
|
||||
}
|
||||
private fun nullConst(expression: IrElement, type: IrType, context: CommonBackendContext) = when {
|
||||
type.isFloat() -> IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
|
||||
type.isDouble() -> IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
|
||||
type.isBoolean() -> IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
|
||||
type.isByte() -> IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isChar() -> IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
|
||||
type.isShort() -> IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isInt() -> IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isLong() -> IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
|
||||
else -> IrConstImpl.constNull(expression.startOffset, expression.endOffset, context.irBuiltIns.nothingNType)
|
||||
}
|
||||
|
||||
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)
|
||||
return expression
|
||||
val (symbolForCall, params) = parametersForCall(expression)
|
||||
symbolForCall as IrConstructorSymbol
|
||||
return IrDelegatingConstructorCallImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
symbol = symbolForCall as IrConstructorSymbol,
|
||||
type = context.irBuiltIns.unitType,
|
||||
symbol = symbolForCall,
|
||||
descriptor = symbolForCall.descriptor
|
||||
)
|
||||
.apply {
|
||||
@@ -273,13 +244,14 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
return IrCallImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
type = symbol.owner.returnType,
|
||||
symbol = symbol,
|
||||
descriptor = descriptor,
|
||||
typeArguments = expression.descriptor.typeParameters.map {
|
||||
it to (expression.getTypeArgument(it) ?: it.defaultType)
|
||||
}.toMap()
|
||||
typeArgumentsCount = expression.typeArgumentsCount
|
||||
)
|
||||
.apply {
|
||||
this.copyTypeArgumentsFrom(expression)
|
||||
|
||||
params.forEach {
|
||||
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(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?>>> {
|
||||
val descriptor = expression.descriptor
|
||||
val keyFunction = expression.symbol.owner.findSuperMethodWithDefaultArguments()!!
|
||||
val keyDescriptor = keyFunction.descriptor
|
||||
val realFunction = keyDescriptor.generateDefaultsFunction(context)
|
||||
val realFunction = keyFunction.generateDefaultsFunction(context)
|
||||
realFunction.parent = keyFunction.parent
|
||||
val realDescriptor = realFunction.descriptor
|
||||
|
||||
@@ -325,15 +296,18 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
maskValues[maskIndex] = maskValues[maskIndex] or (1 shl (i % 32))
|
||||
}
|
||||
val valueParameterDescriptor = realDescriptor.valueParameters[i]
|
||||
val defaultValueArgument =
|
||||
if (valueParameterDescriptor.isVararg) null else nullConst(expression, valueParameterDescriptor.type)
|
||||
val defaultValueArgument = if (valueParameterDescriptor.isVararg) {
|
||||
null
|
||||
} else {
|
||||
nullConst(expression, realFunction.valueParameters[i].type, context)
|
||||
}
|
||||
valueParameterDescriptor to (valueArgument ?: defaultValueArgument)
|
||||
})
|
||||
maskValues.forEachIndexed { i, maskValue ->
|
||||
params += maskParameterDescriptor(realFunction, i) to IrConstImpl.int(
|
||||
startOffset = irBody.startOffset,
|
||||
endOffset = irBody.endOffset,
|
||||
type = descriptor.builtIns.intType,
|
||||
type = context.irBuiltIns.intType,
|
||||
value = maskValue
|
||||
)
|
||||
}
|
||||
@@ -347,7 +321,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
)
|
||||
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
|
||||
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 {
|
||||
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) =
|
||||
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) {
|
||||
val descriptor = when (this) {
|
||||
is ClassConstructorDescriptor ->
|
||||
@@ -389,8 +363,10 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
}
|
||||
}
|
||||
|
||||
val function = this@generateDefaultsFunction
|
||||
|
||||
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) {
|
||||
syntheticParameters += valueParameter(
|
||||
@@ -402,10 +378,29 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
syntheticParameters += valueParameter(
|
||||
descriptor, syntheticParameters.last().index + 1,
|
||||
"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(
|
||||
/* receiverParameterType = */ extensionReceiverParameter?.type,
|
||||
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
|
||||
@@ -425,24 +420,11 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
setInitialized()
|
||||
}
|
||||
},
|
||||
/* unsubstitutedValueParameters = */ valueParameters.map {
|
||||
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,
|
||||
/* unsubstitutedValueParameters = */ newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
/* unsubstitutedReturnType = */ returnType,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ this.visibility)
|
||||
/* visibility = */ this.visibility
|
||||
)
|
||||
descriptor.isSuspend = this.isSuspend
|
||||
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
|
||||
}
|
||||
@@ -472,20 +476,28 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
|
||||
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
|
||||
|
||||
private fun valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: KotlinType): ValueParameterDescriptor {
|
||||
return ValueParameterDescriptorImpl(
|
||||
private fun IrFunction.valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: IrType): IrValueParameter {
|
||||
val parameterDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration = descriptor,
|
||||
original = null,
|
||||
index = index,
|
||||
annotations = Annotations.EMPTY,
|
||||
name = name,
|
||||
outType = type,
|
||||
outType = type.toKotlinType(),
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
varargElementType = null,
|
||||
source = SourceElement.NO_SOURCE
|
||||
)
|
||||
return IrValueParameterImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
parameterDescriptor,
|
||||
type,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
internal val kConstructorMarkerName = "marker".synthesizedName
|
||||
|
||||
+3
-2
@@ -68,7 +68,7 @@ class InitializersLowering(
|
||||
if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField
|
||||
IrGetValueImpl(
|
||||
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
|
||||
irClass.thisReceiver!!.symbol
|
||||
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
|
||||
)
|
||||
else null
|
||||
val irSetField = IrSetFieldImpl(
|
||||
@@ -76,6 +76,7 @@ class InitializersLowering(
|
||||
declaration.symbol,
|
||||
receiver,
|
||||
irFieldInitializer,
|
||||
context.irBuiltIns.unitType,
|
||||
null, null
|
||||
)
|
||||
|
||||
@@ -93,7 +94,7 @@ class InitializersLowering(
|
||||
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
|
||||
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
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) })
|
||||
}
|
||||
})
|
||||
|
||||
+1
-171
@@ -16,26 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
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.declarations.IrDeclaration
|
||||
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> {
|
||||
|
||||
@@ -62,155 +44,3 @@ abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
||||
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 {
|
||||
|
||||
IrCompositeImpl(startOffset, endOffset, context.builtIns.stringType).apply {
|
||||
IrCompositeImpl(startOffset, endOffset, context.irBuiltIns.stringType).apply {
|
||||
receiver?.let {
|
||||
//put receiver for bound callable reference
|
||||
statements.add(it)
|
||||
@@ -68,7 +68,7 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
||||
IrConstImpl.string(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
context.builtIns.stringType,
|
||||
context.irBuiltIns.stringType,
|
||||
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.IrConstImpl
|
||||
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.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -45,20 +47,20 @@ class LateinitLowering(
|
||||
|
||||
private fun transformGetter(backingField: IrField, getter: IrFunction) {
|
||||
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 endOffset = getter.endOffset
|
||||
val irBuilder = context.createIrBuilder(getter.symbol, startOffset, endOffset)
|
||||
irBuilder.run {
|
||||
val block = irBlock(type)
|
||||
val resultVar = scope.createTemporaryVariable(
|
||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it.symbol) }, backingField.symbol)
|
||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it) }, backingField)
|
||||
)
|
||||
block.statements.add(resultVar)
|
||||
val throwIfNull = irIfThenElse(
|
||||
context.builtIns.nothingType,
|
||||
irNotEquals(irGet(resultVar.symbol), irNull()),
|
||||
irReturn(irGet(resultVar.symbol)),
|
||||
context.irBuiltIns.nothingType,
|
||||
irNotEquals(irGet(resultVar), irNull()),
|
||||
irReturn(irGet(resultVar)),
|
||||
throwUninitializedPropertyAccessException(backingField)
|
||||
)
|
||||
block.statements.add(throwIfNull)
|
||||
@@ -76,15 +78,15 @@ class LateinitLowering(
|
||||
IrConstImpl.string(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
context.builtIns.stringType,
|
||||
context.irBuiltIns.stringType,
|
||||
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.resolve.descriptorUtil.parents
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
interface LocalNameProvider {
|
||||
@@ -98,12 +97,12 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
abstract val transformedDescriptor: FunctionDescriptor
|
||||
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? {
|
||||
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? {
|
||||
val field = capturedValueToField[descriptor] ?: return null
|
||||
|
||||
val receiver = declaration.thisReceiver!!
|
||||
return IrGetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, declaration.thisReceiver!!.symbol)
|
||||
startOffset, endOffset, field.symbol, field.type,
|
||||
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? {
|
||||
val field = classContext.capturedValueToField[descriptor] ?: return null
|
||||
|
||||
val receiver = member.dispatchReceiverParameter!!
|
||||
return IrGetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, member.dispatchReceiverParameter!!.symbol)
|
||||
startOffset, endOffset, field.symbol, field.type,
|
||||
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 localClassConstructors: MutableMap<ClassConstructorDescriptor, LocalClassConstructorContext> = LinkedHashMap()
|
||||
|
||||
val transformedDeclarations = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
||||
val transformedDeclarations = mutableMapOf<DeclarationDescriptor, IrDeclaration>()
|
||||
|
||||
val FunctionDescriptor.transformed: IrFunctionSymbol?
|
||||
get() = transformedDeclarations[this] as IrFunctionSymbol?
|
||||
val FunctionDescriptor.transformed: IrFunction?
|
||||
get() = transformedDeclarations[this] as IrFunction?
|
||||
|
||||
val oldParameterToNew: MutableMap<ParameterDescriptor, IrValueParameterSymbol> = HashMap()
|
||||
val oldParameterToNew: MutableMap<ParameterDescriptor, IrValueParameter> = HashMap()
|
||||
val newParameterToOld: MutableMap<ParameterDescriptor, ParameterDescriptor> = 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 ->
|
||||
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 {
|
||||
if (declaration.descriptor in localClasses) {
|
||||
// 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 {
|
||||
return super.visitClass(declaration)
|
||||
}
|
||||
@@ -227,7 +228,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
if (declaration.descriptor in localFunctions) {
|
||||
// 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 {
|
||||
if (localContext is LocalClassContext && declaration.parent == localContext.declaration) {
|
||||
return declaration.apply {
|
||||
@@ -250,7 +251,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
|
||||
declaration.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
||||
val body = declaration.getDefault(argument)!!
|
||||
oldParameterToNew[argument]!!.owner.defaultValue = body
|
||||
oldParameterToNew[argument]!!.defaultValue = body
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -266,7 +267,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
}
|
||||
|
||||
oldParameterToNew[descriptor]?.let {
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, it)
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol)
|
||||
}
|
||||
|
||||
return expression
|
||||
@@ -287,14 +288,17 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val newCallee = transformedDeclarations[oldCallee] as IrConstructorSymbol? ?: return expression
|
||||
val newCallee = transformedDeclarations[oldCallee] as IrConstructor? ?: return expression
|
||||
|
||||
return IrDelegatingConstructorCallImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
newCallee,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(expression, newCallee.descriptor)
|
||||
).fillArguments(expression)
|
||||
context.irBuiltIns.unitType,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor
|
||||
).also {
|
||||
it.fillArguments(expression)
|
||||
it.copyTypeArgumentsFrom(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : IrMemberAccessExpression> T.fillArguments(oldExpression: IrMemberAccessExpression): T {
|
||||
@@ -310,16 +314,17 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
newParameterToCaptured[newValueParameterDescriptor]
|
||||
?: throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
||||
|
||||
val capturedValue = capturedValueSymbol.owner
|
||||
|
||||
val capturedValueDescriptor = capturedValueSymbol.descriptor
|
||||
localContext?.irGet(
|
||||
oldExpression.startOffset, oldExpression.endOffset,
|
||||
capturedValueDescriptor
|
||||
) ?:
|
||||
// Captured value is directly available for the caller.
|
||||
IrGetValueImpl(
|
||||
oldExpression.startOffset, oldExpression.endOffset,
|
||||
oldParameterToNew[capturedValueDescriptor] ?: capturedValueSymbol
|
||||
)
|
||||
) ?: run {
|
||||
// Captured value is directly available for the caller.
|
||||
val value = oldParameterToNew[capturedValueDescriptor] ?: capturedValue
|
||||
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset, value.type, value.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -339,11 +344,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val newCallableReference = IrFunctionReferenceImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, // TODO functional type for transformed descriptor
|
||||
newCallee,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(expression, newCallee.descriptor),
|
||||
expression.typeArgumentsCount,
|
||||
expression.origin
|
||||
).fillArguments(expression)
|
||||
).also {
|
||||
it.fillArguments(expression)
|
||||
it.copyTypeArgumentsFrom(expression)
|
||||
}
|
||||
|
||||
return newCallableReference
|
||||
}
|
||||
@@ -354,7 +362,11 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val oldReturnTarget = expression.returnTarget
|
||||
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 {
|
||||
@@ -398,8 +410,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
0,
|
||||
IrSetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
|
||||
capturedValueExpression, STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
|
||||
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol),
|
||||
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)
|
||||
}
|
||||
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: IrFunctionSymbol) =
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: IrFunction) =
|
||||
if (oldCall is IrCallWithShallowCopy)
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifierSymbol)
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee.symbol, oldCall.superQualifierSymbol)
|
||||
else
|
||||
IrCallImpl(
|
||||
oldCall.startOffset, oldCall.endOffset,
|
||||
newCallee,
|
||||
newCallee.returnType,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(oldCall, newCallee.descriptor),
|
||||
oldCall.origin, oldCall.superQualifierSymbol
|
||||
)
|
||||
|
||||
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) }
|
||||
)
|
||||
}
|
||||
).also {
|
||||
it.copyTypeArgumentsFrom(oldCall)
|
||||
}
|
||||
|
||||
private fun transformDescriptors() {
|
||||
localFunctions.values.forEach {
|
||||
@@ -519,7 +521,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
oldDescriptor.extensionReceiverParameter?.type,
|
||||
newDispatchReceiverParameter,
|
||||
newTypeParameters,
|
||||
newValueParameters,
|
||||
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
oldDescriptor.returnType,
|
||||
Modality.FINAL,
|
||||
Visibilities.PRIVATE
|
||||
@@ -533,9 +535,26 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
IrFunctionImpl(startOffset, endOffset, origin, newDescriptor)
|
||||
}.apply {
|
||||
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)
|
||||
transformedDeclarations[oldDescriptor] = this.symbol
|
||||
transformedDeclarations[oldDescriptor] = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,7 +562,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
localContext: LocalContextWithClosureAsParameters,
|
||||
capturedValues: List<IrValueSymbol>
|
||||
)
|
||||
: List<ValueParameterDescriptor> {
|
||||
: List<IrValueParameter> {
|
||||
|
||||
val oldDescriptor = localContext.descriptor
|
||||
val newDescriptor = localContext.transformedDescriptor
|
||||
@@ -551,17 +570,23 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val closureParametersCount = capturedValues.size
|
||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
||||
|
||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
||||
val newValueParameters = ArrayList<IrValueParameter>(newValueParametersCount).apply {
|
||||
capturedValues.mapIndexedTo(this) { i, capturedValue ->
|
||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValue.descriptor, i).apply {
|
||||
val parameterDescriptor = createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValue.descriptor, i).apply {
|
||||
newParameterToCaptured[this] = capturedValue
|
||||
}
|
||||
capturedValue.owner.copy(parameterDescriptor)
|
||||
}
|
||||
|
||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
||||
newParameterToOld.putAbsentOrSame(this, oldValueParameterDescriptor)
|
||||
localContext.declaration.valueParameters.mapIndexedTo(this) { i, oldValueParameter ->
|
||||
val parameterDescriptor = createUnsubstitutedParameter(
|
||||
newDescriptor,
|
||||
oldValueParameter.descriptor as ValueParameterDescriptor,
|
||||
closureParametersCount + i
|
||||
).apply {
|
||||
newParameterToOld.putAbsentOrSame(this, oldValueParameter.descriptor)
|
||||
}
|
||||
oldValueParameter.copy(parameterDescriptor)
|
||||
}
|
||||
}
|
||||
return newValueParameters
|
||||
@@ -572,14 +597,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
valueParameters.forEach {
|
||||
val capturedValue = newParameterToCaptured[it.descriptor]
|
||||
if (capturedValue != null) {
|
||||
localContext.capturedValueToParameter[capturedValue.descriptor] = it.symbol
|
||||
localContext.capturedValueToParameter[capturedValue.descriptor] = it
|
||||
}
|
||||
}
|
||||
|
||||
(listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters).forEach {
|
||||
val oldParameter = newParameterToOld[it.descriptor]
|
||||
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)
|
||||
|
||||
newDescriptor.initialize(
|
||||
newValueParameters,
|
||||
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
Visibilities.PRIVATE,
|
||||
newTypeParameters
|
||||
)
|
||||
@@ -618,12 +643,23 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
}
|
||||
|
||||
constructorContext.transformedDeclaration = with(constructorContext.declaration) {
|
||||
IrConstructorImpl(startOffset, endOffset, origin, newDescriptor)
|
||||
IrConstructorImpl(startOffset, endOffset, origin, newDescriptor).also { it.returnType = returnType }
|
||||
}.apply {
|
||||
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)
|
||||
transformedDeclarations[oldDescriptor] = this.symbol
|
||||
transformedDeclarations[oldDescriptor] = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,7 +698,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
localClassContext.capturedValueToField[capturedValue.descriptor] = IrFieldImpl(
|
||||
localClassContext.declaration.startOffset, localClassContext.declaration.endOffset,
|
||||
DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE,
|
||||
fieldDescriptor
|
||||
fieldDescriptor, capturedValue.owner.type
|
||||
).apply {
|
||||
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.symbols.IrFieldSymbol
|
||||
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.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -60,7 +61,7 @@ abstract class AbstractVariableRemapper : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression =
|
||||
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
|
||||
}
|
||||
|
||||
@@ -84,7 +85,7 @@ fun <T : IrBuilder> T.at(element: IrElement) = this.at(element.startOffset, elem
|
||||
*/
|
||||
inline fun IrGeneratorWithScope.irBlock(
|
||||
expression: IrExpression, origin: IrStatementOrigin? = null,
|
||||
resultType: KotlinType? = expression.type,
|
||||
resultType: IrType? = expression.type,
|
||||
body: IrBlockBuilder.() -> Unit
|
||||
) =
|
||||
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)
|
||||
|
||||
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) =
|
||||
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL, arg)
|
||||
|
||||
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
|
||||
IrThrowImpl(startOffset, endOffset, context.builtIns.nothingType, arg)
|
||||
IrThrowImpl(startOffset, endOffset, context.irBuiltIns.nothingType, arg)
|
||||
|
||||
fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
||||
IrCatchImpl(
|
||||
@@ -107,21 +110,12 @@ fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
||||
catchParameter
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.irCast(arg: IrExpression, type: KotlinType, typeOperand: KotlinType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, typeOperand, arg)
|
||||
|
||||
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, context.builtIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.builtIns.unitType, arg
|
||||
startOffset, endOffset, context.irBuiltIns.unitType,
|
||||
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() {
|
||||
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.declarations.IrDeclaration
|
||||
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.expressions.IrExpression
|
||||
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.functions
|
||||
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 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.
|
||||
private val constructor = stringBuilder.constructors.single {
|
||||
it.owner.valueParameters.size == 0
|
||||
it.valueParameters.size == 0
|
||||
}
|
||||
|
||||
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 {
|
||||
it.descriptor.name == nameAppend &&
|
||||
it.owner.valueParameters.size == 1 &&
|
||||
it.owner.valueParameters.single().type == builtIns.nullableAnyType
|
||||
it.valueParameters.size == 1 &&
|
||||
it.valueParameters.single().type.isNullableAny()
|
||||
}
|
||||
|
||||
|
||||
private val appendFunctions: Map<KotlinType, IrFunctionSymbol?> =
|
||||
private val appendFunctions: Map<KotlinType, IrSimpleFunction?> =
|
||||
typesWithSpecialAppendFunction.map { type ->
|
||||
type to stringBuilder.functions.toList().atMostOne {
|
||||
it.descriptor.name == nameAppend &&
|
||||
it.owner.valueParameters.size == 1 &&
|
||||
it.owner.valueParameters.single().type == type
|
||||
it.valueParameters.size == 1 &&
|
||||
it.valueParameters.single().type.toKotlinType() == type
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
private fun typeToAppendFunction(type: KotlinType): IrFunctionSymbol {
|
||||
private fun typeToAppendFunction(type: KotlinType): IrSimpleFunction {
|
||||
return appendFunctions[type] ?: defaultAppendFunction
|
||||
}
|
||||
|
||||
@@ -96,9 +98,9 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
||||
expression.transformChildrenVoid(this)
|
||||
val blockBuilder = buildersStack.last()
|
||||
return blockBuilder.irBlock(expression) {
|
||||
val stringBuilderImpl = irTemporary(irCall(constructor)).symbol
|
||||
val stringBuilderImpl = irTemporary(irCall(constructor))
|
||||
expression.arguments.forEach { arg ->
|
||||
val appendFunction = typeToAppendFunction(arg.type)
|
||||
val appendFunction = typeToAppendFunction(arg.type.toKotlinType())
|
||||
+irCall(appendFunction).apply {
|
||||
dispatchReceiver = irGet(stringBuilderImpl)
|
||||
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.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.impl.IrGetValueImpl
|
||||
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.getArgumentsWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
@@ -55,7 +53,7 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
||||
irFunction.body = builder.irBlockBody {
|
||||
// Define variables containing current values of parameters:
|
||||
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).
|
||||
|
||||
@@ -63,11 +61,11 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
||||
val loop = this
|
||||
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:
|
||||
val parameterToNew = parameters.associate {
|
||||
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(
|
||||
@@ -89,8 +87,8 @@ private class BodyTransformer(
|
||||
val builder: IrBuilderWithScope,
|
||||
val irFunction: IrFunction,
|
||||
val loop: IrLoop,
|
||||
val parameterToNew: Map<IrValueParameterSymbol, IrValueSymbol>,
|
||||
val parameterToVariable: Map<IrValueParameterSymbol, IrVariableSymbol>,
|
||||
val parameterToNew: Map<IrValueParameter, IrValueDeclaration>,
|
||||
val parameterToVariable: Map<IrValueParameter, IrVariable>,
|
||||
val tailRecursionCalls: Set<IrCall>
|
||||
) : IrElementTransformerVoid() {
|
||||
|
||||
@@ -98,7 +96,7 @@ private class BodyTransformer(
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val value = parameterToNew[expression.symbol] ?: return expression
|
||||
val value = parameterToNew[expression.symbol.owner] ?: return expression
|
||||
return builder.at(expression).irGet(value)
|
||||
}
|
||||
|
||||
@@ -113,7 +111,7 @@ private class BodyTransformer(
|
||||
|
||||
private fun IrBuilderWithScope.genTailCall(expression: IrCall) = this.irBlock(expression) {
|
||||
// Get all specified arguments:
|
||||
val parameterToArgument = expression.getArgumentsWithSymbols().map { (parameter, argument) ->
|
||||
val parameterToArgument = expression.getArgumentsWithIr().map { (parameter, argument) ->
|
||||
parameter to argument
|
||||
}
|
||||
|
||||
@@ -122,7 +120,7 @@ private class BodyTransformer(
|
||||
at(argument)
|
||||
// Note that argument can use values of parameters, so it is important that
|
||||
// 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()
|
||||
@@ -130,7 +128,7 @@ private class BodyTransformer(
|
||||
// For each unspecified argument set the corresponding variable to default:
|
||||
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:
|
||||
val defaultValue = originalDefaultValue
|
||||
@@ -140,15 +138,15 @@ private class BodyTransformer(
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val variableSymbol = parameterToVariable[expression.symbol] ?: return expression
|
||||
val variable = parameterToVariable[expression.symbol.owner] ?: return expression
|
||||
return IrGetValueImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
variableSymbol, expression.origin
|
||||
expression.startOffset, expression.endOffset, variable.type,
|
||||
variable.symbol, expression.origin
|
||||
)
|
||||
}
|
||||
}, data = null)
|
||||
|
||||
+irSetVar(parameterToVariable[parameter]!!, defaultValue)
|
||||
+irSetVar(parameterToVariable[parameter]!!.symbol, defaultValue)
|
||||
}
|
||||
|
||||
// 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.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
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.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
|
||||
@@ -68,20 +64,25 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
element?.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
val transformer = this
|
||||
|
||||
private fun replaceEmptyParameterWithEmptyArray(expression: IrMemberAccessExpression) {
|
||||
private fun replaceEmptyParameterWithEmptyArray(expression: IrFunctionAccessExpression) {
|
||||
log { "call of: ${expression.descriptor}" }
|
||||
context.createIrBuilder(owner, expression.startOffset, expression.endOffset).apply {
|
||||
expression.descriptor.valueParameters.forEach {
|
||||
log { "varargElementType: ${it.varargElementType} expr: ${ir2string(expression.getValueArgument(it))}" }
|
||||
}
|
||||
expression.descriptor.valueParameters.filter { it.varargElementType != null && expression.getValueArgument(it) == null }.forEach {
|
||||
expression.putValueArgument(it.index,
|
||||
IrVarargImpl(startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
type = it.type,
|
||||
varargElementType = it.varargElementType!!)
|
||||
)
|
||||
}
|
||||
expression.symbol.owner.valueParameters
|
||||
.filter { it.varargElementType != null && expression.getValueArgument(it.index) == null }
|
||||
.forEach {
|
||||
expression.putValueArgument(
|
||||
it.index,
|
||||
IrVarargImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
type = it.type,
|
||||
varargElementType = it.varargElementType!!
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
expression.transformChildrenVoid(this)
|
||||
}
|
||||
@@ -99,28 +100,27 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
override fun visitVararg(expression: IrVararg): IrExpression {
|
||||
expression.transformChildrenVoid(transformer)
|
||||
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" }
|
||||
return expression
|
||||
}
|
||||
val irBuilder = context.createIrBuilder(owner, expression.startOffset, expression.endOffset)
|
||||
irBuilder.run {
|
||||
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 arrayConstructor = arrayHandle.arraySymbol.constructors.find { it.owner.valueParameters.size == 1 }!!
|
||||
val block = irBlock(arrayHandle.arraySymbol.owner.defaultType)
|
||||
val arrayConstructorCall = if (arrayConstructor.owner.typeParameters.isEmpty()) {
|
||||
irCall(arrayConstructor)
|
||||
} else {
|
||||
irCall(arrayConstructor, listOf(type))
|
||||
}
|
||||
val arrayConstructor = arrayHandle.arraySymbol.owner.constructors.find { it.valueParameters.size == 1 }!!
|
||||
val block = irBlock(expression.type)
|
||||
val arrayConstructorCall = irCall(arrayConstructor)
|
||||
|
||||
if (arrayConstructor.typeParameters.isNotEmpty()) {
|
||||
arrayConstructorCall.putTypeArgument(0, expression.varargElementType)
|
||||
}
|
||||
|
||||
val vars = expression.elements.map {
|
||||
val initVar = scope.createTemporaryVariable(
|
||||
(it as? IrSpreadElement)?.expression ?: it as IrExpression,
|
||||
"elem".synthesizedString, true)
|
||||
(it as? IrSpreadElement)?.expression ?: it as IrExpression,
|
||||
"elem".synthesizedString, true)
|
||||
block.statements.add(initVar)
|
||||
it to initVar
|
||||
}.toMap()
|
||||
@@ -138,32 +138,31 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
log { "element:$i> ${ir2string(element)}" }
|
||||
val dst = vars[element]!!
|
||||
if (element !is IrSpreadElement) {
|
||||
val setArrayElementCall = irCall(arrayHandle.setMethodSymbol)
|
||||
setArrayElementCall.dispatchReceiver = irGet(arrayTmpVariable.symbol)
|
||||
setArrayElementCall.putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable.symbol) else irConstInt(i))
|
||||
setArrayElementCall.putValueArgument(1, irGet(dst.symbol))
|
||||
val setArrayElementCall = irCall(arrayHandle.setMethodSymbol.owner)
|
||||
setArrayElementCall.dispatchReceiver = irGet(arrayTmpVariable)
|
||||
setArrayElementCall.putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable) else irConstInt(i))
|
||||
setArrayElementCall.putValueArgument(1, irGet(dst))
|
||||
block.statements.add(setArrayElementCall)
|
||||
if (hasSpreadElement) {
|
||||
block.statements.add(incrementVariable(indexTmpVariable.symbol, kIntOne))
|
||||
block.statements.add(incrementVariable(indexTmpVariable, kIntOne))
|
||||
}
|
||||
} 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)
|
||||
val copyCall = irCall(arrayHandle.copyRangeToSymbol).apply {
|
||||
extensionReceiver = irGet(dst.symbol)
|
||||
putValueArgument(0, irGet(arrayTmpVariable.symbol)) /* destination */
|
||||
val copyCall = irCall(arrayHandle.copyRangeToSymbol.owner).apply {
|
||||
extensionReceiver = irGet(dst)
|
||||
putValueArgument(0, irGet(arrayTmpVariable)) /* destination */
|
||||
putValueArgument(1, kIntZero) /* fromIndex */
|
||||
putValueArgument(2, irGet(arraySizeVariable.symbol)) /* toIndex */
|
||||
putValueArgument(3, irGet(indexTmpVariable.symbol)) /* destinationIndex */
|
||||
putValueArgument(2, irGet(arraySizeVariable)) /* toIndex */
|
||||
putValueArgument(3, irGet(indexTmpVariable)) /* destinationIndex */
|
||||
}
|
||||
block.statements.add(copyCall)
|
||||
block.statements.add(incrementVariable(indexTmpVariable.symbol,
|
||||
irGet(arraySizeVariable.symbol)))
|
||||
block.statements.add(incrementVariable(indexTmpVariable, irGet(arraySizeVariable)))
|
||||
log { "element:$i:spread element> ${ir2string(element.expression)}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
block.statements.add(irGet(arrayTmpVariable.symbol))
|
||||
block.statements.add(irGet(arrayTmpVariable))
|
||||
return block
|
||||
}
|
||||
}
|
||||
@@ -171,24 +170,21 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
}
|
||||
|
||||
private val symbols = context.ir.symbols
|
||||
private val intPlusInt = symbols.intPlusInt
|
||||
private val intPlusInt = symbols.intPlusInt.owner
|
||||
|
||||
private fun arrayType(type: KotlinType): ArrayHandle = when {
|
||||
KotlinBuiltIns.isPrimitiveArray(type) -> {
|
||||
val primitiveType = KotlinBuiltIns.getPrimitiveArrayType(type.constructor.declarationDescriptor!!)
|
||||
when (primitiveType) {
|
||||
PrimitiveType.BYTE -> kByteArrayHandler
|
||||
PrimitiveType.SHORT -> kShortArrayHandler
|
||||
PrimitiveType.CHAR -> kCharArrayHandler
|
||||
PrimitiveType.INT -> kIntArrayHandler
|
||||
PrimitiveType.LONG -> kLongArrayHandler
|
||||
PrimitiveType.FLOAT -> kFloatArrayHandler
|
||||
PrimitiveType.DOUBLE -> kDoubleArrayHandler
|
||||
PrimitiveType.BOOLEAN -> kBooleanArrayHandler
|
||||
else -> TODO("unsupported type: $primitiveType")
|
||||
}
|
||||
private fun arrayType(type: IrType): ArrayHandle {
|
||||
val primitiveType = KotlinBuiltIns.getPrimitiveArrayType(type.classifierOrFail.descriptor)
|
||||
return when (primitiveType) {
|
||||
PrimitiveType.BYTE -> kByteArrayHandler
|
||||
PrimitiveType.SHORT -> kShortArrayHandler
|
||||
PrimitiveType.CHAR -> kCharArrayHandler
|
||||
PrimitiveType.INT -> kIntArrayHandler
|
||||
PrimitiveType.LONG -> kLongArrayHandler
|
||||
PrimitiveType.FLOAT -> kFloatArrayHandler
|
||||
PrimitiveType.DOUBLE -> kDoubleArrayHandler
|
||||
PrimitiveType.BOOLEAN -> kBooleanArrayHandler
|
||||
else -> kArrayHandler
|
||||
}
|
||||
else -> kArrayHandler
|
||||
}
|
||||
|
||||
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 {
|
||||
return irSetVar(symbol, intPlus().apply {
|
||||
dispatchReceiver = irGet(symbol)
|
||||
private fun IrBuilderWithScope.incrementVariable(variable: IrVariable, value: IrExpression): IrExpression {
|
||||
return irSetVar(variable.symbol, intPlus().apply {
|
||||
dispatchReceiver = irGet(variable)
|
||||
putValueArgument(0, value)
|
||||
})
|
||||
}
|
||||
@@ -212,14 +208,14 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
val notSpreadElementCount = expression.elements.filter { it !is IrSpreadElement}.size
|
||||
val initialValue = irConstInt(notSpreadElementCount) as IrExpression
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irArraySize(arrayHandle: ArrayHandle, expression: IrExpression): IrExpression {
|
||||
val arraySize = irCall(arrayHandle.sizeGetterSymbol).apply {
|
||||
val arraySize = irCall(arrayHandle.sizeGetterSymbol.owner).apply {
|
||||
dispatchReceiver = expression
|
||||
}
|
||||
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.irBlock(type: KotlinType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
private fun IrBuilderWithScope.irConstInt(value: Int): IrConst<Int> =
|
||||
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.kIntOne get() = irConstInt(1)
|
||||
|
||||
@@ -16,17 +16,11 @@
|
||||
|
||||
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.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
|
||||
fun IrBuilderWithScope.irWhile(origin: IrStatementOrigin? = null) =
|
||||
IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, origin)
|
||||
@@ -37,18 +31,5 @@ fun IrBuilderWithScope.irBreak(loop: IrLoop) =
|
||||
fun IrBuilderWithScope.irContinue(loop: IrLoop) =
|
||||
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) =
|
||||
IrGetObjectValueImpl(startOffset, endOffset, classSymbol.owner.defaultType, classSymbol)
|
||||
|
||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, symbol: IrFieldSymbol) =
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver)
|
||||
IrGetObjectValueImpl(startOffset, endOffset, IrSimpleTypeImpl(classSymbol, false, emptyList(), emptyList()), classSymbol)
|
||||
|
||||
@@ -9,6 +9,9 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
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.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
@@ -128,9 +131,14 @@ fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) =
|
||||
fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
|
||||
IrGetValueImpl(startOffset, endOffset, type, variable)
|
||||
|
||||
fun IrBuilderWithScope.irGet(variable: IrValueDeclaration) = irGet(variable.type, variable.symbol)
|
||||
|
||||
fun IrBuilderWithScope.irSetVar(variable: IrVariableSymbol, value: IrExpression) =
|
||||
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) =
|
||||
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 =
|
||||
IrCallImpl(startOffset, endOffset, type, callee, descriptor)
|
||||
|
||||
fun IrBuilderWithScope.irCall(callee: IrFunction): IrCall =
|
||||
irCall(callee.symbol, callee.descriptor, callee.returnType)
|
||||
|
||||
|
||||
fun IrBuilderWithScope.irCallOp(
|
||||
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.createFunctionSymbol
|
||||
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.types.KotlinType
|
||||
|
||||
@@ -61,7 +62,7 @@ class Scope(val scopeOwnerSymbol: IrSymbol) {
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
|
||||
): IrVariable {
|
||||
val originalKotlinType = irExpression.type.originalKotlinType ?: throw AssertionError("No originalKotlinType for $irExpression")
|
||||
val originalKotlinType = irExpression.type.originalKotlinType ?: irExpression.type.toKotlinType()
|
||||
return IrVariableImpl(
|
||||
irExpression.startOffset, irExpression.endOffset, origin,
|
||||
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
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
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.safeAs
|
||||
|
||||
@@ -52,4 +53,20 @@ fun IrType.makeNullable() =
|
||||
Variance.INVARIANT
|
||||
)
|
||||
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.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
@@ -79,6 +80,36 @@ fun IrFunctionAccessExpression.getArgumentsWithSymbols(): List<Pair<IrValueParam
|
||||
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.
|
||||
*/
|
||||
@@ -203,14 +234,20 @@ val DeclarationDescriptorWithSource.endOffsetOrUndefined: Int get() = endOffset
|
||||
val IrClassSymbol.functions: Sequence<IrSimpleFunctionSymbol>
|
||||
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>
|
||||
get() = this.owner.declarations.asSequence().filterIsInstance<IrConstructor>().map { it.symbol }
|
||||
|
||||
val IrFunction.explicitParameters: List<IrValueParameterSymbol>
|
||||
get() = (listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters).map { it.symbol }
|
||||
val IrClass.constructors: Sequence<IrConstructor>
|
||||
get() = this.declarations.asSequence().filterIsInstance<IrConstructor>()
|
||||
|
||||
val IrClass.defaultType: KotlinType
|
||||
get() = this.descriptor.defaultType
|
||||
val IrFunction.explicitParameters: List<IrValueParameter>
|
||||
get() = (listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters)
|
||||
|
||||
val IrClass.defaultType: IrType
|
||||
get() = this.thisReceiver!!.type
|
||||
|
||||
val IrSimpleFunction.isReal: Boolean get() = descriptor.kind.isReal
|
||||
|
||||
@@ -263,3 +300,31 @@ fun IrAnnotationContainer.hasAnnotation(name: FqName) =
|
||||
annotations.any {
|
||||
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