JS: support explicit SAM constructor invocation
This commit is contained in:
Generated
+5
@@ -11029,6 +11029,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samConstructorExplicitInvocation.kt")
|
||||
public void testSamConstructorExplicitInvocation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
|
||||
@@ -10,11 +10,37 @@ fun interface CharToAny {
|
||||
fun invoke(c: Char): Any
|
||||
}
|
||||
|
||||
fun foo(c: CharToAny): Any = c.invoke('O')
|
||||
fun interface GenericToAny<T> {
|
||||
fun invoke(t: T): Any
|
||||
}
|
||||
|
||||
fun interface GenericCharToAny: GenericToAny<Char>
|
||||
|
||||
fun foo1(c: CharToAny): Any = c.invoke('1')
|
||||
|
||||
fun <T> foo2(t: T, g: GenericToAny<T>): Any = g.invoke(t)
|
||||
|
||||
fun foo3(c: GenericCharToAny) = c.invoke('3')
|
||||
|
||||
fun box(): String {
|
||||
|
||||
if (foo { it } !is Char) return "fail"
|
||||
val c1 = foo1 { it }
|
||||
if (c1 !is Char || c1 != '1') return "fail1"
|
||||
|
||||
val c2 = foo2<Char>('2') { it }
|
||||
if (c2 !is Char || c2 != '2') return "fail2"
|
||||
|
||||
val c3 = foo3 { it }
|
||||
if (c3 !is Char || c3 != '3') return "fail3"
|
||||
|
||||
val c4 = CharToAny { it }.invoke('4')
|
||||
if (c4 !is Char || c4 != '4') return "fail4"
|
||||
|
||||
val c5 = GenericToAny<Char> { it }.invoke('5')
|
||||
if (c5 !is Char || c5 != '5') return "fail5"
|
||||
|
||||
val c6 = GenericCharToAny { it }.invoke('6')
|
||||
if (c6 !is Char || c6 != '6') return "fail6"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// !LANGUAGE: +FunctionalInterfaceConversion
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
fun interface S {
|
||||
fun invoke(): String
|
||||
}
|
||||
|
||||
fun interface G<T> {
|
||||
fun foo(t: T): T
|
||||
}
|
||||
|
||||
fun interface C: G<Char>
|
||||
|
||||
fun interface C2 {
|
||||
fun bar(c: Char): Char
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val g = G<Int> { it * 10 }
|
||||
if (g.foo(2) != 20) return "fail1"
|
||||
|
||||
val g2 = G { a: Char -> a + 1 }
|
||||
if (g2.foo('a') != 'b') return "fail2"
|
||||
|
||||
val c = C { it + 2 }
|
||||
if (c.foo('A') != 'C') return "fail3"
|
||||
|
||||
val c2 = C2 { it + 3 }
|
||||
if (c2.bar('0') != '3') return "fail4"
|
||||
|
||||
return S { "OK" }.invoke()
|
||||
}
|
||||
+5
@@ -12244,6 +12244,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samConstructorExplicitInvocation.kt")
|
||||
public void testSamConstructorExplicitInvocation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
|
||||
+5
@@ -12244,6 +12244,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samConstructorExplicitInvocation.kt")
|
||||
public void testSamConstructorExplicitInvocation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
|
||||
+5
@@ -11029,6 +11029,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samConstructorExplicitInvocation.kt")
|
||||
public void testSamConstructorExplicitInvocation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
|
||||
Generated
+5
@@ -9444,6 +9444,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samConstructorExplicitInvocation.kt")
|
||||
public void testSamConstructorExplicitInvocation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
|
||||
+5
@@ -9444,6 +9444,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samConstructorExplicitInvocation.kt")
|
||||
public void testSamConstructorExplicitInvocation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
|
||||
+7
-1
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.util.*
|
||||
|
||||
@@ -184,7 +185,7 @@ object InvokeIntrinsic : FunctionCallCase() {
|
||||
|
||||
object ConstructorCallCase : FunctionCallCase() {
|
||||
fun canApply(callInfo: FunctionCallInfo): Boolean {
|
||||
return callInfo.callableDescriptor is ConstructorDescriptor
|
||||
return callInfo.callableDescriptor is ConstructorDescriptor || callInfo.callableDescriptor is SamConstructorDescriptor
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.noReceivers() = doTranslate { translateArguments }
|
||||
@@ -197,6 +198,11 @@ object ConstructorCallCase : FunctionCallCase() {
|
||||
getArguments: CallArgumentTranslator.ArgumentsInfo.() -> List<JsExpression>
|
||||
): JsExpression {
|
||||
val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
|
||||
|
||||
if (callableDescriptor is SamConstructorDescriptor) {
|
||||
return JsNew(functionRef, argumentsInfo.getArguments())
|
||||
}
|
||||
|
||||
val invocationArguments = mutableListOf<JsExpression>()
|
||||
|
||||
val constructorDescriptor = callableDescriptor as ClassConstructorDescriptor
|
||||
|
||||
+1
-1
@@ -592,7 +592,7 @@ class ClassTranslator private constructor(
|
||||
listOfNotNull(innerContext.continuationParameterDescriptor)
|
||||
|
||||
val arguments = parameters.map {
|
||||
TranslationUtils.coerce(innerContext, innerContext.getAliasForDescriptor(it)!!, context.currentModule.builtIns.anyType)
|
||||
TranslationUtils.coerce(innerContext, ReferenceTranslator.translateAsValueReference(it, innerContext), context.currentModule.builtIns.anyType)
|
||||
}
|
||||
|
||||
function.body = JsBlock(JsReturn(JsInvocation(pureFqn(Namer.SAM_FIELD_NAME, JsThisRef()), arguments)))
|
||||
|
||||
Reference in New Issue
Block a user