PSI2IR: capture adapted reference receiver to a local val if required

This commit is contained in:
Dmitry Petrov
2020-01-21 14:26:49 +03:00
parent 38b90b7fbd
commit 57bbfbbfcc
9 changed files with 488 additions and 10 deletions
@@ -1349,6 +1349,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions/callableReferences"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("constructorWithAdaptedArguments.kt")
public void testConstructorWithAdaptedArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.kt");
}
@TestMetadata("genericMember.kt")
public void testGenericMember() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/genericMember.kt");
@@ -1369,6 +1374,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withAdaptedArguments.kt");
}
@TestMetadata("withArgumentAdaptationAndReceiver.kt")
public void testWithArgumentAdaptationAndReceiver() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withArgumentAdaptationAndReceiver.kt");
}
@TestMetadata("withVarargViewedAsArray.kt")
public void testWithVarargViewedAsArray() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withVarargViewedAsArray.kt");
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
@@ -42,6 +40,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
import org.jetbrains.kotlin.utils.addIfNotNull
class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
@@ -99,6 +98,8 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
}
}
private val adapterOrigin = IrDeclarationOrigin.DEFINED // TODO special declaration origin for callable reference adapter?
private fun isTrivialArgumentAdaptation(irAdapteeCall: IrFunctionAccessExpression): Boolean {
for (i in 0 until irAdapteeCall.valueArgumentsCount) {
val irValueArgument = irAdapteeCall.getValueArgument(i) ?: return false
@@ -138,8 +139,12 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
val ktExpectedParameterTypes = ktFunctionalTypeArguments.take(ktFunctionalTypeArguments.size - 1).map { it.type }
val irAdapterFun = createAdapterFun(startOffset, endOffset, adapteeDescriptor, ktExpectedParameterTypes, ktExpectedReturnType)
val (irCall, irAdapteeCallInner) =
createAdapteeCall(startOffset, endOffset, ktCallableReference, adapteeSymbol, callBuilder, irAdapterFun)
val adapteeCall = createAdapteeCall(startOffset, endOffset, ktCallableReference, adapteeSymbol, callBuilder, irAdapterFun)
val irCall = adapteeCall.callExpression
val irAdapteeCallInner = adapteeCall.innerCallExpression
val tmpDispatchReceiver = adapteeCall.tmpDispatchReceiver
val tmpExtensionReceiver = adapteeCall.tmpExtensionReceiver
irAdapterFun.body = IrBlockBodyImpl(startOffset, endOffset).apply {
if (KotlinBuiltIns.isUnit(ktExpectedReturnType))
@@ -149,6 +154,8 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
}
val irBlock = IrBlockImpl(startOffset, endOffset, irFunctionalType).apply {
statements.addIfNotNull(tmpDispatchReceiver)
statements.addIfNotNull(tmpExtensionReceiver)
statements.add(irAdapterFun)
statements.add(
IrFunctionReferenceImpl(
@@ -167,6 +174,13 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
)
}
private class AdapteeCall(
val callExpression: IrExpression,
val innerCallExpression: IrFunctionAccessExpression,
val tmpDispatchReceiver: IrVariable?,
val tmpExtensionReceiver: IrVariable?
)
private fun createAdapteeCall(
startOffset: Int,
endOffset: Int,
@@ -174,11 +188,14 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
adapteeSymbol: IrFunctionSymbol,
callBuilder: CallBuilder,
irAdapterFun: IrSimpleFunction
): Pair<IrExpression, IrFunctionAccessExpression> {
): AdapteeCall {
val resolvedCall = callBuilder.original
val resolvedDescriptor = resolvedCall.resultingDescriptor
var irAdapteeCall: IrFunctionAccessExpression? = null
var tmpDispatchReceiver: IrVariable? = null
var tmpExtensionReceiver: IrVariable? = null
val irCall = statementGenerator.generateCallReceiver(
ktCallableReference,
resolvedDescriptor,
@@ -202,8 +219,28 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
context.callToSubstitutedDescriptorMap[irAdapteeCallInner] = resolvedDescriptor
irAdapteeCallInner.dispatchReceiver = dispatchReceiverValue?.load()
irAdapteeCallInner.extensionReceiver = extensionReceiverValue?.load()
val irDispatchReceiver = dispatchReceiverValue?.load()
val irExtensionReceiver = extensionReceiverValue?.load()
if (irDispatchReceiver != null) {
if (irDispatchReceiver.isSafeToUseWithoutCopying()) {
irAdapteeCallInner.dispatchReceiver = irDispatchReceiver
} else {
val irVariable = statementGenerator.scope.createTemporaryVariable(irDispatchReceiver, "this")
irAdapteeCallInner.dispatchReceiver = IrGetValueImpl(startOffset, endOffset, irVariable.symbol)
tmpDispatchReceiver = irVariable
}
}
if (irExtensionReceiver != null) {
if (irExtensionReceiver.isSafeToUseWithoutCopying()) {
irAdapteeCallInner.extensionReceiver = irExtensionReceiver
} else {
val irVariable = statementGenerator.scope.createTemporaryVariable(irExtensionReceiver, "receiver")
irAdapteeCallInner.extensionReceiver = IrGetValueImpl(startOffset, endOffset, irVariable.symbol)
tmpExtensionReceiver = irVariable
}
}
irAdapteeCallInner.putTypeArguments(callBuilder.typeArguments) { it.toIrType() }
@@ -214,9 +251,18 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
irAdapteeCallInner
}
return Pair(irCall, irAdapteeCall!!)
return AdapteeCall(irCall, irAdapteeCall!!, tmpDispatchReceiver, tmpExtensionReceiver)
}
private fun IrExpression.isSafeToUseWithoutCopying() =
this is IrGetObjectValue ||
this is IrGetEnumValue ||
this is IrConst<*> ||
this is IrGetValue && symbol.isBound && symbol.owner.isImmutable()
private fun IrValueDeclaration.isImmutable() =
this is IrValueParameter || this is IrVariable && !this.isVar
private fun putAdaptedValueArguments(
startOffset: Int,
endOffset: Int,
@@ -294,7 +340,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
ktExpectedReturnType: KotlinType
): IrSimpleFunction {
val adapterFunctionDescriptor = WrappedSimpleFunctionDescriptor()
val adapterOrigin = IrDeclarationOrigin.DEFINED // TODO special declaration origin for callable reference adapter?
return context.symbolTable.declareSimpleFunction(
startOffset, endOffset, adapterOrigin, adapterFunctionDescriptor
@@ -0,0 +1,83 @@
FILE fqName:<root> fileName:/constructorWithAdaptedArguments.kt
FUN name:use visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Any>) returnType:kotlin.Any
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Any>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Any>): kotlin.Any declared in <root>'
CALL 'public abstract fun invoke (p1: kotlin.Int): kotlin.Any [operator] declared in kotlin.Function1' type=kotlin.Any origin=null
$this: GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Any> declared in <root>.use' type=kotlin.Function1<kotlin.Int, kotlin.Any> origin=null
p1: CONST Int type=kotlin.Int value=42
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.C
CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:<root>.C [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C 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 CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Outer
CONSTRUCTOR visibility:public <> () returnType:<root>.Outer [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]'
CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Outer.Inner
CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:<root>.Outer.Inner [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Inner modality:FINAL visibility:public [inner] 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 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:testConstructor visibility:public modality:FINAL <> () returnType:IrErrorType
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testConstructor (): IrErrorType declared in <root>'
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public constructor <init> (xs: kotlin.IntArray) [primary] declared in <root>.C' type=kotlin.reflect.KFunction1<kotlin.IntArray, <root>.C> origin=null
FUN name:testInnerClassConstructor visibility:public modality:FINAL <> (outer:<root>.Outer) returnType:IrErrorType
VALUE_PARAMETER name:outer index:0 type:<root>.Outer
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructor (outer: <root>.Outer): IrErrorType declared in <root>'
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public constructor <init> (xs: kotlin.IntArray) [primary] declared in <root>.Outer.Inner' type=kotlin.reflect.KFunction1<kotlin.IntArray, <root>.Outer.Inner> origin=null
FUN name:testInnerClassConstructorCapturingOuter visibility:public modality:FINAL <> () returnType:IrErrorType
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructorCapturingOuter (): IrErrorType declared in <root>'
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public constructor <init> (xs: kotlin.IntArray) [primary] declared in <root>.Outer.Inner' type=kotlin.reflect.KFunction1<kotlin.IntArray, <root>.Outer.Inner> origin=null
@@ -0,0 +1,15 @@
// !LANGUAGE: +NewInference, +FunctionReferenceWithDefaultValueAsOtherType
fun use(fn: (Int) -> Any) = fn(42)
class C(vararg xs: Int)
class Outer {
inner class Inner(vararg xs: Int)
}
fun testConstructor() = use(::C)
fun testInnerClassConstructor(outer: Outer) = use(outer::Inner)
fun testInnerClassConstructorCapturingOuter() = use(Outer()::Inner)
@@ -0,0 +1,112 @@
FILE fqName:<root> fileName:/constructorWithAdaptedArguments.kt
FUN name:use visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Any>) returnType:kotlin.Any
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Any>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Any>): kotlin.Any declared in <root>'
CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Any origin=INVOKE
$this: GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Any> declared in <root>.use' type=kotlin.Function1<kotlin.Int, kotlin.Any> origin=VARIABLE_AS_FUNCTION
p1: CONST Int type=kotlin.Int value=42
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.C
CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:<root>.C [primary]
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray varargElementType:kotlin.Int [vararg]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C 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 CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Outer
CONSTRUCTOR visibility:public <> () returnType:<root>.Outer [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]'
CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Outer.Inner
CONSTRUCTOR visibility:public <> ($this:<root>.Outer, xs:kotlin.IntArray) returnType:<root>.Outer.Inner [primary]
$outer: VALUE_PARAMETER name:<this> type:<root>.Outer
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray varargElementType:kotlin.Int [vararg]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Inner modality:FINAL visibility:public [inner] 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 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:testConstructor visibility:public modality:FINAL <> () returnType:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testConstructor (): kotlin.Any declared in <root>'
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
fn: BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, <root>.C> origin=null
FUN name:<init> visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:<root>.C
VALUE_PARAMETER name:p0 index:0 type:kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <init> (p0: kotlin.Int): <root>.C declared in <root>.testConstructor'
CONSTRUCTOR_CALL 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.C' type=<root>.C origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.testConstructor.<init>' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun <init> (p0: kotlin.Int): <root>.C declared in <root>.testConstructor' type=kotlin.reflect.KFunction1<kotlin.Int, <root>.C> origin=null
FUN name:testInnerClassConstructor visibility:public modality:FINAL <> (outer:<root>.Outer) returnType:kotlin.Any
VALUE_PARAMETER name:outer index:0 type:<root>.Outer
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructor (outer: <root>.Outer): kotlin.Any declared in <root>'
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
fn: BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, <root>.Outer.Inner> origin=null
FUN name:<init> visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:<root>.Outer.Inner
VALUE_PARAMETER name:p0 index:0 type:kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <init> (p0: kotlin.Int): <root>.Outer.Inner declared in <root>.testInnerClassConstructor'
CONSTRUCTOR_CALL 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.Outer.Inner' type=<root>.Outer.Inner origin=null
$outer: GET_VAR 'outer: <root>.Outer declared in <root>.testInnerClassConstructor' type=<root>.Outer origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.testInnerClassConstructor.<init>' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun <init> (p0: kotlin.Int): <root>.Outer.Inner declared in <root>.testInnerClassConstructor' type=kotlin.reflect.KFunction1<kotlin.Int, <root>.Outer.Inner> origin=null
FUN name:testInnerClassConstructorCapturingOuter visibility:public modality:FINAL <> () returnType:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructorCapturingOuter (): kotlin.Any declared in <root>'
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
fn: BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, <root>.Outer.Inner> origin=null
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.Outer [val]
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Outer' type=<root>.Outer origin=null
FUN name:<init> visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:<root>.Outer.Inner
VALUE_PARAMETER name:p0 index:0 type:kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <init> (p0: kotlin.Int): <root>.Outer.Inner declared in <root>.testInnerClassConstructorCapturingOuter'
CONSTRUCTOR_CALL 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.Outer.Inner' type=<root>.Outer.Inner origin=null
$outer: GET_VAR 'val tmp_0: <root>.Outer [val] declared in <root>.testInnerClassConstructorCapturingOuter' type=<root>.Outer origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.testInnerClassConstructorCapturingOuter.<init>' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun <init> (p0: kotlin.Int): <root>.Outer.Inner declared in <root>.testInnerClassConstructorCapturingOuter' type=kotlin.reflect.KFunction1<kotlin.Int, <root>.Outer.Inner> origin=null
@@ -0,0 +1,62 @@
FILE fqName:<root> fileName:/withArgumentAdaptationAndReceiver.kt
FUN name:use 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
CALL 'public abstract fun invoke (p1: kotlin.Int): kotlin.Unit [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null
$this: GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.use' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
p1: CONST Int type=kotlin.Int value=1
CLASS CLASS name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Host
CONSTRUCTOR visibility:public <> () returnType:<root>.Host [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN name:withVararg visibility:public modality:FINAL <> ($this:<root>.Host, xs:kotlin.IntArray) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.Host
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun withVararg (xs: kotlin.IntArray): kotlin.String declared in <root>.Host'
CONST String type=kotlin.String value=""
FUN name:testImplicitThis visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun withVararg (xs: kotlin.IntArray): kotlin.String declared in <root>.Host' type=kotlin.reflect.KFunction1<kotlin.IntArray, kotlin.String> origin=null
FUN name:testBoundReceiverLocalVal visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
VAR name:h type:<root>.Host [val]
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Host' type=<root>.Host origin=null
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun withVararg (xs: kotlin.IntArray): kotlin.String declared in <root>.Host' type=kotlin.reflect.KFunction1<kotlin.IntArray, kotlin.String> origin=null
FUN name:testBoundReceiverLocalVar visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
VAR name:h type:<root>.Host [var]
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Host' type=<root>.Host origin=null
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun withVararg (xs: kotlin.IntArray): kotlin.String declared in <root>.Host' type=kotlin.reflect.KFunction1<kotlin.IntArray, kotlin.String> origin=null
FUN name:testBoundReceiverParameter visibility:public modality:FINAL <> ($this:<root>.Host, h:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
VALUE_PARAMETER name:h index:0 type:<root>.Host
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun withVararg (xs: kotlin.IntArray): kotlin.String declared in <root>.Host' type=kotlin.reflect.KFunction1<kotlin.IntArray, kotlin.String> origin=null
FUN name:testBoundReceiverExpression visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun withVararg (xs: kotlin.IntArray): kotlin.String declared in <root>.Host' type=kotlin.reflect.KFunction1<kotlin.IntArray, kotlin.String> origin=null
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
@@ -0,0 +1,29 @@
// !LANGUAGE: +NewInference, +FunctionReferenceWithDefaultValueAsOtherType
fun use(fn: (Int) -> Unit) { fn(1) }
class Host {
fun withVararg(vararg xs: Int) = ""
fun testImplicitThis() {
use(::withVararg)
}
fun testBoundReceiverLocalVal() {
val h = Host()
use(h::withVararg)
}
fun testBoundReceiverLocalVar() {
var h = Host()
use(h::withVararg)
}
fun testBoundReceiverParameter(h: Host) {
use(h::withVararg)
}
fun testBoundReceiverExpression() {
use(Host()::withVararg)
}
}
@@ -0,0 +1,111 @@
FILE fqName:<root> fileName:/withArgumentAdaptationAndReceiver.kt
FUN name:use 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
CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=INVOKE
$this: GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.use' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=VARIABLE_AS_FUNCTION
p1: CONST Int type=kotlin.Int value=1
CLASS CLASS name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Host
CONSTRUCTOR visibility:public <> () returnType:<root>.Host [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN name:withVararg visibility:public modality:FINAL <> ($this:<root>.Host, xs:kotlin.IntArray) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.Host
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.String declared in <root>.Host'
CONST String type=kotlin.String value=""
FUN name:testImplicitThis visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
fn: BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER 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.String declared in <root>.Host' type=kotlin.String origin=null
$this: GET_VAR '<this>: <root>.Host declared in <root>.Host.testImplicitThis' type=<root>.Host origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.Host.testImplicitThis.withVararg' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.Host.testImplicitThis' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN name:testBoundReceiverLocalVal visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
VAR name:h type:<root>.Host [val]
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Host' type=<root>.Host origin=null
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
fn: BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER 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.String declared in <root>.Host' type=kotlin.String origin=null
$this: GET_VAR 'val h: <root>.Host [val] declared in <root>.Host.testBoundReceiverLocalVal' type=<root>.Host origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.Host.testBoundReceiverLocalVal.withVararg' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.Host.testBoundReceiverLocalVal' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN name:testBoundReceiverLocalVar visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
VAR name:h type:<root>.Host [var]
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Host' type=<root>.Host origin=null
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
fn: BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.Host [val]
GET_VAR 'var h: <root>.Host [var] declared in <root>.Host.testBoundReceiverLocalVar' type=<root>.Host origin=null
FUN name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER 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.String declared in <root>.Host' type=kotlin.String origin=null
$this: GET_VAR 'val tmp_0: <root>.Host [val] declared in <root>.Host.testBoundReceiverLocalVar' type=<root>.Host origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.Host.testBoundReceiverLocalVar.withVararg' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.Host.testBoundReceiverLocalVar' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN name:testBoundReceiverParameter visibility:public modality:FINAL <> ($this:<root>.Host, h:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
VALUE_PARAMETER name:h index:0 type:<root>.Host
BLOCK_BODY
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
fn: BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER 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.String declared in <root>.Host' type=kotlin.String origin=null
$this: GET_VAR 'h: <root>.Host declared in <root>.Host.testBoundReceiverParameter' type=<root>.Host origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.Host.testBoundReceiverParameter.withVararg' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.Host.testBoundReceiverParameter' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
FUN name:testBoundReceiverExpression visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
fn: BLOCK type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.Host [val]
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Host' type=<root>.Host origin=null
FUN name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER 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.String declared in <root>.Host' type=kotlin.String origin=null
$this: GET_VAR 'val tmp_1: <root>.Host [val] declared in <root>.Host.testBoundReceiverExpression' type=<root>.Host origin=null
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
GET_VAR 'p0: kotlin.Int declared in <root>.Host.testBoundReceiverExpression.withVararg' type=kotlin.Int origin=null
FUNCTION_REFERENCE 'local final fun withVararg (p0: kotlin.Int): kotlin.Unit declared in <root>.Host.testBoundReceiverExpression' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
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
@@ -1348,6 +1348,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions/callableReferences"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("constructorWithAdaptedArguments.kt")
public void testConstructorWithAdaptedArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.kt");
}
@TestMetadata("genericMember.kt")
public void testGenericMember() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/genericMember.kt");
@@ -1368,6 +1373,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withAdaptedArguments.kt");
}
@TestMetadata("withArgumentAdaptationAndReceiver.kt")
public void testWithArgumentAdaptationAndReceiver() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withArgumentAdaptationAndReceiver.kt");
}
@TestMetadata("withVarargViewedAsArray.kt")
public void testWithVarargViewedAsArray() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/withVarargViewedAsArray.kt");