PSI2IR: SAM conversion should be performed once for index variables

Given esoteric code as in 'caoWithAdaptationForSam.kt', we should make
sure that we pass same objects to 'get' and 'set'.
This commit is contained in:
Dmitry Petrov
2020-01-28 17:12:50 +03:00
parent e750528551
commit bf9673a0a2
14 changed files with 689 additions and 125 deletions
@@ -1354,6 +1354,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/expressions/callableReferences/boundInnerGenericConstructor.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/boundInnerGenericConstructor.kt");
} }
@TestMetadata("caoWithAdaptationForSam.kt")
public void testCaoWithAdaptationForSam() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.kt");
}
@TestMetadata("constructorWithAdaptedArguments.kt") @TestMetadata("constructorWithAdaptedArguments.kt")
public void testConstructorWithAdaptedArguments() throws Exception { public void testConstructorWithAdaptedArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.kt");
@@ -1369,11 +1374,6 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/expressions/callableReferences/importedFromObject.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/importedFromObject.kt");
} }
@TestMetadata("letArrayOf.kt")
public void testLetArrayOf() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/letArrayOf.kt");
}
@TestMetadata("typeArguments.kt") @TestMetadata("typeArguments.kt")
public void testTypeArguments() throws Exception { public void testTypeArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/typeArguments.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/typeArguments.kt");
@@ -1384,6 +1384,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.kt");
} }
@TestMetadata("withAdaptationForSam.kt")
public void testWithAdaptationForSam() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withAdaptationForSam.kt");
}
@TestMetadata("withAdaptedArguments.kt") @TestMetadata("withAdaptedArguments.kt")
public void testWithAdaptedArguments() throws Exception { public void testWithAdaptedArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withAdaptedArguments.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/withAdaptedArguments.kt");
@@ -17,11 +17,18 @@
package org.jetbrains.kotlin.psi2ir.intermediate package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.inlineStatement import org.jetbrains.kotlin.ir.expressions.impl.inlineStatement
import org.jetbrains.kotlin.ir.expressions.isAssignmentOperatorWithResult import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
import org.jetbrains.kotlin.psi2ir.generators.generateSamConversionForValueArgumentsIfRequired import org.jetbrains.kotlin.psi2ir.generators.generateSamConversionForValueArgumentsIfRequired
@@ -29,6 +36,7 @@ import org.jetbrains.kotlin.psi2ir.generators.pregenerateValueArgumentsUsing
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
class ArrayAccessAssignmentReceiver( class ArrayAccessAssignmentReceiver(
private val irArray: IrExpression, private val irArray: IrExpression,
@@ -47,6 +55,10 @@ class ArrayAccessAssignmentReceiver(
private val indexedGetDescriptor = indexedGetResolvedCall?.resultingDescriptor private val indexedGetDescriptor = indexedGetResolvedCall?.resultingDescriptor
private val indexedSetDescriptor = indexedSetResolvedCall?.resultingDescriptor private val indexedSetDescriptor = indexedSetResolvedCall?.resultingDescriptor
private class CompoundAssignmentInfo {
val indexVariables = LinkedHashSet<IrVariable>()
}
private val descriptor = private val descriptor =
indexedGetDescriptor indexedGetDescriptor
?: indexedSetDescriptor ?: indexedSetDescriptor
@@ -74,17 +86,132 @@ class ArrayAccessAssignmentReceiver(
val irArrayValue = callGenerator.scope.createTemporaryVariableInBlock(callGenerator.context, irArray, irBlock, "array") val irArrayValue = callGenerator.scope.createTemporaryVariableInBlock(callGenerator.context, irArray, irBlock, "array")
val compoundAssignmentInfo = CompoundAssignmentInfo()
irBlock.inlineStatement( irBlock.inlineStatement(
withLValue( withLValue(
createLValue(kotlinType, irArrayValue) { i, irIndex -> createLValue(kotlinType, irArrayValue) { i, irIndex ->
callGenerator.scope.createTemporaryVariableInBlock(callGenerator.context, irIndex, irBlock, "index$i") val irIndexVar = callGenerator.scope.createTemporaryVariable(irIndex, "index$i")
compoundAssignmentInfo.indexVariables.add(irIndexVar)
irBlock.statements.add(irIndexVar)
VariableLValue(callGenerator.context, irIndexVar)
} }
) )
) )
postprocessSamConversionsInCompoundAssignment(irBlock, compoundAssignmentInfo)
return irBlock return irBlock
} }
private fun postprocessSamConversionsInCompoundAssignment(
irBlock: IrBlock,
compoundAssignmentInfo: CompoundAssignmentInfo
) {
val samConversionsCollector = SamConversionsCollector(compoundAssignmentInfo)
irBlock.acceptChildrenVoid(samConversionsCollector)
if (samConversionsCollector.samConversionsPerVariable.isEmpty()) return
val samConvertedVars = hashMapOf<IrVariable, IrVariable>()
for ((irIndexVar, samConversions) in samConversionsCollector.samConversionsPerVariable) {
var mostSpecificSamConversion: IrTypeOperatorCall = samConversions.first()
for (samConversion in samConversions) {
if (samConversion === mostSpecificSamConversion) continue
val lastType = mostSpecificSamConversion.operandKotlinType
val nextType = samConversion.operandKotlinType
if (KotlinTypeChecker.DEFAULT.isSubtypeOf(nextType, lastType)) {
mostSpecificSamConversion = samConversion
} else if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(lastType, nextType)) {
throw AssertionError("Unrelated types in SAM conversion for index variable: $lastType, $nextType")
}
}
val irSamConvertedVarInitializer = createSamConvertedVarInitializer(irIndexVar, mostSpecificSamConversion)
val irSamConvertedVar = callGenerator.scope.createTemporaryVariable(irSamConvertedVarInitializer, "sam")
val index = irBlock.statements.indexOf(irIndexVar)
irBlock.statements[index] = irSamConvertedVar
samConvertedVars[irIndexVar] = irSamConvertedVar
}
irBlock.transformChildrenVoid(SamConversionsRewriter(samConvertedVars))
}
private fun createSamConvertedVarInitializer(irIndexVar: IrVariable, mostSpecificSamConversion: IrTypeOperatorCall): IrExpression {
val irIndexVarInitializer = irIndexVar.initializer!!
val startOffset = irIndexVarInitializer.startOffset
val endOffset = irIndexVarInitializer.endOffset
val implicitCast = mostSpecificSamConversion.argument as IrTypeOperatorCall
return IrTypeOperatorCallImpl(
startOffset, endOffset,
mostSpecificSamConversion.type,
IrTypeOperator.SAM_CONVERSION,
mostSpecificSamConversion.typeOperand,
IrTypeOperatorCallImpl(
startOffset, endOffset,
implicitCast.type,
IrTypeOperator.IMPLICIT_CAST,
implicitCast.typeOperand,
irIndexVarInitializer
)
)
}
private val IrTypeOperatorCall.operandKotlinType
get() = typeOperand.originalKotlinType!!
private class SamConversionsCollector(
private val compoundAssignmentInfo: CompoundAssignmentInfo
) : IrElementVisitorVoid {
val samConversionsPerVariable = HashMap<IrVariable, MutableList<IrTypeOperatorCall>>()
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitTypeOperator(expression: IrTypeOperatorCall) {
expression.acceptChildrenVoid(this)
val irGetVar = expression.getSamConvertedGetValue()
if (irGetVar != null) {
val valueDeclaration = irGetVar.symbol.owner
if (valueDeclaration is IrVariable && valueDeclaration in compoundAssignmentInfo.indexVariables) {
samConversionsPerVariable.getOrPut(valueDeclaration) { ArrayList() }.add(expression)
}
}
}
}
private class SamConversionsRewriter(
private val replacementVars: Map<IrVariable, IrVariable>
) : IrElementTransformerVoid() {
override fun visitElement(element: IrElement): IrElement {
return element.apply { transformChildrenVoid() }
}
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
val irGetVar = expression.getSamConvertedGetValue()
if (irGetVar != null) {
val valueDeclaration = irGetVar.symbol.owner
val replacementVar = replacementVars[valueDeclaration]
if (replacementVar != null) {
return IrGetValueImpl(expression.startOffset, expression.endOffset, replacementVar.symbol, null)
}
}
return expression.apply { transformChildrenVoid() }
}
override fun visitGetValue(expression: IrGetValue): IrExpression {
val symbol = expression.symbol
if (symbol.owner in replacementVars) {
throw AssertionError(
"SAM-converted index variable ${symbol.descriptor} is present in get/set calls in non-converted"
)
}
return expression
}
}
private fun createLValue( private fun createLValue(
kotlinType: KotlinType, kotlinType: KotlinType,
irArrayValue: IntermediateValue, irArrayValue: IntermediateValue,
@@ -126,4 +253,17 @@ class ArrayAccessAssignmentReceiver(
value?.let { lastArgument = it } value?.let { lastArgument = it }
callGenerator.statementGenerator.generateSamConversionForValueArgumentsIfRequired(this, resolvedCall) callGenerator.statementGenerator.generateSamConversionForValueArgumentsIfRequired(this, resolvedCall)
} }
companion object {
internal fun IrTypeOperatorCall.getSamConvertedGetValue(): IrGetValue? {
if (operator != IrTypeOperator.SAM_CONVERSION) return null
val arg0 = argument
if (arg0 !is IrTypeOperatorCall) return null
if (arg0.operator != IrTypeOperator.IMPLICIT_CAST) return null
val arg1 = arg0.argument
if (arg1 !is IrGetValue) return null
if (arg1.symbol.owner !is IrVariable) return null
return arg1
}
}
} }
@@ -23,14 +23,14 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
class LValueWithGetterAndSetterCalls( class LValueWithGetterAndSetterCalls(
val callGenerator: CallGenerator, private val callGenerator: CallGenerator,
val descriptor: CallableDescriptor, private val descriptor: CallableDescriptor,
val getterCall: () -> CallBuilder?, private val getterCall: () -> CallBuilder?,
val setterCall: (IrExpression) -> CallBuilder?, private val setterCall: (IrExpression) -> CallBuilder?,
override val type: IrType, override val type: IrType,
val startOffset: Int, private val startOffset: Int,
val endOffset: Int, private val endOffset: Int,
val origin: IrStatementOrigin? = null private val origin: IrStatementOrigin? = null
) : LValue { ) : LValue {
override fun load(): IrExpression { override fun load(): IrExpression {
@@ -0,0 +1,137 @@
FILE fqName:<root> fileName:/caoWithAdaptationForSam.kt
CLASS INTERFACE name:IFoo modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.IFoo
FUN name:foo visibility:public modality:ABSTRACT <> ($this:<root>.IFoo, i:kotlin.Int) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.IFoo
VALUE_PARAMETER name:i index:0 type:kotlin.Int
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS INTERFACE name:IFoo2 modality:ABSTRACT visibility:public superTypes:[<root>.IFoo]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.IFoo2
FUN FAKE_OVERRIDE name:foo visibility:public modality:ABSTRACT <> ($this:<root>.IFoo, i:kotlin.Int) returnType:kotlin.Unit [fake_override]
overridden:
public abstract fun foo (i: kotlin.Int): kotlin.Unit declared in <root>.IFoo
$this: VALUE_PARAMETER name:<this> type:<root>.IFoo
VALUE_PARAMETER name:i index:0 type:kotlin.Int
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.A
CONSTRUCTOR visibility:private <> () returnType:<root>.A [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS OBJECT name:B modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.B
CONSTRUCTOR visibility:private <> () returnType:<root>.B [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:B modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:get visibility:public modality:FINAL <> ($receiver:<root>.A, i:<root>.IFoo) returnType:kotlin.Int [operator]
$receiver: VALUE_PARAMETER name:<this> type:<root>.A
VALUE_PARAMETER name:i index:0 type:<root>.IFoo
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>'
CONST Int type=kotlin.Int value=1
FUN name:set visibility:public modality:FINAL <> ($receiver:<root>.A, i:<root>.IFoo, newValue:kotlin.Int) returnType:kotlin.Unit [operator]
$receiver: VALUE_PARAMETER name:<this> type:<root>.A
VALUE_PARAMETER name:i index:0 type:<root>.IFoo
VALUE_PARAMETER name:newValue index:1 type:kotlin.Int
BLOCK_BODY
FUN name:get visibility:public modality:FINAL <> ($receiver:<root>.B, i:<root>.IFoo) returnType:kotlin.Int [operator]
$receiver: VALUE_PARAMETER name:<this> type:<root>.B
VALUE_PARAMETER name:i index:0 type:<root>.IFoo
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>'
CONST Int type=kotlin.Int value=1
FUN name:set visibility:public modality:FINAL <> ($receiver:<root>.B, i:<root>.IFoo2, newValue:kotlin.Int) returnType:kotlin.Unit [operator]
$receiver: VALUE_PARAMETER name:<this> type:<root>.B
VALUE_PARAMETER name:i index:0 type:<root>.IFoo2
VALUE_PARAMETER name:newValue index:1 type:kotlin.Int
BLOCK_BODY
FUN name:withVararg visibility:public modality:FINAL <> (xs:kotlin.IntArray) returnType:kotlin.Int
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun withVararg (xs: kotlin.IntArray): kotlin.Int declared in <root>'
CONST Int type=kotlin.Int value=42
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
ERROR_CALL 'FirArraySetCall (resolve isn't supported yet)' type=kotlin.Unit
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
ERROR_CALL 'FirArraySetCall (resolve isn't supported yet)' type=kotlin.Unit
FUN name:test3 visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'FirArraySetCall (resolve isn't supported yet)' type=kotlin.Unit
FUN name:test4 visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
WHEN type=kotlin.Unit origin=IF
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.IFoo
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.test4' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
then: BLOCK type=kotlin.Unit origin=null
ERROR_CALL 'FirArraySetCall (resolve isn't supported yet)' type=kotlin.Unit
FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Any
BLOCK_BODY
TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.test5' type=kotlin.Any origin=null
ERROR_CALL 'FirArraySetCall (resolve isn't supported yet)' type=kotlin.Unit
FUN name:test6 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Any
BLOCK_BODY
TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.test6' type=kotlin.Any origin=null
TYPE_OP type=<root>.IFoo origin=CAST typeOperand=<root>.IFoo
GET_VAR 'a: kotlin.Any declared in <root>.test6' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
ERROR_CALL 'FirArraySetCall (resolve isn't supported yet)' type=kotlin.Unit
@@ -0,0 +1,47 @@
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
fun interface IFoo {
fun foo(i: Int)
}
fun interface IFoo2 : IFoo
object A
object B
operator fun A.get(i: IFoo) = 1
operator fun A.set(i: IFoo, newValue: Int) {}
operator fun B.get(i: IFoo) = 1
operator fun B.set(i: IFoo2, newValue: Int) {}
fun withVararg(vararg xs: Int) = 42
fun test1() {
A[::withVararg] += 1
}
fun test2() {
B[::withVararg] += 1
}
fun test3(fn: (Int) -> Unit) {
A[fn] += 1
}
fun test4(fn: (Int) -> Unit) {
if (fn is IFoo) {
A[fn] += 1
}
}
fun test5(a: Any) {
a as (Int) -> Unit
A[a] += 1
}
fun test6(a: Any) {
a as (Int) -> Unit
a as IFoo
A[a] += 1
}
@@ -0,0 +1,237 @@
FILE fqName:<root> fileName:/caoWithAdaptationForSam.kt
CLASS INTERFACE name:IFoo modality:ABSTRACT visibility:public [fun] superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.IFoo
FUN name:foo visibility:public modality:ABSTRACT <> ($this:<root>.IFoo, i:kotlin.Int) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.IFoo
VALUE_PARAMETER name:i index:0 type:kotlin.Int
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS INTERFACE name:IFoo2 modality:ABSTRACT visibility:public [fun] superTypes:[<root>.IFoo]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.IFoo2
FUN FAKE_OVERRIDE name:foo visibility:public modality:ABSTRACT <> ($this:<root>.IFoo, i:kotlin.Int) returnType:kotlin.Unit [fake_override]
overridden:
public abstract fun foo (i: kotlin.Int): kotlin.Unit declared in <root>.IFoo
$this: VALUE_PARAMETER name:<this> type:<root>.IFoo
VALUE_PARAMETER name:i index:0 type:kotlin.Int
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in <root>.IFoo
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int [fake_override] declared in <root>.IFoo
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String [fake_override] declared in <root>.IFoo
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.A
CONSTRUCTOR visibility:private <> () returnType:<root>.A [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS OBJECT name:B modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.B
CONSTRUCTOR visibility:private <> () returnType:<root>.B [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:B modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:get visibility:public modality:FINAL <> ($receiver:<root>.A, i:<root>.IFoo) returnType:kotlin.Int [operator]
$receiver: VALUE_PARAMETER name:<this> type:<root>.A
VALUE_PARAMETER name:i index:0 type:<root>.IFoo
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>'
CONST Int type=kotlin.Int value=1
FUN name:set visibility:public modality:FINAL <> ($receiver:<root>.A, i:<root>.IFoo, newValue:kotlin.Int) returnType:kotlin.Unit [operator]
$receiver: VALUE_PARAMETER name:<this> type:<root>.A
VALUE_PARAMETER name:i index:0 type:<root>.IFoo
VALUE_PARAMETER name:newValue index:1 type:kotlin.Int
BLOCK_BODY
FUN name:get visibility:public modality:FINAL <> ($receiver:<root>.B, i:<root>.IFoo) returnType:kotlin.Int [operator]
$receiver: VALUE_PARAMETER name:<this> type:<root>.B
VALUE_PARAMETER name:i index:0 type:<root>.IFoo
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>'
CONST Int type=kotlin.Int value=1
FUN name:set visibility:public modality:FINAL <> ($receiver:<root>.B, i:<root>.IFoo2, newValue:kotlin.Int) returnType:kotlin.Unit [operator]
$receiver: VALUE_PARAMETER name:<this> type:<root>.B
VALUE_PARAMETER name:i index:0 type:<root>.IFoo2
VALUE_PARAMETER name:newValue index:1 type:kotlin.Int
BLOCK_BODY
FUN name:withVararg visibility:public modality:FINAL <> (xs:kotlin.IntArray) returnType:kotlin.Int
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray varargElementType:kotlin.Int [vararg]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun withVararg (vararg xs: kotlin.Int): kotlin.Int declared in <root>'
CONST Int type=kotlin.Int value=42
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
BLOCK type=kotlin.Unit origin=PLUSEQ
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.A [val]
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.IFoo [val]
TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun withVararg (vararg xs: kotlin.Int): kotlin.Int declared in <root>' type=kotlin.Int origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.test1.withVararg' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.test1' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null reflectionTarget=null
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=PLUSEQ
$receiver: GET_VAR 'val tmp_0: <root>.A [val] declared in <root>.test1' type=<root>.A origin=null
i: GET_VAR 'val tmp_1: <root>.IFoo [val] declared in <root>.test1' type=<root>.IFoo origin=null
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUSEQ
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=PLUSEQ
$receiver: GET_VAR 'val tmp_0: <root>.A [val] declared in <root>.test1' type=<root>.A origin=null
i: GET_VAR 'val tmp_1: <root>.IFoo [val] declared in <root>.test1' type=<root>.IFoo origin=null
other: CONST Int type=kotlin.Int value=1
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
BLOCK type=kotlin.Unit origin=PLUSEQ
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.B [val]
GET_OBJECT 'CLASS OBJECT name:B modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.B
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:<root>.IFoo2 [val]
TYPE_OP type=<root>.IFoo2 origin=SAM_CONVERSION typeOperand=<root>.IFoo2
BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun withVararg (vararg xs: kotlin.Int): kotlin.Int declared in <root>' type=kotlin.Int origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.test2.withVararg' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.test2' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null reflectionTarget=null
CALL 'public final fun set (i: <root>.IFoo2, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=PLUSEQ
$receiver: GET_VAR 'val tmp_2: <root>.B [val] declared in <root>.test2' type=<root>.B origin=null
i: GET_VAR 'val tmp_3: <root>.IFoo2 [val] declared in <root>.test2' type=<root>.IFoo2 origin=null
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUSEQ
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=PLUSEQ
$receiver: GET_VAR 'val tmp_2: <root>.B [val] declared in <root>.test2' type=<root>.B origin=null
i: GET_VAR 'val tmp_3: <root>.IFoo2 [val] declared in <root>.test2' type=<root>.IFoo2 origin=null
other: CONST Int type=kotlin.Int value=1
FUN name:test3 visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
BLOCK type=kotlin.Unit origin=PLUSEQ
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:<root>.A [val]
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:<root>.IFoo [val]
TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.test3' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=PLUSEQ
$receiver: GET_VAR 'val tmp_4: <root>.A [val] declared in <root>.test3' type=<root>.A origin=null
i: GET_VAR 'val tmp_5: <root>.IFoo [val] declared in <root>.test3' type=<root>.IFoo origin=null
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUSEQ
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=PLUSEQ
$receiver: GET_VAR 'val tmp_4: <root>.A [val] declared in <root>.test3' type=<root>.A origin=null
i: GET_VAR 'val tmp_5: <root>.IFoo [val] declared in <root>.test3' type=<root>.IFoo origin=null
other: CONST Int type=kotlin.Int value=1
FUN name:test4 visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
WHEN type=kotlin.Unit origin=IF
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.IFoo
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.test4' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
then: BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Unit origin=PLUSEQ
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:<root>.A [val]
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.test4' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=PLUSEQ
$receiver: GET_VAR 'val tmp_6: <root>.A [val] declared in <root>.test4' type=<root>.A origin=null
i: TYPE_OP type=<root>.IFoo origin=IMPLICIT_CAST typeOperand=<root>.IFoo
GET_VAR 'val tmp_7: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test4' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUSEQ
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=PLUSEQ
$receiver: GET_VAR 'val tmp_6: <root>.A [val] declared in <root>.test4' type=<root>.A origin=null
i: TYPE_OP type=<root>.IFoo origin=IMPLICIT_CAST typeOperand=<root>.IFoo
GET_VAR 'val tmp_7: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test4' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
other: CONST Int type=kotlin.Int value=1
FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Any
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.test5' type=kotlin.Any origin=null
BLOCK type=kotlin.Unit origin=PLUSEQ
VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:<root>.A [val]
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:<root>.IFoo [val]
TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'i')] kotlin.Int, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'i')] kotlin.Int, kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.test5' type=kotlin.Any origin=null
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=PLUSEQ
$receiver: GET_VAR 'val tmp_8: <root>.A [val] declared in <root>.test5' type=<root>.A origin=null
i: GET_VAR 'val tmp_9: <root>.IFoo [val] declared in <root>.test5' type=<root>.IFoo origin=null
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUSEQ
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=PLUSEQ
$receiver: GET_VAR 'val tmp_8: <root>.A [val] declared in <root>.test5' type=<root>.A origin=null
i: GET_VAR 'val tmp_9: <root>.IFoo [val] declared in <root>.test5' type=<root>.IFoo origin=null
other: CONST Int type=kotlin.Int value=1
FUN name:test6 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Any
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.test6' type=kotlin.Any origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
TYPE_OP type=<root>.IFoo origin=CAST typeOperand=<root>.IFoo
GET_VAR 'a: kotlin.Any declared in <root>.test6' type=kotlin.Any origin=null
BLOCK type=kotlin.Unit origin=PLUSEQ
VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:<root>.A [val]
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlin.Any [val]
GET_VAR 'a: kotlin.Any declared in <root>.test6' type=kotlin.Any origin=null
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=PLUSEQ
$receiver: GET_VAR 'val tmp_10: <root>.A [val] declared in <root>.test6' type=<root>.A origin=null
i: TYPE_OP type=<root>.IFoo origin=IMPLICIT_CAST typeOperand=<root>.IFoo
GET_VAR 'val tmp_11: kotlin.Any [val] declared in <root>.test6' type=kotlin.Any origin=null
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUSEQ
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=PLUSEQ
$receiver: GET_VAR 'val tmp_10: <root>.A [val] declared in <root>.test6' type=<root>.A origin=null
i: TYPE_OP type=<root>.IFoo origin=IMPLICIT_CAST typeOperand=<root>.IFoo
GET_VAR 'val tmp_11: kotlin.Any [val] declared in <root>.test6' type=kotlin.Any origin=null
other: CONST Int type=kotlin.Int value=1
@@ -1,6 +0,0 @@
FILE fqName:<root> fileName:/letArrayOf.kt
FUN name:test visibility:public modality:FINAL <> () returnType:IrErrorType
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test (): IrErrorType declared in <root>'
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/let]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun arrayOf <T> (elements: kotlin.Array<out T of kotlin.arrayOf>): kotlin.Array<T of kotlin.arrayOf> [inline] declared in kotlin' type=kotlin.reflect.KFunction1<kotlin.Array<out kotlin.Any?>, kotlin.Array<kotlin.Any?>> origin=null reflectionTarget=<same>
@@ -1,3 +0,0 @@
// !LANGUAGE: +NewInference
fun test() = "OK".let(::arrayOf)
@@ -1,18 +0,0 @@
FILE fqName:<root> fileName:/letArrayOf.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Array<kotlin.String>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test (): kotlin.Array<kotlin.String> declared in <root>'
CALL 'public final fun let <T, R> (block: kotlin.Function1<T of kotlin.let, R of kotlin.let>): R of kotlin.let [inline] declared in kotlin' type=kotlin.Array<kotlin.String> origin=null
<T>: kotlin.String
<R>: kotlin.Array<kotlin.String>
$receiver: CONST String type=kotlin.String value="OK"
block: BLOCK type=kotlin.reflect.KFunction1<kotlin.String, kotlin.Array<kotlin.String>> origin=null
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:arrayOf visibility:local modality:FINAL <> (p0:kotlin.String) returnType:kotlin.Array<kotlin.String> [inline]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun arrayOf (p0: kotlin.String): kotlin.Array<kotlin.String> [inline] declared in <root>.test'
CALL 'public final fun arrayOf <T> (vararg elements: T of kotlin.arrayOf): kotlin.Array<T of kotlin.arrayOf> [inline] declared in kotlin' type=kotlin.Array<kotlin.String> origin=null
<T>: kotlin.String
elements: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
GET_VAR 'p0: kotlin.String declared in <root>.test.arrayOf' type=kotlin.String origin=null
FUNCTION_REFERENCE 'local final fun arrayOf (p0: kotlin.String): kotlin.Array<kotlin.String> [inline] declared in <root>.test' type=kotlin.reflect.KFunction1<kotlin.String, kotlin.Array<kotlin.String>> origin=null reflectionTarget=null
@@ -0,0 +1,34 @@
FILE fqName:<root> fileName:/withAdaptationForSam.kt
CLASS INTERFACE name:IFoo modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.IFoo
FUN name:foo visibility:public modality:ABSTRACT <> ($this:<root>.IFoo, i:kotlin.Int) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.IFoo
VALUE_PARAMETER name:i index:0 type:kotlin.Int
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:useFoo visibility:public modality:FINAL <> (foo:<root>.IFoo) returnType:kotlin.Unit
VALUE_PARAMETER name:foo index:0 type:<root>.IFoo
BLOCK_BODY
FUN name:useVarargFoo visibility:public modality:FINAL <> (foos:kotlin.Array<<root>.IFoo>) returnType:kotlin.Unit
VALUE_PARAMETER name:foos index:0 type:kotlin.Array<<root>.IFoo>
BLOCK_BODY
FUN name:withVararg visibility:public modality:FINAL <> (xs:kotlin.IntArray) returnType:kotlin.Int
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun withVararg (xs: kotlin.IntArray): kotlin.Int declared in <root>'
CONST Int type=kotlin.Int value=42
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/useFoo]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun withVararg (xs: kotlin.IntArray): kotlin.Int declared in <root>' type=kotlin.reflect.KFunction1<kotlin.IntArray, kotlin.Int> origin=null reflectionTarget=<same>
@@ -0,0 +1,20 @@
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
fun interface IFoo {
fun foo(i: Int)
}
fun useFoo(foo: IFoo) {}
fun useVarargFoo(vararg foos: IFoo) {}
fun withVararg(vararg xs: Int) = 42
fun test() {
useFoo(::withVararg)
}
// TODO
//fun testVarargOfSams() {
// useVarargFoo(::withVararg)
//}
@@ -0,0 +1,43 @@
FILE fqName:<root> fileName:/withAdaptationForSam.kt
CLASS INTERFACE name:IFoo modality:ABSTRACT visibility:public [fun] superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.IFoo
FUN name:foo visibility:public modality:ABSTRACT <> ($this:<root>.IFoo, i:kotlin.Int) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.IFoo
VALUE_PARAMETER name:i index:0 type:kotlin.Int
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:useFoo visibility:public modality:FINAL <> (foo:<root>.IFoo) returnType:kotlin.Unit
VALUE_PARAMETER name:foo index:0 type:<root>.IFoo
BLOCK_BODY
FUN name:useVarargFoo visibility:public modality:FINAL <> (foos:kotlin.Array<out <root>.IFoo>) returnType:kotlin.Unit
VALUE_PARAMETER name:foos index:0 type:kotlin.Array<out <root>.IFoo> varargElementType:<root>.IFoo [vararg]
BLOCK_BODY
FUN name:withVararg visibility:public modality:FINAL <> (xs:kotlin.IntArray) returnType:kotlin.Int
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray varargElementType:kotlin.Int [vararg]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun withVararg (vararg xs: kotlin.Int): kotlin.Int declared in <root>'
CONST Int type=kotlin.Int value=42
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
CALL 'public final fun useFoo (foo: <root>.IFoo): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
foo: TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun withVararg (vararg xs: kotlin.Int): kotlin.Int declared in <root>' type=kotlin.Int origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.test.withVararg' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.test' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null reflectionTarget=null
@@ -8118,83 +8118,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
} }
} }
@TestMetadata("compiler/testData/codegen/box/coroutines/noStdLib")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class NoStdLib extends AbstractLightAnalysisModeTest {
@TestMetadata("breakFinally.kt")
public void ignoreBreakFinally_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/breakFinally.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("breakFinally.kt")
public void ignoreBreakFinally_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/breakFinally.kt", "kotlin.coroutines");
}
@TestMetadata("breakStatement.kt")
public void ignoreBreakStatement_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/breakStatement.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("breakStatement.kt")
public void ignoreBreakStatement_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/breakStatement.kt", "kotlin.coroutines");
}
@TestMetadata("crossinline.kt")
public void ignoreCrossinline_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/crossinline.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("crossinline.kt")
public void ignoreCrossinline_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/crossinline.kt", "kotlin.coroutines");
}
@TestMetadata("ifStatement.kt")
public void ignoreIfStatement_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/ifStatement.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("ifStatement.kt")
public void ignoreIfStatement_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/ifStatement.kt", "kotlin.coroutines");
}
@TestMetadata("stateMachine.kt")
public void ignoreStateMachine_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/stateMachine.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("stateMachine.kt")
public void ignoreStateMachine_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/stateMachine.kt", "kotlin.coroutines");
}
@TestMetadata("switchLikeWhen.kt")
public void ignoreSwitchLikeWhen_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/switchLikeWhen.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("switchLikeWhen.kt")
public void ignoreSwitchLikeWhen_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noStdLib/switchLikeWhen.kt", "kotlin.coroutines");
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
private void runTestWithPackageReplacement(String testDataFilePath, String packageName) throws Exception {
KotlinTestUtils.runTest(filePath -> doTestWithCoroutinesPackageReplacement(filePath, packageName), TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInNoStdLib() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/noStdLib"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
}
@TestMetadata("compiler/testData/codegen/box/coroutines/redundantLocalsElimination") @TestMetadata("compiler/testData/codegen/box/coroutines/redundantLocalsElimination")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -1353,6 +1353,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
runTest("compiler/testData/ir/irText/expressions/callableReferences/boundInnerGenericConstructor.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/boundInnerGenericConstructor.kt");
} }
@TestMetadata("caoWithAdaptationForSam.kt")
public void testCaoWithAdaptationForSam() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.kt");
}
@TestMetadata("constructorWithAdaptedArguments.kt") @TestMetadata("constructorWithAdaptedArguments.kt")
public void testConstructorWithAdaptedArguments() throws Exception { public void testConstructorWithAdaptedArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.kt");
@@ -1368,11 +1373,6 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
runTest("compiler/testData/ir/irText/expressions/callableReferences/importedFromObject.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/importedFromObject.kt");
} }
@TestMetadata("letArrayOf.kt")
public void testLetArrayOf() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/letArrayOf.kt");
}
@TestMetadata("typeArguments.kt") @TestMetadata("typeArguments.kt")
public void testTypeArguments() throws Exception { public void testTypeArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/typeArguments.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/typeArguments.kt");
@@ -1383,6 +1383,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
runTest("compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.kt");
} }
@TestMetadata("withAdaptationForSam.kt")
public void testWithAdaptationForSam() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withAdaptationForSam.kt");
}
@TestMetadata("withAdaptedArguments.kt") @TestMetadata("withAdaptedArguments.kt")
public void testWithAdaptedArguments() throws Exception { public void testWithAdaptedArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withAdaptedArguments.kt"); runTest("compiler/testData/ir/irText/expressions/callableReferences/withAdaptedArguments.kt");