PSI2IR fix SOE in testKt47450 (again)
This commit is contained in:
+1
-1
@@ -140,7 +140,7 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
||||
is SuperCallReceiverValue ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.thisType.constructor.declarationDescriptor as ClassDescriptor)
|
||||
is ExpressionReceiver ->
|
||||
generateExpression(receiver.expression)
|
||||
generateStatement(receiver.expression) as IrExpression
|
||||
is ExtensionReceiver -> {
|
||||
IrGetValueImpl(
|
||||
defaultStartOffset, defaultStartOffset, irReceiverType,
|
||||
|
||||
@@ -306,7 +306,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateFunctionCall(
|
||||
internal fun generateFunctionCall(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
|
||||
+16
-10
@@ -25,7 +25,9 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltInsOverDescriptors
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -527,15 +529,19 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateBinaryOperatorAsCall(expression: KtBinaryExpression, origin: IrStatementOrigin?): IrExpression =
|
||||
if (isDynamicBinaryOperator(expression))
|
||||
generateDynamicBinaryExpression(expression)
|
||||
else
|
||||
CallGenerator(statementGenerator)
|
||||
.generateCall(
|
||||
expression.startOffsetSkippingComments, expression.endOffset,
|
||||
statementGenerator.pregenerateCall(getResolvedCall(expression)!!), origin
|
||||
)
|
||||
private fun generateBinaryOperatorAsCall(expression: KtBinaryExpression, origin: IrStatementOrigin?): IrExpression {
|
||||
if (isDynamicBinaryOperator(expression)) {
|
||||
return generateDynamicBinaryExpression(expression)
|
||||
}
|
||||
val callBuilder = statementGenerator.pregenerateCall(getResolvedCall(expression)!!)
|
||||
return CallGenerator(statementGenerator).generateFunctionCall(
|
||||
callBuilder.descriptor as? FunctionDescriptor
|
||||
?: throw AssertionError("Operator call resolved to a non-function: ${callBuilder.descriptor}"),
|
||||
expression.startOffsetSkippingComments, expression.endOffset,
|
||||
origin,
|
||||
callBuilder
|
||||
)
|
||||
}
|
||||
|
||||
private fun generatePrefixOperatorAsCall(expression: KtPrefixExpression, origin: IrStatementOrigin): IrExpression {
|
||||
val resolvedCall = getResolvedCall(expression)!!
|
||||
|
||||
@@ -84,11 +84,11 @@ val CallBuilder.explicitReceiverType: KotlinType?
|
||||
fun CallBuilder.setExplicitReceiverValue(explicitReceiverValue: IntermediateValue) {
|
||||
val previousCallReceiver = callReceiver
|
||||
callReceiver = object : CallReceiver {
|
||||
override fun call(withDispatchAndExtensionAndContextReceivers: (IntermediateValue?, IntermediateValue?, List<IntermediateValue>) -> IrExpression): IrExpression {
|
||||
override fun call(builder: CallExpressionBuilder): IrExpression {
|
||||
return previousCallReceiver.call { dispatchReceiverValue, _, contextReceiverValues ->
|
||||
val newDispatchReceiverValue = if (hasExtensionReceiver) dispatchReceiverValue else explicitReceiverValue
|
||||
val newExtensionReceiverValue = if (hasExtensionReceiver) explicitReceiverValue else null
|
||||
withDispatchAndExtensionAndContextReceivers(newDispatchReceiverValue, newExtensionReceiverValue, contextReceiverValues)
|
||||
builder.withReceivers(newDispatchReceiverValue, newExtensionReceiverValue, contextReceiverValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -23,8 +23,7 @@ class ExtensionInvokeCallReceiver(
|
||||
private val functionReceiver: IntermediateValue,
|
||||
private val extensionInvokeReceiver: IntermediateValue
|
||||
) : CallReceiver {
|
||||
|
||||
override fun call(withDispatchAndExtensionAndContextReceivers: (IntermediateValue?, IntermediateValue?, List<IntermediateValue>) -> IrExpression): IrExpression {
|
||||
override fun call(builder: CallExpressionBuilder): IrExpression {
|
||||
// extensionInvokeReceiver is actually a first argument:
|
||||
// receiver.extFun(p1, ..., pN)
|
||||
// =>
|
||||
@@ -34,6 +33,6 @@ class ExtensionInvokeCallReceiver(
|
||||
"Extension 'invoke' call should have null as its 1st value argument, got: ${callBuilder.irValueArgumentsByIndex[0]}"
|
||||
}
|
||||
callBuilder.irValueArgumentsByIndex[0] = extensionInvokeReceiver.load()
|
||||
return withDispatchAndExtensionAndContextReceivers(functionReceiver, null, emptyList())
|
||||
return builder.withReceivers(functionReceiver, null, emptyList())
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ fun IrVariable.loadAt(startOffset: Int, endOffset: Int): IrExpression =
|
||||
|
||||
fun CallReceiver.adjustForCallee(callee: CallableMemberDescriptor): CallReceiver =
|
||||
object : CallReceiver {
|
||||
override fun call(withDispatchAndExtensionAndContextReceivers: (IntermediateValue?, IntermediateValue?, List<IntermediateValue>) -> IrExpression): IrExpression =
|
||||
override fun call(builder: CallExpressionBuilder): IrExpression =
|
||||
this@adjustForCallee.call { dispatchReceiverValue, extensionReceiverValue, contextReceiverValues ->
|
||||
val numReceiversPresent = listOfNotNull(dispatchReceiverValue, extensionReceiverValue).size
|
||||
val numReceiversExpected = listOfNotNull(callee.dispatchReceiverParameter, callee.extensionReceiverParameter).size
|
||||
@@ -46,7 +46,7 @@ fun CallReceiver.adjustForCallee(callee: CallableMemberDescriptor): CallReceiver
|
||||
dispatchReceiverValue != null && callee.dispatchReceiverParameter == null -> dispatchReceiverValue
|
||||
else -> extensionReceiverValue
|
||||
}
|
||||
withDispatchAndExtensionAndContextReceivers(newDispatchReceiverValue, newExtensionReceiverValue, contextReceiverValues)
|
||||
builder.withReceivers(newDispatchReceiverValue, newExtensionReceiverValue, contextReceiverValues)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -35,8 +35,7 @@ class SafeCallReceiver(
|
||||
val dispatchReceiver: IntermediateValue?,
|
||||
val isStatement: Boolean
|
||||
) : CallReceiver {
|
||||
|
||||
override fun call(withDispatchAndExtensionAndContextReceivers: (IntermediateValue?, IntermediateValue?, List<IntermediateValue>) -> IrExpression): IrExpression {
|
||||
override fun call(builder: CallExpressionBuilder): IrExpression {
|
||||
val irTmp = generator.scope.createTemporaryVariable(extensionReceiver?.load() ?: dispatchReceiver!!.load(), "safe_receiver")
|
||||
val safeReceiverValue = VariableLValue(generator.context, irTmp)
|
||||
|
||||
@@ -50,7 +49,7 @@ class SafeCallReceiver(
|
||||
extensionReceiverValue = null
|
||||
}
|
||||
|
||||
val irResult = withDispatchAndExtensionAndContextReceivers(dispatchReceiverValue, extensionReceiverValue, contextReceivers)
|
||||
val irResult = builder.withReceivers(dispatchReceiverValue, extensionReceiverValue, contextReceivers)
|
||||
|
||||
val resultType = if (isStatement) generator.context.irBuiltIns.unitType else irResult.type.makeNullable()
|
||||
|
||||
|
||||
+2
-3
@@ -32,8 +32,7 @@ class SafeExtensionInvokeCallReceiver(
|
||||
val functionReceiver: IntermediateValue,
|
||||
val extensionInvokeReceiver: IntermediateValue
|
||||
) : CallReceiver {
|
||||
|
||||
override fun call(withDispatchAndExtensionAndContextReceivers: (IntermediateValue?, IntermediateValue?, List<IntermediateValue>) -> IrExpression): IrExpression {
|
||||
override fun call(builder: CallExpressionBuilder): IrExpression {
|
||||
// extensionInvokeReceiver is actually a first argument:
|
||||
// receiver?.extFun(p1, ..., pN)
|
||||
// =>
|
||||
@@ -49,7 +48,7 @@ class SafeExtensionInvokeCallReceiver(
|
||||
"Safe extension 'invoke' call should have null as its 1st value argument, got: ${callBuilder.irValueArgumentsByIndex[0]}"
|
||||
}
|
||||
callBuilder.irValueArgumentsByIndex[0] = safeReceiverValue.load()
|
||||
val irResult = withDispatchAndExtensionAndContextReceivers(functionReceiver, null, emptyList())
|
||||
val irResult = builder.withReceivers(functionReceiver, null, emptyList())
|
||||
|
||||
val resultType = irResult.type.makeNullable()
|
||||
|
||||
|
||||
+2
-3
@@ -23,8 +23,7 @@ class SimpleCallReceiver(
|
||||
private val extensionReceiverValue: IntermediateValue?,
|
||||
private val contextReceiverValues: List<IntermediateValue>
|
||||
) : CallReceiver {
|
||||
|
||||
override fun call(withDispatchAndExtensionAndContextReceivers: (IntermediateValue?, IntermediateValue?, List<IntermediateValue>) -> IrExpression): IrExpression {
|
||||
return withDispatchAndExtensionAndContextReceivers(dispatchReceiverValue, extensionReceiverValue, contextReceiverValues)
|
||||
override fun call(builder: CallExpressionBuilder): IrExpression {
|
||||
return builder.withReceivers(dispatchReceiverValue, extensionReceiverValue, contextReceiverValues)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IntermediateValue {
|
||||
fun load(): IrExpression
|
||||
@@ -35,6 +34,14 @@ interface AssignmentReceiver {
|
||||
fun assign(value: IrExpression): IrExpression = assign { it.store(value) }
|
||||
}
|
||||
|
||||
interface CallReceiver {
|
||||
fun call(withDispatchAndExtensionAndContextReceivers: (IntermediateValue?, IntermediateValue?, List<IntermediateValue>) -> IrExpression): IrExpression
|
||||
fun interface CallExpressionBuilder {
|
||||
fun withReceivers(
|
||||
dispatchReceiver: IntermediateValue?,
|
||||
extensionReceiver: IntermediateValue?,
|
||||
contextReceivers: List<IntermediateValue>
|
||||
): IrExpression
|
||||
}
|
||||
|
||||
interface CallReceiver {
|
||||
fun call(builder: CallExpressionBuilder): IrExpression
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user