Type propagation on call sites
This commit is contained in:
committed by
KonstantinAnisimov
parent
c06eeb096a
commit
26f4271906
+56
-15
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
|||||||
import org.jetbrains.kotlin.ir.util.getArguments
|
import org.jetbrains.kotlin.ir.util.getArguments
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------//
|
//-----------------------------------------------------------------------------//
|
||||||
@@ -262,6 +262,46 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
|
|
||||||
return IrSetVariableImpl(startOffset, endOffset, descriptor, value, origin) // Create SetVariable expression for the new descriptor.
|
return IrSetVariableImpl(startOffset, endOffset, descriptor, value, origin) // Create SetVariable expression for the new descriptor.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
|
||||||
|
val irCall = super.visitCall(expression) as IrCall
|
||||||
|
if (irCall !is IrCallImpl) return irCall
|
||||||
|
|
||||||
|
val oldTypeArguments = (irCall as IrMemberAccessExpressionBase).typeArguments
|
||||||
|
|
||||||
|
val substitutionContext = typeArgsMap!!.entries.associate {
|
||||||
|
(typeParameter, typeArgument) ->
|
||||||
|
typeParameter.typeConstructor to TypeProjectionImpl(typeArgument)
|
||||||
|
}
|
||||||
|
val typeSubstitutor = TypeSubstitutor.create(substitutionContext)
|
||||||
|
|
||||||
|
val newTypeArguments = oldTypeArguments!!.map {
|
||||||
|
val typeParameterDescriptor = it.key
|
||||||
|
val oldTypeArgument = it.value
|
||||||
|
val newTypeArgument = typeSubstitutor.substitute(oldTypeArgument, Variance.INVARIANT) ?: oldTypeArgument
|
||||||
|
typeParameterDescriptor to newTypeArgument
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
val descriptor = irCall.descriptor
|
||||||
|
val type = typeSubstitutor.substitute(irCall.type, Variance.INVARIANT) ?: irCall.type
|
||||||
|
val startOffset = irCall.startOffset
|
||||||
|
val endOffset = irCall.endOffset
|
||||||
|
val origin = irCall.origin
|
||||||
|
val superQualifier = irCall.superQualifier
|
||||||
|
|
||||||
|
return IrCallImpl(startOffset, endOffset, type, descriptor, newTypeArguments, origin, superQualifier)
|
||||||
|
.apply {
|
||||||
|
descriptor.valueParameters.forEach {
|
||||||
|
val valueArgument = irCall.getValueArgument(it)
|
||||||
|
putValueArgument(it.index, valueArgument)
|
||||||
|
}
|
||||||
|
extensionReceiver = irCall.extensionReceiver
|
||||||
|
dispatchReceiver = irCall.dispatchReceiver
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
@@ -369,21 +409,22 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
class InlineCopyIr() : DeepCopyIrTree() {
|
class InlineCopyIr() : DeepCopyIrTree() {
|
||||||
|
|
||||||
override fun visitBlock(expression: IrBlock): IrBlock {
|
override fun visitBlock(expression: IrBlock): IrBlock {
|
||||||
|
return when(expression) {
|
||||||
|
is IrInlineFunctionBody ->
|
||||||
|
IrInlineFunctionBody(
|
||||||
|
expression.startOffset, expression.endOffset,
|
||||||
|
expression.type,
|
||||||
|
mapStatementOrigin(expression.origin),
|
||||||
|
expression.statements.map { it.transform(this, null) }
|
||||||
|
)
|
||||||
|
|
||||||
if (expression is IrInlineFunctionBody)
|
else -> IrBlockImpl(
|
||||||
return IrInlineFunctionBody(
|
expression.startOffset, expression.endOffset,
|
||||||
expression.startOffset, expression.endOffset,
|
expression.type,
|
||||||
expression.type,
|
mapStatementOrigin(expression.origin),
|
||||||
mapStatementOrigin(expression.origin),
|
expression.statements.map { it.transform(this, null) }
|
||||||
expression.statements.map { it.transform(this, null) }
|
)
|
||||||
)
|
}
|
||||||
|
|
||||||
return IrBlockImpl(
|
|
||||||
expression.startOffset, expression.endOffset,
|
|
||||||
expression.type,
|
|
||||||
mapStatementOrigin(expression.origin),
|
|
||||||
expression.statements.map { it.transform(this, null) }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user