From 6670e4b21da2baf5ef4ee67fa217cd03aac51616 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Wed, 23 Sep 2020 14:38:12 +0300 Subject: [PATCH] [JS IR] Fix callable reference to generic constructor - add tests - fix KT-42025 --- .../ir/FirBlackBoxCodegenTestGenerated.java | 5 + .../js/lower/CallableReferenceLowering.kt | 25 ++++- .../genericConstructorReference.kt | 100 ++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 + .../LightAnalysisModeTestGenerated.java | 5 + .../ir/IrBlackBoxCodegenTestGenerated.java | 5 + .../IrJsCodegenBoxES6TestGenerated.java | 5 + .../IrJsCodegenBoxTestGenerated.java | 5 + .../semantics/JsCodegenBoxTestGenerated.java | 5 + 9 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/callableReference/genericConstructorReference.kt diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index e761f4ab11f..cdf5140a327 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -2003,6 +2003,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt"); } + @TestMetadata("genericConstructorReference.kt") + public void testGenericConstructorReference() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/genericConstructorReference.kt"); + } + @TestMetadata("kt37604.kt") public void testKt37604() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt37604.kt"); diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt index 1c5fad632b7..6a5bc4c20c8 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt @@ -213,10 +213,31 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod fun getValue(d: IrValueDeclaration): IrGetValue = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, d.type, d.symbol, CALLABLE_REFERENCE_INVOKE) + /** + inner class IN { + private fun foo() { + class CC(t: T, tt: TT, ttt: IT) + } + } + */ + + private fun IrConstructor.countContextTypeParameters(): Int { + fun countImpl(container: IrDeclarationParent): Int { + return when (container) { + is IrClass -> container.typeParameters.size + container.run { if (isInner) countImpl(container.parent) else 0 } + is IrFunction -> container.typeParameters.size + countImpl(container.parent) + is IrProperty -> (container.run { getter ?: setter }?.typeParameters?.size ?: 0) + countImpl(container.parent) + is IrDeclaration -> countImpl(container.parent) + else -> 0 + } + } + + return countImpl(parent) + } private fun IrSimpleFunction.buildInvoke(): IrFunctionAccessExpression { val callee = function - val irCall = reference.run { + val irCall = reference.run { when (callee) { is IrConstructor -> IrConstructorCallImpl( @@ -224,8 +245,8 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod endOffset, callee.parentAsClass.defaultType, callee.symbol, + callee.countContextTypeParameters(), callee.typeParameters.size, - 0 /* TODO */, callee.valueParameters.size, CALLABLE_REFERENCE_INVOKE ) diff --git a/compiler/testData/codegen/box/callableReference/genericConstructorReference.kt b/compiler/testData/codegen/box/callableReference/genericConstructorReference.kt new file mode 100644 index 00000000000..4fec1e7cd07 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/genericConstructorReference.kt @@ -0,0 +1,100 @@ + +// IGNORE_BACKEND: JVM_IR +// IGNORE_BACKEND_FIR: JVM_IR +// KT-42025 + +open class L(val ll: LL) + +class Rec(val rt: T) + +public class Outer(val ot: OT) { + fun bar(ft: FT): Outer { + return foo1(ft, ::Outer) + } + + fun local1(ft: FT): L { + class Local1(val lt: LT, val ooot: OT): L(lt) + return foo2(ft, ot, ::Local1) + } + + fun createS(ss: SS): Static = foo1(ss, ::Static) + + fun createI(ii: II) = foo2(ii, ot, ::Inner) + + public class Static(val st: ST) { + public fun bar(fft: FT): Static { + return foo1(fft, ::Static) + } + + public fun local2(ft: FT): L { + class Local2(val lt: LT, val sst: ST): L(lt) + return foo2(ft, st, ::Local2) + } + } + + public inner class Inner(val it: IT, val oot: OT) { + public fun bar(fft: FT): Inner { + return foo2(fft, ot, ::Inner) + } + + public fun local3(fft: FT): L { + class Local3(val lt: LT, val iit: IT, val ooot: OT): L(lt) + return foo3(fft, it, ot, ::Local3) + } + + public fun local4(fft: FT): L { + class Local4(val lt: LT, val iit: IT, val ooot: OT, val ffff: FT): L(lt) + return foo4(fft, it, ot, fft, ::Local4) + } + + public val Rec.p: L + get() { + class PLocal(lt: LT, val pt: PT): L(lt) + return foo2(rt, rt, ::PLocal) + } + + fun readP(r: Rec) = r.p + } + +} + +fun foo1(t1: T1, bb: (T1) -> R): R = bb(t1) +fun foo2(t1: T1, t2: T2, bb: (T1, T2) -> R): R = bb(t1, t2) +fun foo3(t1: T1, t2: T2, t3: T3, bb: (T1, T2, T3) -> R): R = bb(t1, t2, t3) +fun foo4(t1: T1, t2: T2, t3: T3, t4: T4, bb: (T1, T2, T3, T4) -> R): R = bb(t1, t2, t3, t4) + +fun box(): String { + + // outer + val o = foo1(42, ::Outer) + if (o.ot != 42) return "FAIL1: ${o.ot}" + val ob = o.bar("42") + if (ob.ot != "42") return "FAIL2: ${ob.ot}" + val l1 = o.local1(42L) + if (l1.ll != 42L) return "FAIL3: ${l1.ll}" + + // static + val s = o.createS("ST") + if (s.st != "ST") return "FAIL4: ${s.st}" + val sb = s.bar("SB") + if (sb.st != "SB") return "FAIL5: ${sb.st}" + val sl = s.local2("SL") + if (sl.ll != "SL") return "FAIL6: ${sl.ll}" + + // inner + val i = o.createI("II") + if (i.it != "II") return "FAIL7: ${i.it}" + + val ib = i.bar("IBar") + if (ib.it != "IBar" && ib.oot != 42) return "FAIL8: ${ib.it} && ${ib.oot}" + + val il = i.local3("IL") + if (il.ll != "IL") return "FAIL9: ${il.ll}" + + val il4 = i.local4("IL4") + if (il4.ll != "IL4") return "FAIL10: ${il4.ll}" + + val ipl = i.readP(Rec("OK")) + + return ipl.ll +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index bf5ea7dd022..3d3871051bb 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -2023,6 +2023,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt"); } + @TestMetadata("genericConstructorReference.kt") + public void testGenericConstructorReference() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/genericConstructorReference.kt"); + } + @TestMetadata("kt37604.kt") public void testKt37604() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt37604.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 4089ecaf504..ff50721023b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2023,6 +2023,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt"); } + @TestMetadata("genericConstructorReference.kt") + public void testGenericConstructorReference() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/genericConstructorReference.kt"); + } + @TestMetadata("kt37604.kt") public void testKt37604() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt37604.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 235be01da79..2f32b8765e7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -2003,6 +2003,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt"); } + @TestMetadata("genericConstructorReference.kt") + public void testGenericConstructorReference() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/genericConstructorReference.kt"); + } + @TestMetadata("kt37604.kt") public void testKt37604() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt37604.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 2a57674bdc5..9ce50970d08 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -1453,6 +1453,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } + @TestMetadata("genericConstructorReference.kt") + public void testGenericConstructorReference() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/genericConstructorReference.kt"); + } + @TestMetadata("kt37604.kt") public void testKt37604() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt37604.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 535853c06b4..7b4324ec2df 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -1453,6 +1453,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + @TestMetadata("genericConstructorReference.kt") + public void testGenericConstructorReference() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/genericConstructorReference.kt"); + } + @TestMetadata("kt37604.kt") public void testKt37604() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt37604.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 66b4c70a191..8db9e2552da 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -1453,6 +1453,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + @TestMetadata("genericConstructorReference.kt") + public void testGenericConstructorReference() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/genericConstructorReference.kt"); + } + @TestMetadata("kt37604.kt") public void testKt37604() throws Exception { runTest("compiler/testData/codegen/box/callableReference/kt37604.kt");