From e23325b014368fd35e6ab575c5323d67d647bdf4 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 7 Sep 2016 12:31:34 +0300 Subject: [PATCH] Bound callable references. --- .../ReflectionReferencesGenerator.kt | 21 +++++++++++++--- .../expressions/boundCallableReferences.kt | 12 +++++++++ .../expressions/boundCallableReferences.txt | 25 +++++++++++++++++++ .../irText/expressions/reflectionLiterals.txt | 1 + .../kotlin/ir/IrTextTestCaseGenerated.java | 6 +++++ 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/ir/irText/expressions/boundCallableReferences.kt create mode 100644 compiler/testData/ir/irText/expressions/boundCallableReferences.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt index 60a9ea257f7..ed2856a23e0 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtClassLiteralExpression import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver import org.jetbrains.kotlin.types.expressions.DoubleColonLHS class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { @@ -48,10 +49,22 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St fun generateCallableReference(ktCallableReference: KtCallableReferenceExpression): IrExpression { val resolvedCall = getResolvedCall(ktCallableReference.callableReference)!! - // TODO bound method references - return IrCallableReferenceImpl(ktCallableReference.startOffset, ktCallableReference.endOffset, - getInferredTypeWithImplicitCastsOrFail(ktCallableReference), - resolvedCall.resultingDescriptor) + val irCallableRef = IrCallableReferenceImpl(ktCallableReference.startOffset, ktCallableReference.endOffset, + getInferredTypeWithImplicitCastsOrFail(ktCallableReference), + resolvedCall.resultingDescriptor) + resolvedCall.dispatchReceiver?.let { dispatchReceiver -> + if (dispatchReceiver !is TransientReceiver) { + irCallableRef.dispatchReceiver = statementGenerator.generateReceiver(ktCallableReference, dispatchReceiver).load() + } + } + resolvedCall.extensionReceiver?.let { extensionReceiver -> + if (extensionReceiver !is TransientReceiver) { + irCallableRef.extensionReceiver = statementGenerator.generateReceiver(ktCallableReference, extensionReceiver).load() + } + } + + return irCallableRef } + } \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/boundCallableReferences.kt b/compiler/testData/ir/irText/expressions/boundCallableReferences.kt new file mode 100644 index 00000000000..715ccd5f2b8 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/boundCallableReferences.kt @@ -0,0 +1,12 @@ +class A { + fun foo() {} + val bar = 0 +} + +fun A.qux() {} + +val test1 = A()::foo + +val test2 = A()::bar + +val test3 = A()::qux diff --git a/compiler/testData/ir/irText/expressions/boundCallableReferences.txt b/compiler/testData/ir/irText/expressions/boundCallableReferences.txt new file mode 100644 index 00000000000..7a445704af9 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/boundCallableReferences.txt @@ -0,0 +1,25 @@ +FILE /boundCallableReferences.kt + CLASS CLASS A + CONSTRUCTOR public constructor A() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='A' + FUN public final fun foo(): kotlin.Unit + BLOCK_BODY + PROPERTY public final val bar: kotlin.Int = 0 + EXPRESSION_BODY + CONST Int type=kotlin.Int value='0' + FUN public fun A.qux(): kotlin.Unit + BLOCK_BODY + PROPERTY public val test1: kotlin.reflect.KFunction0 + EXPRESSION_BODY + CALLABLE_REFERENCE 'foo(): Unit' type=kotlin.reflect.KFunction0 operator=null + $this: CALL 'constructor A()' type=A operator=null + PROPERTY public val test2: kotlin.reflect.KProperty0 + EXPRESSION_BODY + CALLABLE_REFERENCE 'bar: Int' type=kotlin.reflect.KProperty0 operator=null + $this: CALL 'constructor A()' type=A operator=null + PROPERTY public val test3: kotlin.reflect.KFunction0 + EXPRESSION_BODY + CALLABLE_REFERENCE 'qux() on A: Unit' type=kotlin.reflect.KFunction0 operator=null + $receiver: CALL 'constructor A()' type=A operator=null diff --git a/compiler/testData/ir/irText/expressions/reflectionLiterals.txt b/compiler/testData/ir/irText/expressions/reflectionLiterals.txt index 62dc051272f..d9d7a7bd037 100644 --- a/compiler/testData/ir/irText/expressions/reflectionLiterals.txt +++ b/compiler/testData/ir/irText/expressions/reflectionLiterals.txt @@ -27,6 +27,7 @@ FILE /reflectionLiterals.kt PROPERTY public val test5: kotlin.reflect.KFunction0 EXPRESSION_BODY CALLABLE_REFERENCE 'foo(): Unit' type=kotlin.reflect.KFunction0 operator=null + $this: CALL 'constructor A()' type=A operator=null PROPERTY public val test6: kotlin.reflect.KFunction0 EXPRESSION_BODY CALLABLE_REFERENCE 'bar(): Unit' type=kotlin.reflect.KFunction0 operator=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index cf7c49ae70f..14fba26a0f7 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -298,6 +298,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("boundCallableReferences.kt") + public void testBoundCallableReferences() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/boundCallableReferences.kt"); + doTest(fileName); + } + @TestMetadata("boxOk.kt") public void testBoxOk() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/boxOk.kt");