From d8539fdde915f1e76921a3e44e04041d4882537c Mon Sep 17 00:00:00 2001 From: Juan Chen Date: Sun, 29 Mar 2020 22:49:41 -0700 Subject: [PATCH] [FIR2IR] Add dispatch & extension receivers to callable references --- .../jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt | 12 +++++++++++- .../box/callableReference/bound/arrayGetIntrinsic.kt | 1 - .../box/callableReference/bound/dontShareReceiver.kt | 1 - .../box/callableReference/bound/enumEntryMember.kt | 1 - .../bound/equals/receiverInEquals.kt | 1 - .../codegen/box/callableReference/bound/kt15446.kt | 1 - .../callableReference/bound/receiverEvaluatedOnce.kt | 1 - .../bound/referenceToGetSetMethodsFromVararg.kt | 1 - .../box/callableReference/bound/simpleFunction.kt | 1 - .../bound/smartCastForExtensionReceiver.kt | 1 - .../bound/syntheticExtensionOnLHS.kt | 1 - .../box/callableReference/classesAreSynthetic.kt | 1 - .../optimizedSuperclasses_before.kt | 1 - .../codegen/box/functions/bigArity/function255.kt | 1 - .../bigArity/invokeMemberCallableReference.kt | 1 - .../callableReferences/boundInlineClassMemberFun.kt | 1 - .../callableReferencesWithInlineClasses.kt | 1 - .../expressions/boundCallableReferences.fir.txt | 2 ++ .../boundInnerGenericConstructor.fir.txt | 1 + .../constructorWithAdaptedArguments.fir.txt | 2 ++ ...nboundMemberReferenceWithAdaptedArguments.fir.txt | 1 + .../withArgumentAdaptationAndReceiver.fir.txt | 4 ++++ .../ir/irText/expressions/reflectionLiterals.fir.txt | 1 + 23 files changed, 22 insertions(+), 17 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 1f90227e5d8..9ae8f45acbb 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -344,7 +344,17 @@ class Fir2IrVisitor( startOffset, endOffset, type, symbol, typeArgumentsCount = 0, reflectionTarget = symbol - ) + ).apply { + val firReceiver = callableReferenceAccess.explicitReceiver + if (firReceiver != null && firReceiver !is FirResolvedQualifier) { + val irReceiver = convertToIrExpression(firReceiver) + if (symbol.owner.dispatchReceiverParameter != null) { + this.dispatchReceiver = irReceiver + } else if (symbol.owner.extensionReceiverParameter != null) { + this.extensionReceiver = irReceiver + } + } + } } else -> { IrErrorCallExpressionImpl( diff --git a/compiler/testData/codegen/box/callableReference/bound/arrayGetIntrinsic.kt b/compiler/testData/codegen/box/callableReference/bound/arrayGetIntrinsic.kt index ad271dfc31c..d81fb9087aa 100644 --- a/compiler/testData/codegen/box/callableReference/bound/arrayGetIntrinsic.kt +++ b/compiler/testData/codegen/box/callableReference/bound/arrayGetIntrinsic.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun box(): String { return if ((arrayOf(1, 2, 3)::get)(1) == 2) "OK" else "Fail" } diff --git a/compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt b/compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt index a6775e73eba..d5d36ca681d 100644 --- a/compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt +++ b/compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun box(): String { var state = 0 diff --git a/compiler/testData/codegen/box/callableReference/bound/enumEntryMember.kt b/compiler/testData/codegen/box/callableReference/bound/enumEntryMember.kt index 942657f4652..d1a159b7565 100644 --- a/compiler/testData/codegen/box/callableReference/bound/enumEntryMember.kt +++ b/compiler/testData/codegen/box/callableReference/bound/enumEntryMember.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS, JS_IR enum class E { A, B; diff --git a/compiler/testData/codegen/box/callableReference/bound/equals/receiverInEquals.kt b/compiler/testData/codegen/box/callableReference/bound/equals/receiverInEquals.kt index 9bd5c7da4b1..245ca43ced3 100644 --- a/compiler/testData/codegen/box/callableReference/bound/equals/receiverInEquals.kt +++ b/compiler/testData/codegen/box/callableReference/bound/equals/receiverInEquals.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: investigate should it be ran for JS or not // IGNORE_BACKEND: JS diff --git a/compiler/testData/codegen/box/callableReference/bound/kt15446.kt b/compiler/testData/codegen/box/callableReference/bound/kt15446.kt index 37d5b0bb13d..2630e17739a 100644 --- a/compiler/testData/codegen/box/callableReference/bound/kt15446.kt +++ b/compiler/testData/codegen/box/callableReference/bound/kt15446.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // KJS_WITH_FULL_RUNTIME //WITH_RUNTIME fun box(): String { diff --git a/compiler/testData/codegen/box/callableReference/bound/receiverEvaluatedOnce.kt b/compiler/testData/codegen/box/callableReference/bound/receiverEvaluatedOnce.kt index 1d5ea8da0a5..fcc6d27ed51 100644 --- a/compiler/testData/codegen/box/callableReference/bound/receiverEvaluatedOnce.kt +++ b/compiler/testData/codegen/box/callableReference/bound/receiverEvaluatedOnce.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR var x = 0 class A { diff --git a/compiler/testData/codegen/box/callableReference/bound/referenceToGetSetMethodsFromVararg.kt b/compiler/testData/codegen/box/callableReference/bound/referenceToGetSetMethodsFromVararg.kt index d9406b5a41c..b0b95948c4e 100644 --- a/compiler/testData/codegen/box/callableReference/bound/referenceToGetSetMethodsFromVararg.kt +++ b/compiler/testData/codegen/box/callableReference/bound/referenceToGetSetMethodsFromVararg.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +NewInference // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // WITH_REFLECT import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt b/compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt index b4492cf7181..15fae151f5f 100644 --- a/compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt +++ b/compiler/testData/codegen/box/callableReference/bound/simpleFunction.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun box(): String { val f = "KOTLIN"::get return "${f(1)}${f(0)}" diff --git a/compiler/testData/codegen/box/callableReference/bound/smartCastForExtensionReceiver.kt b/compiler/testData/codegen/box/callableReference/bound/smartCastForExtensionReceiver.kt index e3bdcb85854..c48830488c4 100644 --- a/compiler/testData/codegen/box/callableReference/bound/smartCastForExtensionReceiver.kt +++ b/compiler/testData/codegen/box/callableReference/bound/smartCastForExtensionReceiver.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR class B fun B.magic() { diff --git a/compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt b/compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt index 31b05e38432..b8be5402715 100644 --- a/compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt +++ b/compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME // FILE: A.java diff --git a/compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt b/compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt index 7ffd253d585..4651be22eb9 100644 --- a/compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt +++ b/compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/callableReference/optimizedSuperclasses_before.kt b/compiler/testData/codegen/box/callableReference/optimizedSuperclasses_before.kt index b967e998e2f..ff6a19a681c 100644 --- a/compiler/testData/codegen/box/callableReference/optimizedSuperclasses_before.kt +++ b/compiler/testData/codegen/box/callableReference/optimizedSuperclasses_before.kt @@ -1,6 +1,5 @@ // !API_VERSION: 1.3 // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME class A { diff --git a/compiler/testData/codegen/box/functions/bigArity/function255.kt b/compiler/testData/codegen/box/functions/bigArity/function255.kt index 1df2ce25340..16fdf6c2c9e 100644 --- a/compiler/testData/codegen/box/functions/bigArity/function255.kt +++ b/compiler/testData/codegen/box/functions/bigArity/function255.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +FunctionTypesWithBigArity -// IGNORE_BACKEND_FIR: JVM_IR class A(val value: Int) { // for (i in 1..254) { print("p${"%03d".format(i)}: A, "); if (i % 10 == 0) println() }; println() diff --git a/compiler/testData/codegen/box/functions/bigArity/invokeMemberCallableReference.kt b/compiler/testData/codegen/box/functions/bigArity/invokeMemberCallableReference.kt index f5ffccbb92f..743865b5b4d 100644 --- a/compiler/testData/codegen/box/functions/bigArity/invokeMemberCallableReference.kt +++ b/compiler/testData/codegen/box/functions/bigArity/invokeMemberCallableReference.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +FunctionTypesWithBigArity -// IGNORE_BACKEND_FIR: JVM_IR class A { fun foo( diff --git a/compiler/testData/codegen/box/inlineClasses/callableReferences/boundInlineClassMemberFun.kt b/compiler/testData/codegen/box/inlineClasses/callableReferences/boundInlineClassMemberFun.kt index 7960be01c24..465845d7c71 100644 --- a/compiler/testData/codegen/box/inlineClasses/callableReferences/boundInlineClassMemberFun.kt +++ b/compiler/testData/codegen/box/inlineClasses/callableReferences/boundInlineClassMemberFun.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +InlineClasses -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME inline class Z(val x: Int) { diff --git a/compiler/testData/codegen/box/inlineClasses/callableReferencesWithInlineClasses.kt b/compiler/testData/codegen/box/inlineClasses/callableReferencesWithInlineClasses.kt index 649009b3ea6..e3e9744f98a 100644 --- a/compiler/testData/codegen/box/inlineClasses/callableReferencesWithInlineClasses.kt +++ b/compiler/testData/codegen/box/inlineClasses/callableReferencesWithInlineClasses.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +InlineClasses -// IGNORE_BACKEND_FIR: JVM_IR // WITH_REFLECT inline class Foo(val x: String) { diff --git a/compiler/testData/ir/irText/expressions/boundCallableReferences.fir.txt b/compiler/testData/ir/irText/expressions/boundCallableReferences.fir.txt index c5863879f91..71a518ef93a 100644 --- a/compiler/testData/ir/irText/expressions/boundCallableReferences.fir.txt +++ b/compiler/testData/ir/irText/expressions/boundCallableReferences.fir.txt @@ -39,6 +39,7 @@ FILE fqName: fileName:/boundCallableReferences.kt FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction0 visibility:private [final,static] EXPRESSION_BODY FUNCTION_REFERENCE 'public final fun foo (): kotlin.Unit declared in .A' type=kotlin.reflect.KFunction0 origin=null reflectionTarget= + $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .A' type=.A origin=null FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KFunction0 correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val] BLOCK_BODY @@ -57,6 +58,7 @@ FILE fqName: fileName:/boundCallableReferences.kt FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.reflect.KFunction0 visibility:private [final,static] EXPRESSION_BODY FUNCTION_REFERENCE 'public final fun qux (): kotlin.Unit declared in ' type=kotlin.reflect.KFunction0 origin=null reflectionTarget= + $receiver: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .A' type=.A origin=null FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KFunction0 correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [val] BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/callableReferences/boundInnerGenericConstructor.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/boundInnerGenericConstructor.fir.txt index a5980093be3..e9f2e54e1cc 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/boundInnerGenericConstructor.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/boundInnerGenericConstructor.fir.txt @@ -86,6 +86,7 @@ FILE fqName:test fileName:/boundInnerGenericConstructor.kt CONST String type=kotlin.String value="O" CONST String type=kotlin.String value="K" FUNCTION_REFERENCE 'public constructor (a: T of test.Foo, b: P of test.Foo.Inner) [primary] declared in test.Foo.Inner' type=kotlin.reflect.KFunction2> origin=null reflectionTarget= + $this: GET_VAR 'val z: test.Foo [val] declared in test.box' type=test.Foo origin=null RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in test' CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin' type=kotlin.String origin=PLUS $receiver: ERROR_CALL 'Unresolved reference: #' type=IrErrorType diff --git a/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.txt index c7541ccd5b5..5faffd177d3 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.txt @@ -77,8 +77,10 @@ FILE fqName: fileName:/constructorWithAdaptedArguments.kt RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructor (outer: .Outer): IrErrorType declared in ' ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUNCTION_REFERENCE 'public constructor (vararg xs: kotlin.Int) [primary] declared in .Outer.Inner' type=kotlin.reflect.KFunction1.Outer.Inner> origin=null reflectionTarget= + $this: GET_VAR 'outer: .Outer declared in .testInnerClassConstructor' type=.Outer 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 ' ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUNCTION_REFERENCE 'public constructor (vararg xs: kotlin.Int) [primary] declared in .Outer.Inner' type=kotlin.reflect.KFunction1.Outer.Inner> origin=null reflectionTarget= + $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Outer' type=.Outer origin=null diff --git a/compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.fir.txt index c473fd65747..52f759c461d 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.fir.txt @@ -64,6 +64,7 @@ FILE fqName: fileName:/unboundMemberReferenceWithAdaptedArguments.kt BLOCK_BODY ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUNCTION_REFERENCE 'public open fun foo (vararg xs: kotlin.Int): kotlin.Int declared in .A' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= + $this: GET_VAR 'a: .A declared in .testBound' type=.A origin=null FUN name:testObject visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY ERROR_CALL 'Unresolved reference: #' type=IrErrorType diff --git a/compiler/testData/ir/irText/expressions/callableReferences/withArgumentAdaptationAndReceiver.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/withArgumentAdaptationAndReceiver.fir.txt index 509ab5e1e25..1c5e892a6ba 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/withArgumentAdaptationAndReceiver.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/withArgumentAdaptationAndReceiver.fir.txt @@ -29,6 +29,7 @@ FILE fqName: fileName:/withArgumentAdaptationAndReceiver.kt CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Host' type=.Host origin=null ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUNCTION_REFERENCE 'public final fun withVararg (vararg xs: kotlin.Int): kotlin.String declared in .Host' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= + $this: GET_VAR 'val h: .Host [val] declared in .Host.testBoundReceiverLocalVal' type=.Host origin=null FUN name:testBoundReceiverLocalVar visibility:public modality:FINAL <> ($this:.Host) returnType:kotlin.Unit $this: VALUE_PARAMETER name: type:.Host BLOCK_BODY @@ -36,17 +37,20 @@ FILE fqName: fileName:/withArgumentAdaptationAndReceiver.kt CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Host' type=.Host origin=null ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUNCTION_REFERENCE 'public final fun withVararg (vararg xs: kotlin.Int): kotlin.String declared in .Host' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= + $this: GET_VAR 'var h: .Host [var] declared in .Host.testBoundReceiverLocalVar' type=.Host origin=null FUN name:testBoundReceiverParameter visibility:public modality:FINAL <> ($this:.Host, h:.Host) returnType:kotlin.Unit $this: VALUE_PARAMETER name: type:.Host VALUE_PARAMETER name:h index:0 type:.Host BLOCK_BODY ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUNCTION_REFERENCE 'public final fun withVararg (vararg xs: kotlin.Int): kotlin.String declared in .Host' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= + $this: GET_VAR 'h: .Host declared in .Host.testBoundReceiverParameter' type=.Host origin=null FUN name:testBoundReceiverExpression visibility:public modality:FINAL <> ($this:.Host) returnType:kotlin.Unit $this: VALUE_PARAMETER name: type:.Host BLOCK_BODY ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUNCTION_REFERENCE 'public final fun withVararg (vararg xs: kotlin.Int): kotlin.String declared in .Host' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= + $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Host' type=.Host 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 diff --git a/compiler/testData/ir/irText/expressions/reflectionLiterals.fir.txt b/compiler/testData/ir/irText/expressions/reflectionLiterals.fir.txt index 920d1d54df9..cef9c290d56 100644 --- a/compiler/testData/ir/irText/expressions/reflectionLiterals.fir.txt +++ b/compiler/testData/ir/irText/expressions/reflectionLiterals.fir.txt @@ -73,6 +73,7 @@ FILE fqName: fileName:/reflectionLiterals.kt FIELD PROPERTY_BACKING_FIELD name:test5 type:kotlin.reflect.KFunction0 visibility:private [final,static] EXPRESSION_BODY FUNCTION_REFERENCE 'public final fun foo (): kotlin.Unit declared in .A' type=kotlin.reflect.KFunction0 origin=null reflectionTarget= + $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .A' type=.A origin=null FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KFunction0 correspondingProperty: PROPERTY name:test5 visibility:public modality:FINAL [val] BLOCK_BODY