From 3c093f321d512d077ded2c67aea84efdc8447dfa Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Wed, 22 May 2019 15:06:05 +0200 Subject: [PATCH] Support unbound callable function references in inliner --- .../kotlin/backend/common/ir/IrUtils.kt | 2 +- .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 1 + .../backend/jvm/codegen/IrInlineCodegen.kt | 16 +- .../jvm/lower/CallableReferenceLowering.kt | 2 +- .../lower/InlineCallableRefereceToLambda.kt | 179 ++++++++++++++++++ .../boundFieldReferenceInInline.kt | 18 ++ .../boundFunReferenceInInline.kt | 17 ++ .../boundPropertyReferenceInInline.kt | 16 ++ .../unboundFieldReferenceInInline.kt | 16 ++ ...line.kt => unboundFunReferenceInInline.kt} | 1 - .../unboundPropertyReferenceInInline.kt | 12 ++ .../codegen/BytecodeTextTestGenerated.java | 31 ++- .../ir/IrBytecodeTextTestGenerated.java | 31 ++- 13 files changed, 326 insertions(+), 16 deletions(-) create mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InlineCallableRefereceToLambda.kt create mode 100644 compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt create mode 100644 compiler/testData/codegen/bytecodeText/callableReference/boundFunReferenceInInline.kt create mode 100644 compiler/testData/codegen/bytecodeText/callableReference/boundPropertyReferenceInInline.kt create mode 100644 compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt rename compiler/testData/codegen/bytecodeText/callableReference/{inline.kt => unboundFunReferenceInInline.kt} (88%) create mode 100644 compiler/testData/codegen/bytecodeText/callableReference/unboundPropertyReferenceInInline.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index 875b8a836e1..1302d0a4cbf 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -484,4 +484,4 @@ fun IrClass.addFakeOverrides() { } fun IrValueParameter.isInlineParameter() = - !isNoinline && !type.isNullable() && type.isFunctionOrKFunction() \ No newline at end of file + !isNoinline && !type.isNullable() && (type.isFunction() || type.isSuspendFunctionTypeOrSubtype()) \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index d372f199ea6..6e8903b3d8b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -106,6 +106,7 @@ val jvmPhases = namedIrFilePhase( lateinitPhase then moveOrCopyCompanionObjectFieldsPhase then + inlineCallableReferenceToLambdaPhase then propertyReferencePhase then constPhase then propertiesToFieldsPhase then diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index e6909efc72d..c09acfb171a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen +import org.jetbrains.kotlin.backend.common.ir.isInlineParameter import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.inline.* @@ -14,7 +15,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.Method @@ -161,11 +162,12 @@ class IrExpressionLambdaImpl( } fun isInlineIrExpression(argumentExpression: IrExpression) = - argumentExpression is IrBlock && - (argumentExpression.origin == IrStatementOrigin.LAMBDA || argumentExpression.origin == IrStatementOrigin.ANONYMOUS_FUNCTION) + when (argumentExpression) { + is IrBlock -> (argumentExpression.origin == IrStatementOrigin.LAMBDA || argumentExpression.origin == IrStatementOrigin.ANONYMOUS_FUNCTION) + //TODO: support bound CR + is IrCallableReference -> argumentExpression.dispatchReceiver == null && argumentExpression.extensionReceiver == null + else -> false + } fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) = - (!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && isInline - -fun IrValueParameter.isInlineParameter() = - !isNoinline && !type.isNullable() && type.isFunctionOrKFunction() \ No newline at end of file + (!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && isInline \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt index 4d198b64705..9f05da5b1d6 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.isFunctionOrKFunctionType import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor +import org.jetbrains.kotlin.backend.common.ir.isInlineParameter import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.common.lower.irIfThen @@ -30,7 +31,6 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression -import org.jetbrains.kotlin.backend.jvm.codegen.isInlineParameter import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InlineCallableRefereceToLambda.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InlineCallableRefereceToLambda.kt new file mode 100644 index 00000000000..595a276b99b --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InlineCallableRefereceToLambda.kt @@ -0,0 +1,179 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.jvm.lower + +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext +import org.jetbrains.kotlin.backend.common.ScopeWithIr +import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom +import org.jetbrains.kotlin.backend.common.ir.copyValueParametersToStatic +import org.jetbrains.kotlin.backend.common.ir.isInlineParameter +import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.backend.common.lower.irBlock +import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall +import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter +import org.jetbrains.kotlin.ir.builders.declarations.buildFun +import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.name.Name + +internal val inlineCallableReferenceToLambdaPhase = makeIrFilePhase( + ::InlineCallableReferenceToLambdaPhase, + name = "InlineCallableReferenceToLambdaPhase", + description = "Transform callable reference to inline lambda" +) + +// This lowering transforms CR passed to inline function to lambda which would be inlined +// +// inline fun foo(inlineParameter: (A) -> B): B { +// return inlineParameter() +// } +// +// foo(::smth) -> foo { a -> smth(a) } +// +internal class InlineCallableReferenceToLambdaPhase(val context: JvmBackendContext) : FileLoweringPass { + private val inlinableCR = mutableSetOf() + override fun lower(irFile: IrFile) { + irFile.transformChildrenVoid(object : IrElementTransformerVoidWithContext() { + + override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression { + val callee = expression.symbol.owner + if (callee.isInlineFunctionCall(context)) { + for (valueParameter in callee.valueParameters) { + if (valueParameter.isInlineParameter()) { + expression.getValueArgument(valueParameter.index)?.let { argument -> + if (argument is IrCallableReference && isInlineIrExpression(argument)) { + inlinableCR.add(argument) + } + } + } + } + } + + return super.visitFunctionAccess(expression) + } + + + override fun visitPropertyReference(expression: IrPropertyReference): IrExpression { + if (expression !in inlinableCR) { + return super.visitPropertyReference(expression) + } + + //Use getter if field is absent... + val field = + expression.field?.owner ?: return functionReferenceToLambda(currentScope!!, expression, expression.getter!!.owner) + + //..else use field itself + val irBuilder = + context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset) + + return irBuilder.irBlock(expression, IrStatementOrigin.LAMBDA) { + val newLambda = buildFun { + setSourceRange(expression) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + name = Name.identifier("stub_for_inline") + visibility = Visibilities.LOCAL + returnType = field.type + isSuspend = false + }.apply { + + val receiver = + if (field.isStatic) null + else addValueParameter("receiver", field.parentAsClass.defaultType) + + val lambdaBodyBuilder = this@InlineCallableReferenceToLambdaPhase.context.createIrBuilder(this.symbol) + body = lambdaBodyBuilder.irBlockBody(startOffset, endOffset) { + +irReturn(irGetField(if (receiver != null) irGet(receiver) else null, field)) + } + } + +newLambda + + +IrFunctionReferenceImpl( + expression.startOffset, expression.endOffset, field.type, + newLambda.symbol, newLambda.symbol.descriptor, 0, + IrStatementOrigin.LAMBDA + ) + } + } + + override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { + if (inlinableCR.contains(expression)) { + val referencedFunction = expression.symbol.owner + return functionReferenceToLambda(currentScope!!, expression, referencedFunction) + } + + return super.visitFunctionReference(expression) + } + }) + } + + private fun functionReferenceToLambda( + scope: ScopeWithIr, + expression: IrCallableReference, + referencedFunction: IrFunction + ): IrExpression { + val irBuilder = + context.createIrBuilder(scope.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset) + + return irBuilder.irBlock(expression, IrStatementOrigin.LAMBDA) { + val newLambda = buildFun { + setSourceRange(expression) + origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + name = Name.identifier("stub_for_inline") + visibility = Visibilities.LOCAL + returnType = referencedFunction.returnType + isSuspend = false + }.apply { + if (referencedFunction is IrConstructor) { + copyTypeParametersFrom(referencedFunction.parentAsClass) + } + copyTypeParametersFrom(referencedFunction) + copyValueParametersToStatic(referencedFunction, origin) + val lambdaBodyBuilder = this@InlineCallableReferenceToLambdaPhase.context.createIrBuilder(this.symbol) + body = lambdaBodyBuilder.irBlockBody(startOffset, endOffset) { + var shift = 0 + +irReturn( + irCall(referencedFunction.symbol).also { call -> + + for (it in this@apply.typeParameters) { + call.putTypeArgument(it.index, expression.getTypeArgument(it.index)) + } + + referencedFunction.dispatchReceiverParameter?.let { + call.dispatchReceiver = irGet(valueParameters[shift++]) + } + referencedFunction.extensionReceiverParameter?.let { + call.extensionReceiver = irGet(valueParameters[shift++]) + } + for (it in referencedFunction.valueParameters.indices) { + call.putValueArgument(it, irGet(valueParameters[shift++])) + } + } + ) + } + } + +newLambda + + +IrFunctionReferenceImpl( + expression.startOffset, expression.endOffset, referencedFunction.returnType, + newLambda.symbol, newLambda.symbol.descriptor, referencedFunction.typeParameters.size, + IrStatementOrigin.LAMBDA + ) + } + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt b/compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt new file mode 100644 index 00000000000..36f975a536e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt @@ -0,0 +1,18 @@ +// IGNORE_BACKEND: JVM_IR +// FILE: JClass.java + +public class JClass { + public int field; +} + +// FILE: main.kt +fun box(): String { + return if (call(10, JClass()::field) == 5) "OK" else "fail" +} + +inline fun call(p: Int, s: () -> Int): Int { + return s() +} + +// 1 NEW JClass +// 1 NEW \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/callableReference/boundFunReferenceInInline.kt b/compiler/testData/codegen/bytecodeText/callableReference/boundFunReferenceInInline.kt new file mode 100644 index 00000000000..84106abc1d1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/callableReference/boundFunReferenceInInline.kt @@ -0,0 +1,17 @@ +// IGNORE_BACKEND: JVM_IR +fun box(): String { + return if (call(10, A()::calc) == 5) "OK" else "fail" +} + +class A { + fun calc(p: Int): Int { + return p / 2 + } +} + +inline fun call(p: Int, s: (Int) -> Int): Int { + return s(p) +} + +// 1 NEW A +// 1 NEW \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/callableReference/boundPropertyReferenceInInline.kt b/compiler/testData/codegen/bytecodeText/callableReference/boundPropertyReferenceInInline.kt new file mode 100644 index 00000000000..cdf83f9aa89 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/callableReference/boundPropertyReferenceInInline.kt @@ -0,0 +1,16 @@ +// IGNORE_BACKEND: JVM_IR +fun box(): String { + return if (call(A(10)::calc) == 5) "OK" else "fail" +} + +class A(val p: Int) { + val calc: Int + get() = p / 2 +} + +inline fun call( s: () -> Int): Int { + return s() +} + +// 1 NEW A +// 1 NEW \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt b/compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt new file mode 100644 index 00000000000..30e77d5baa7 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt @@ -0,0 +1,16 @@ +// FILE: JClass.java + +public class JClass { + public static int field; +} + +// FILE: main.kt +fun box(): String { + return if (call(10, JClass::field) == 5) "OK" else "fail" +} + +inline fun call(p: Int, s: () -> Int): Int { + return s() +} + +// 0 NEW \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/callableReference/inline.kt b/compiler/testData/codegen/bytecodeText/callableReference/unboundFunReferenceInInline.kt similarity index 88% rename from compiler/testData/codegen/bytecodeText/callableReference/inline.kt rename to compiler/testData/codegen/bytecodeText/callableReference/unboundFunReferenceInInline.kt index b3f566ac9b1..5e137ea2b38 100644 --- a/compiler/testData/codegen/bytecodeText/callableReference/inline.kt +++ b/compiler/testData/codegen/bytecodeText/callableReference/unboundFunReferenceInInline.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR fun box(): String { return if (call(10, ::calc) == 5) "OK" else "fail" } diff --git a/compiler/testData/codegen/bytecodeText/callableReference/unboundPropertyReferenceInInline.kt b/compiler/testData/codegen/bytecodeText/callableReference/unboundPropertyReferenceInInline.kt new file mode 100644 index 00000000000..bfc3290fbb2 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/callableReference/unboundPropertyReferenceInInline.kt @@ -0,0 +1,12 @@ +fun box(): String { + return if (call(10, Int::calc) == 5) "OK" else "fail" +} + +val Int.calc: Int + get() = this / 2 + +inline fun call(p: Int, s: (Int) -> Int): Int { + return s(p) +} + +// 0 NEW \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 3f13aaaa688..080e5b201b9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -689,15 +689,40 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } - @TestMetadata("inline.kt") - public void testInline() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/callableReference/inline.kt"); + @TestMetadata("boundFieldReferenceInInline.kt") + public void testBoundFieldReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt"); + } + + @TestMetadata("boundFunReferenceInInline.kt") + public void testBoundFunReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/boundFunReferenceInInline.kt"); + } + + @TestMetadata("boundPropertyReferenceInInline.kt") + public void testBoundPropertyReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/boundPropertyReferenceInInline.kt"); } @TestMetadata("nameIntrinsicWithImplicitThis.kt") public void testNameIntrinsicWithImplicitThis() throws Exception { runTest("compiler/testData/codegen/bytecodeText/callableReference/nameIntrinsicWithImplicitThis.kt"); } + + @TestMetadata("unboundFieldReferenceInInline.kt") + public void testUnboundFieldReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt"); + } + + @TestMetadata("unboundFunReferenceInInline.kt") + public void testUnboundFunReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/unboundFunReferenceInInline.kt"); + } + + @TestMetadata("unboundPropertyReferenceInInline.kt") + public void testUnboundPropertyReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/unboundPropertyReferenceInInline.kt"); + } } @TestMetadata("compiler/testData/codegen/bytecodeText/capturedVarsOptimization") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index b7850738bad..d462d496812 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -689,15 +689,40 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } - @TestMetadata("inline.kt") - public void testInline() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/callableReference/inline.kt"); + @TestMetadata("boundFieldReferenceInInline.kt") + public void testBoundFieldReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt"); + } + + @TestMetadata("boundFunReferenceInInline.kt") + public void testBoundFunReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/boundFunReferenceInInline.kt"); + } + + @TestMetadata("boundPropertyReferenceInInline.kt") + public void testBoundPropertyReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/boundPropertyReferenceInInline.kt"); } @TestMetadata("nameIntrinsicWithImplicitThis.kt") public void testNameIntrinsicWithImplicitThis() throws Exception { runTest("compiler/testData/codegen/bytecodeText/callableReference/nameIntrinsicWithImplicitThis.kt"); } + + @TestMetadata("unboundFieldReferenceInInline.kt") + public void testUnboundFieldReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt"); + } + + @TestMetadata("unboundFunReferenceInInline.kt") + public void testUnboundFunReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/unboundFunReferenceInInline.kt"); + } + + @TestMetadata("unboundPropertyReferenceInInline.kt") + public void testUnboundPropertyReferenceInInline() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/unboundPropertyReferenceInInline.kt"); + } } @TestMetadata("compiler/testData/codegen/bytecodeText/capturedVarsOptimization")