[K/N] Fix work with adapted function references
Their parsing was totally incorrect for K2, and sometimes incorrect for K1. After this commit it uses same code as for JVM. ^KT-55462
This commit is contained in:
committed by
Space Team
parent
9a693fa967
commit
cb655d2d37
+6
@@ -3826,6 +3826,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
+2
@@ -463,6 +463,8 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
private val useOptimizedSuperClass =
|
||||
context.state.generateOptimizedCallableReferenceSuperClasses
|
||||
|
||||
// This code is partially duplicated in IrUtils getAdapteeFromAdaptedForReferenceFunction
|
||||
// The difference is utils version supports ReturnableBlock, but returns called function instead of call node.
|
||||
private val adapteeCall: IrFunctionAccessExpression? =
|
||||
if (callee.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) {
|
||||
// The body of a callable reference adapter contains either only a call, or an IMPLICIT_COERCION_TO_UNIT type operator
|
||||
|
||||
@@ -1368,3 +1368,24 @@ val IrFunction.isValueClassTypedEquals: Boolean
|
||||
&& contextReceiverParametersCount == 0 && extensionReceiverParameter == null
|
||||
&& (parentClass.isValue)
|
||||
}
|
||||
|
||||
// This code is partially duplicated in jvm FunctionReferenceLowering::adapteeCall
|
||||
// The difference is jvm version doesn't support ReturnableBlock, but returns call node instead of called function.
|
||||
fun IrFunction.getAdapteeFromAdaptedForReferenceFunction() : IrFunction? {
|
||||
if (origin != IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) return null
|
||||
// The body of a callable reference adapter contains either only a call, or an IMPLICIT_COERCION_TO_UNIT type operator
|
||||
// applied to a either a call or ReturnableBlock produced from that call inlining.
|
||||
// That call's target is the original function which we need to get.
|
||||
fun unknownStructure(): Nothing = throw UnsupportedOperationException("Unknown structure of ADAPTER_FOR_CALLABLE_REFERENCE: ${dump()}")
|
||||
val call = when (val statement = body?.statements?.singleOrNull() ?: unknownStructure()) {
|
||||
is IrTypeOperatorCall -> {
|
||||
if (statement.operator != IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) unknownStructure()
|
||||
statement.argument
|
||||
}
|
||||
is IrReturn -> statement.value
|
||||
else -> statement
|
||||
}
|
||||
if (call is IrReturnableBlock) return (call.inlineFunctionSymbol ?: unknownStructure()).owner
|
||||
if (call !is IrFunctionAccessExpression) { unknownStructure() }
|
||||
return call.symbol.owner
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
// WASM_MUTE_REASON: FAILS_IN_JS_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// KT-55462
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
// FILE: test.kt
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// WASM_MUTE_REASON: FAILS_IN_JS_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// KT-55462
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
// FILE: test.kt
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// WASM_MUTE_REASON: FAILS_IN_JS_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// KT-55462
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
// FILE: test.kt
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
|
||||
-2
@@ -2,8 +2,6 @@
|
||||
// WASM_MUTE_REASON: FAILS_IN_JS_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// KT-55462
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
// FILE: test.kt
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
|
||||
-2
@@ -2,8 +2,6 @@
|
||||
// WASM_MUTE_REASON: FAILS_IN_JS_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// KT-55462
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
// FILE: test.kt
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// WITH_STDLIB
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: FAILS_IN_JS_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
if (x != y || y != x) throw AssertionError("$x and $y should be equal")
|
||||
if (x.hashCode() != y.hashCode()) throw AssertionError("$x and $y should have the same hash code")
|
||||
}
|
||||
|
||||
|
||||
inline fun inlineF(a:Int, vararg b: String, c: Int = 0) = 0
|
||||
inline fun <reified T> inlineReifiedF(a: T, vararg b: String, c: Int = 0) = 0
|
||||
fun normalF(a:Int, vararg b: String, c: Int = 0) = 0
|
||||
|
||||
fun noConversion(ref: (Int, Array<String>, Int) -> Int) = ref
|
||||
fun suspendConversion(ref: suspend (Int, Array<String>, Int) -> Int) = ref
|
||||
fun unitConversion(ref: (Int, Array<String>, Int) -> Unit) = ref
|
||||
fun defaultConversion(ref: (Int, Array<String>) -> Int) = ref
|
||||
fun varargConversion(ref: (Int, String, Int) -> Int) = ref
|
||||
fun suspendAndUnitConversion(ref: suspend (Int, Array<String>, Int) -> Unit) = ref
|
||||
fun suspendAndDefaultConversion(ref: suspend (Int, Array<String>) -> Int) = ref
|
||||
fun suspendAndVarargConversion(ref: suspend (Int, String, Int) -> Int) = ref
|
||||
fun unitAndDefaultConversion(ref: (Int, Array<String>) -> Unit) = ref
|
||||
fun unitAndVarargConversion(ref: (Int, String, Int) -> Unit) = ref
|
||||
fun defaultAndVarargConversion(ref: (Int, String) -> Int) = ref
|
||||
fun allExceptSuspendConversion(ref: (Int, String) -> Unit) = ref
|
||||
fun allExceptUnitConversion(ref: suspend (Int, String) -> Int) = ref
|
||||
fun allExceptVarargConversion(ref: suspend (Int, Array<String>) -> Unit) = ref
|
||||
fun allExceptDefaultConversion(ref: suspend (Int, String, Int) -> Unit) = ref
|
||||
fun allConversions(ref: suspend (Int, String) -> Unit) = ref
|
||||
|
||||
fun testNormal() {
|
||||
checkEqual(noConversion(::normalF), noConversion(::normalF))
|
||||
checkEqual(suspendConversion(::normalF), suspendConversion(::normalF))
|
||||
checkEqual(unitConversion(::normalF), unitConversion(::normalF))
|
||||
checkEqual(defaultConversion(::normalF), defaultConversion(::normalF))
|
||||
checkEqual(varargConversion(::normalF), varargConversion(::normalF))
|
||||
checkEqual(suspendAndUnitConversion(::normalF), suspendAndUnitConversion(::normalF))
|
||||
checkEqual(suspendAndDefaultConversion(::normalF), suspendAndDefaultConversion(::normalF))
|
||||
checkEqual(suspendAndVarargConversion(::normalF), suspendAndVarargConversion(::normalF))
|
||||
checkEqual(unitAndDefaultConversion(::normalF), unitAndDefaultConversion(::normalF))
|
||||
checkEqual(unitAndVarargConversion(::normalF), unitAndVarargConversion(::normalF))
|
||||
checkEqual(defaultAndVarargConversion(::normalF), defaultAndVarargConversion(::normalF))
|
||||
checkEqual(allExceptSuspendConversion(::normalF), allExceptSuspendConversion(::normalF))
|
||||
checkEqual(allExceptUnitConversion(::normalF), allExceptUnitConversion(::normalF))
|
||||
checkEqual(allExceptVarargConversion(::normalF), allExceptVarargConversion(::normalF))
|
||||
checkEqual(allExceptDefaultConversion(::normalF), allExceptDefaultConversion(::normalF))
|
||||
checkEqual(allConversions(::normalF), allConversions(::normalF))
|
||||
}
|
||||
|
||||
fun testInline() {
|
||||
checkEqual(noConversion(::inlineF), noConversion(::inlineF))
|
||||
checkEqual(suspendConversion(::inlineF), suspendConversion(::inlineF))
|
||||
checkEqual(unitConversion(::inlineF), unitConversion(::inlineF))
|
||||
checkEqual(defaultConversion(::inlineF), defaultConversion(::inlineF))
|
||||
checkEqual(varargConversion(::inlineF), varargConversion(::inlineF))
|
||||
checkEqual(suspendAndUnitConversion(::inlineF), suspendAndUnitConversion(::inlineF))
|
||||
checkEqual(suspendAndDefaultConversion(::inlineF), suspendAndDefaultConversion(::inlineF))
|
||||
checkEqual(suspendAndVarargConversion(::inlineF), suspendAndVarargConversion(::inlineF))
|
||||
checkEqual(unitAndDefaultConversion(::inlineF), unitAndDefaultConversion(::inlineF))
|
||||
checkEqual(unitAndVarargConversion(::inlineF), unitAndVarargConversion(::inlineF))
|
||||
checkEqual(defaultAndVarargConversion(::inlineF), defaultAndVarargConversion(::inlineF))
|
||||
checkEqual(allExceptSuspendConversion(::inlineF), allExceptSuspendConversion(::inlineF))
|
||||
checkEqual(allExceptUnitConversion(::inlineF), allExceptUnitConversion(::inlineF))
|
||||
checkEqual(allExceptVarargConversion(::inlineF), allExceptVarargConversion(::inlineF))
|
||||
checkEqual(allExceptDefaultConversion(::inlineF), allExceptDefaultConversion(::inlineF))
|
||||
checkEqual(allConversions(::inlineF), allConversions(::inlineF))
|
||||
}
|
||||
|
||||
fun testInlineReifined() {
|
||||
checkEqual(noConversion(::inlineReifiedF), noConversion(::inlineReifiedF))
|
||||
checkEqual(suspendConversion(::inlineReifiedF), suspendConversion(::inlineReifiedF))
|
||||
checkEqual(unitConversion(::inlineReifiedF), unitConversion(::inlineReifiedF))
|
||||
checkEqual(defaultConversion(::inlineReifiedF), defaultConversion(::inlineReifiedF))
|
||||
checkEqual(varargConversion(::inlineReifiedF), varargConversion(::inlineReifiedF))
|
||||
checkEqual(suspendAndUnitConversion(::inlineReifiedF), suspendAndUnitConversion(::inlineReifiedF))
|
||||
checkEqual(suspendAndDefaultConversion(::inlineReifiedF), suspendAndDefaultConversion(::inlineReifiedF))
|
||||
checkEqual(suspendAndVarargConversion(::inlineReifiedF), suspendAndVarargConversion(::inlineReifiedF))
|
||||
checkEqual(unitAndDefaultConversion(::inlineReifiedF), unitAndDefaultConversion(::inlineReifiedF))
|
||||
checkEqual(unitAndVarargConversion(::inlineReifiedF), unitAndVarargConversion(::inlineReifiedF))
|
||||
checkEqual(defaultAndVarargConversion(::inlineReifiedF), defaultAndVarargConversion(::inlineReifiedF))
|
||||
checkEqual(allExceptSuspendConversion(::inlineReifiedF), allExceptSuspendConversion(::inlineReifiedF))
|
||||
checkEqual(allExceptUnitConversion(::inlineReifiedF), allExceptUnitConversion(::inlineReifiedF))
|
||||
checkEqual(allExceptVarargConversion(::inlineReifiedF), allExceptVarargConversion(::inlineReifiedF))
|
||||
checkEqual(allExceptDefaultConversion(::inlineReifiedF), allExceptDefaultConversion(::inlineReifiedF))
|
||||
checkEqual(allConversions(::inlineReifiedF), allConversions(::inlineReifiedF))
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
testNormal()
|
||||
testInline()
|
||||
testInlineReifined()
|
||||
|
||||
val allRefs = mapOf(
|
||||
"noConversionNormal" to noConversion(::normalF),
|
||||
"suspendConversionNormal" to suspendConversion(::normalF),
|
||||
"unitConversionNormal" to unitConversion(::normalF),
|
||||
"defaultConversionNormal" to defaultConversion(::normalF),
|
||||
"varargConversionNormal" to varargConversion(::normalF),
|
||||
"suspendAndUnitConversionNormal" to suspendAndUnitConversion(::normalF),
|
||||
"suspendAndDefaultConversionNormal" to suspendAndDefaultConversion(::normalF),
|
||||
"suspendAndVarargConversionNormal" to suspendAndVarargConversion(::normalF),
|
||||
"unitAndDefaultConversionNormal" to unitAndDefaultConversion(::normalF),
|
||||
"unitAndVarargConversionNormal" to unitAndVarargConversion(::normalF),
|
||||
"defaultAndVarargConversionNormal" to defaultAndVarargConversion(::normalF),
|
||||
"allExceptSuspendConversionNormal" to allExceptSuspendConversion(::normalF),
|
||||
"allExceptUnitConversionNormal" to allExceptUnitConversion(::normalF),
|
||||
"allExceptVarargConversionNormal" to allExceptVarargConversion(::normalF),
|
||||
"allExceptDefaultConversionNormal" to allExceptDefaultConversion(::normalF),
|
||||
"allConversionsNormal" to allConversions(::normalF),
|
||||
|
||||
"noConversionInline" to noConversion(::inlineF),
|
||||
"suspendConversionInline" to suspendConversion(::inlineF),
|
||||
"unitConversionInline" to unitConversion(::inlineF),
|
||||
"defaultConversionInline" to defaultConversion(::inlineF),
|
||||
"varargConversionInline" to varargConversion(::inlineF),
|
||||
"suspendAndUnitConversionInline" to suspendAndUnitConversion(::inlineF),
|
||||
"suspendAndDefaultConversionInline" to suspendAndDefaultConversion(::inlineF),
|
||||
"suspendAndVarargConversionInline" to suspendAndVarargConversion(::inlineF),
|
||||
"unitAndDefaultConversionInline" to unitAndDefaultConversion(::inlineF),
|
||||
"unitAndVarargConversionInline" to unitAndVarargConversion(::inlineF),
|
||||
"defaultAndVarargConversionInline" to defaultAndVarargConversion(::inlineF),
|
||||
"allExceptSuspendConversionInline" to allExceptSuspendConversion(::inlineF),
|
||||
"allExceptUnitConversionInline" to allExceptUnitConversion(::inlineF),
|
||||
"allExceptVarargConversionInline" to allExceptVarargConversion(::inlineF),
|
||||
"allExceptDefaultConversionInline" to allExceptDefaultConversion(::inlineF),
|
||||
"allConversionsInline" to allConversions(::inlineF),
|
||||
|
||||
"noConversionInlineReified" to noConversion(::inlineReifiedF),
|
||||
"suspendConversionInlineReified" to suspendConversion(::inlineReifiedF),
|
||||
"unitConversionInlineReified" to unitConversion(::inlineReifiedF),
|
||||
"defaultConversionInlineReified" to defaultConversion(::inlineReifiedF),
|
||||
"varargConversionInlineReified" to varargConversion(::inlineReifiedF),
|
||||
"suspendAndUnitConversionInlineReified" to suspendAndUnitConversion(::inlineReifiedF),
|
||||
"suspendAndDefaultConversionInlineReified" to suspendAndDefaultConversion(::inlineReifiedF),
|
||||
"suspendAndVarargConversionInlineReified" to suspendAndVarargConversion(::inlineReifiedF),
|
||||
"unitAndDefaultConversionInlineReified" to unitAndDefaultConversion(::inlineReifiedF),
|
||||
"unitAndVarargConversionInlineReified" to unitAndVarargConversion(::inlineReifiedF),
|
||||
"defaultAndVarargConversionInlineReified" to defaultAndVarargConversion(::inlineReifiedF),
|
||||
"allExceptSuspendConversionInlineReified" to allExceptSuspendConversion(::inlineReifiedF),
|
||||
"allExceptUnitConversionInlineReified" to allExceptUnitConversion(::inlineReifiedF),
|
||||
"allExceptVarargConversionInlineReified" to allExceptVarargConversion(::inlineReifiedF),
|
||||
"allExceptDefaultConversionInlineReified" to allExceptDefaultConversion(::inlineReifiedF),
|
||||
"allConversionsInlineReified" to allConversions(::inlineReifiedF),
|
||||
)
|
||||
|
||||
for ((name1, ref1) in allRefs) {
|
||||
for ((name2, ref2) in allRefs) {
|
||||
if (name1 != name2) {
|
||||
if (ref1 == ref2) {
|
||||
return "$name1 and $name2 wrappers should not be equal"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+22
@@ -1,9 +1,19 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: FAILS_IN_JS_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// FILE: suspendCovnersion.kt
|
||||
|
||||
|
||||
fun checkNotEqual(x: Any, y: Any) {
|
||||
if (x == y || y == x) throw AssertionError("$x and $y should NOT be equal")
|
||||
}
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
if (x != y || y != x) throw AssertionError("$x and $y should be equal")
|
||||
if (x.hashCode() != y.hashCode()) throw AssertionError("$x and $y should have the same hash code")
|
||||
}
|
||||
|
||||
|
||||
fun capturePlain(fn: () -> Unit): Any = fn
|
||||
fun captureSuspend(fn: suspend () -> Unit): Any = fn
|
||||
@@ -26,18 +36,30 @@ fun box(): String {
|
||||
val c = C()
|
||||
|
||||
checkNotEqual(capturePlain(::foo), captureSuspend(::foo))
|
||||
checkEqual(capturePlain(::foo), capturePlain(::foo))
|
||||
checkEqual(captureSuspend(::foo), captureSuspend(::foo))
|
||||
checkNotEqual(capturePlain(c::memberFun), captureSuspend(c::memberFun))
|
||||
checkEqual(capturePlain(c::memberFun), capturePlain(c::memberFun))
|
||||
checkEqual(captureSuspend(c::memberFun), captureSuspend(c::memberFun))
|
||||
|
||||
checkNotEqual(captureOther1(), captureOther2())
|
||||
checkNotEqual(captureBoundOther1(c), captureBoundOther2(c))
|
||||
|
||||
checkNotEqual(capturePlainInt(::fnWithVararg), captureSuspendInt(::fnWithVararg))
|
||||
checkNotEqual(captureSuspend(::fnWithVararg), captureSuspendInt(::fnWithVararg))
|
||||
checkEqual(capturePlainInt(::fnWithVararg), capturePlainInt(::fnWithVararg))
|
||||
checkEqual(captureSuspendInt(::fnWithVararg), captureSuspendInt(::fnWithVararg))
|
||||
checkEqual(captureSuspend(::fnWithVararg), captureSuspend(::fnWithVararg))
|
||||
|
||||
checkNotEqual(capturePlainInt(::fnWithDefault), captureSuspendInt(::fnWithDefault))
|
||||
checkNotEqual(captureSuspend(::fnWithDefault), captureSuspendInt(::fnWithDefault))
|
||||
checkEqual(capturePlainInt(::fnWithDefault), capturePlainInt(::fnWithDefault))
|
||||
checkEqual(captureSuspendInt(::fnWithDefault), captureSuspendInt(::fnWithDefault))
|
||||
checkEqual(captureSuspend(::fnWithDefault), captureSuspend(::fnWithDefault))
|
||||
|
||||
checkNotEqual(capturePlain(::fnReturnsInt), captureSuspend(::fnReturnsInt))
|
||||
checkEqual(capturePlain(::fnReturnsInt), capturePlain(::fnReturnsInt))
|
||||
checkEqual(captureSuspend(::fnReturnsInt), captureSuspend(::fnReturnsInt))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
-2
@@ -2,8 +2,6 @@
|
||||
// WASM_MUTE_REASON: FAILS_IN_JS_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// KT-55462
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
// FILE: test.kt
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
|
||||
-2
@@ -1,8 +1,6 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: IGNORED_IN_JS
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6
|
||||
// KT-55463
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
// FILE: test.kt
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
|
||||
-2
@@ -1,8 +1,6 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: IGNORED_IN_JS
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6
|
||||
// KT-55463
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
// FILE: test.kt
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
|
||||
-2
@@ -1,8 +1,6 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: IGNORED_IN_JS
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6
|
||||
// KT-55463
|
||||
// IGNORE_BACKEND_K2: NATIVE
|
||||
|
||||
fun checkEqual(x: Any, y: Any) {
|
||||
if (x != y || y != x) throw AssertionError("$x and $y should be equal")
|
||||
|
||||
+6
@@ -3718,6 +3718,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
+6
@@ -3826,6 +3826,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
+5
@@ -3219,6 +3219,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Equality extends AbstractLightAnalysisModeTest {
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void ignoreConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
+6
@@ -2524,6 +2524,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
+6
@@ -2578,6 +2578,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
+6
@@ -2578,6 +2578,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
+6
@@ -2578,6 +2578,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
+5
@@ -2292,6 +2292,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/extensionReceiverVsDefault.kt");
|
||||
|
||||
+20
-14
@@ -155,12 +155,17 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
|
||||
break
|
||||
}
|
||||
|
||||
if (!expression.type.isFunction() && !expression.type.isKFunction()
|
||||
&& !expression.type.isKSuspendFunction()) {
|
||||
if (!expression.type.isFunction() && !expression.type.isKFunction() &&
|
||||
!expression.type.isKSuspendFunction() && !expression.type.isSuspendFunction()) {
|
||||
// Not a subject of this lowering.
|
||||
return expression
|
||||
}
|
||||
|
||||
if (expression.origin.isLambda && expression.type.isSuspendFunction()) {
|
||||
// Handled later by coroutines lowerings
|
||||
return expression
|
||||
}
|
||||
|
||||
return transformFunctionReference(expression)
|
||||
}
|
||||
|
||||
@@ -203,12 +208,10 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
|
||||
private val unboundFunctionParameters = functionParameters - boundFunctionParameters
|
||||
|
||||
private val isLambda = functionReference.origin.isLambda
|
||||
private val isKFunction = functionReference.type.isKFunction()
|
||||
private val isKSuspendFunction = functionReference.type.isKSuspendFunction()
|
||||
|
||||
private val adaptedReferenceOriginalTarget: IrFunction? = functionReference.reflectionTarget?.owner
|
||||
|
||||
private val functionReferenceTarget = adaptedReferenceOriginalTarget ?: referencedFunction
|
||||
private val isK = functionReference.type.isKFunction() || functionReference.type.isKSuspendFunction()
|
||||
private val isSuspend = functionReference.type.isSuspendFunction() || functionReference.type.isKSuspendFunction()
|
||||
private val adaptedReferenceOriginalTarget = referencedFunction.getAdapteeFromAdaptedForReferenceFunction()
|
||||
private val functionReferenceTarget = adaptedReferenceOriginalTarget ?:referencedFunction
|
||||
|
||||
/**
|
||||
* The first element of a pair is a type parameter of [referencedFunction], the second element is its argument in
|
||||
@@ -329,8 +332,8 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
|
||||
)
|
||||
}
|
||||
val superClass = when {
|
||||
isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(functionReturnType)
|
||||
isLambda -> irBuiltIns.anyType
|
||||
isSuspend -> kSuspendFunctionImplSymbol.typeWith(functionReturnType)
|
||||
else -> kFunctionImplSymbol.typeWith(functionReturnType)
|
||||
}
|
||||
val superTypes = mutableListOf(superClass)
|
||||
@@ -342,12 +345,12 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
|
||||
transformedSuperMethod = remappedSuperType.classOrNull!!.functions.single { it.owner.modality == Modality.ABSTRACT }.owner
|
||||
} else {
|
||||
val numberOfParameters = unboundFunctionParameters.size
|
||||
if (isKSuspendFunction) {
|
||||
val suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner
|
||||
if (isSuspend) {
|
||||
val suspendFunctionClass = (if (isK) symbols.kSuspendFunctionN(numberOfParameters) else symbols.suspendFunctionN(numberOfParameters)).owner
|
||||
superTypes += suspendFunctionClass.typeWith(functionParameterAndReturnTypes)
|
||||
transformedSuperMethod = suspendFunctionClass.invokeFun!!
|
||||
} else {
|
||||
val functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner
|
||||
val functionClass = (if (isK) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner
|
||||
superTypes += functionClass.typeWith(functionParameterAndReturnTypes)
|
||||
transformedSuperMethod = functionClass.invokeFun!!
|
||||
}
|
||||
@@ -437,7 +440,7 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
|
||||
|
||||
body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody {
|
||||
val superConstructor = when {
|
||||
isKSuspendFunction -> kSuspendFunctionImplConstructorSymbol.owner
|
||||
this@FunctionReferenceBuilder.isSuspend -> kSuspendFunctionImplConstructorSymbol.owner
|
||||
isLambda -> irBuiltIns.anyClass.owner.constructors.single()
|
||||
else -> kFunctionImplConstructorSymbol.owner
|
||||
}
|
||||
@@ -472,7 +475,7 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
|
||||
listOfNotNull(
|
||||
(1 shl 0).takeIf { referencedFunction.isSuspend },
|
||||
(1 shl 1).takeIf { hasVarargMappedToElement() },
|
||||
(1 shl 2).takeIf { adaptedReferenceOriginalTarget?.isSuspend == false && referencedFunction.isSuspend },
|
||||
(1 shl 2).takeIf { isSuspendConversion() },
|
||||
(1 shl 3).takeIf { isCoercedToUnit() },
|
||||
(1 shl 4).takeIf { isFunInterfaceConstructorAdapter() }
|
||||
).sum()
|
||||
@@ -489,6 +492,9 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
|
||||
private fun isCoercedToUnit() =
|
||||
adaptedReferenceOriginalTarget?.returnType?.isUnit() == false && referencedFunction.returnType.isUnit()
|
||||
|
||||
private fun isSuspendConversion() =
|
||||
adaptedReferenceOriginalTarget?.isSuspend == false && referencedFunction.isSuspend
|
||||
|
||||
private fun hasVarargMappedToElement(): Boolean {
|
||||
if (adaptedReferenceOriginalTarget == null) return false
|
||||
val originalParameters = adaptedReferenceOriginalTarget.allParameters
|
||||
|
||||
+6
@@ -2673,6 +2673,12 @@ public class K2NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
+6
@@ -2640,6 +2640,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/coercionToUnitWithVararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("conversionCombinations.kt")
|
||||
public void testConversionCombinations() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/equality/conversionCombinations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("extensionReceiverVsDefault.kt")
|
||||
public void testExtensionReceiverVsDefault() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user