Fix inlining of invoke operator [#KT-25474]

* add test
This commit is contained in:
Roman Artemev
2018-07-16 17:54:29 +03:00
committed by Roman Artemev
parent a457a9f870
commit e4b314c26c
4 changed files with 48 additions and 9 deletions
@@ -3930,6 +3930,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
runTest("js/js.translator/testData/box/inline/innerOuterThis.kt");
}
@TestMetadata("invokeOnField.kt")
public void testInvokeOnField() throws Exception {
runTest("js/js.translator/testData/box/inline/invokeOnField.kt");
}
@TestMetadata("iteratorOnInlineFunctionResult.kt")
public void testIteratorOnInlineFunctionResult() throws Exception {
runTest("js/js.translator/testData/box/inline/iteratorOnInlineFunctionResult.kt");
@@ -3930,6 +3930,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
runTest("js/js.translator/testData/box/inline/innerOuterThis.kt");
}
@TestMetadata("invokeOnField.kt")
public void testInvokeOnField() throws Exception {
runTest("js/js.translator/testData/box/inline/invokeOnField.kt");
}
@TestMetadata("iteratorOnInlineFunctionResult.kt")
public void testIteratorOnInlineFunctionResult() throws Exception {
runTest("js/js.translator/testData/box/inline/iteratorOnInlineFunctionResult.kt");
@@ -109,22 +109,22 @@ private fun translateCall(
if (resolvedCall is VariableAsFunctionResolvedCall) {
assert(explicitReceivers.extensionReceiver == null) { "VariableAsFunctionResolvedCall must have one receiver" }
val variableCall = resolvedCall.variableCall
val isFunctionType = variableCall.resultingDescriptor.type.isFunctionTypeOrSubtype
val inlineCall = if (isFunctionType) variableCall else resolvedCall
return if (variableCall.expectedReceivers()) {
val newExplicitReceivers = if (variableCall.expectedReceivers()) {
val newReceiver = CallTranslator.translateGet(context, variableCall, explicitReceivers.extensionOrDispatchReceiver)
translateFunctionCall(context, resolvedCall.functionCall, resolvedCall.variableCall, ExplicitReceivers(newReceiver))
ExplicitReceivers(newReceiver)
} else {
val dispatchReceiver = CallTranslator.translateGet(context, variableCall, null)
val isFunctionType = resolvedCall.variableCall.resultingDescriptor.type.isFunctionTypeOrSubtype
val inlineCall = if (isFunctionType) resolvedCall.variableCall else resolvedCall
if (explicitReceivers.extensionOrDispatchReceiver == null) {
translateFunctionCall(context, resolvedCall.functionCall, inlineCall, ExplicitReceivers(dispatchReceiver))
}
else {
translateFunctionCall(context, resolvedCall.functionCall, inlineCall,
ExplicitReceivers(dispatchReceiver, explicitReceivers.extensionOrDispatchReceiver))
ExplicitReceivers(dispatchReceiver)
} else {
ExplicitReceivers(dispatchReceiver, explicitReceivers.extensionOrDispatchReceiver)
}
}
return translateFunctionCall(context, resolvedCall.functionCall, inlineCall, newExplicitReceivers)
}
val call = resolvedCall.call
+29
View File
@@ -0,0 +1,29 @@
// EXPECTED_REACHABLE_NODES: 1189
// CHECK_CONTAINS_NO_CALLS: testDispatch
// CHECK_CONTAINS_NO_CALLS: testExtension
class Bar {
inline operator fun invoke(f: () -> String) { f() }
}
class Baz
inline operator fun Baz.invoke(f: () -> String) { f() }
class Foo {
val bar = Bar()
val baz = Baz()
}
fun testDispatch(foo: Foo): String {
foo.bar { return "O" }
return "FailDispatch;"
}
fun testExtension(foo: Foo): String {
foo.baz { return "K" }
return "FailExtension;"
}
fun box(): String {
val f = Foo()
return testDispatch(f) + testExtension(f)
}