JS: support reified usage in extension functions
This commit is contained in:
@@ -41,6 +41,12 @@ public class ReifiedTestGenerated extends AbstractReifiedTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extensionFun.kt")
|
||||
public void testExtensionFun() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/extensionFun.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extensionLambda.kt")
|
||||
public void testExtensionLambda() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/extensionLambda.kt");
|
||||
|
||||
+10
-13
@@ -36,17 +36,14 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import java.util.ArrayList
|
||||
|
||||
public fun addReceiverToArgs(receiver: JsExpression, arguments: List<JsExpression>): List<JsExpression> {
|
||||
if (arguments.isEmpty())
|
||||
return SmartList(receiver)
|
||||
|
||||
val argumentList = ArrayList<JsExpression>(1 + arguments.size())
|
||||
argumentList.add(receiver)
|
||||
argumentList.addAll(arguments)
|
||||
return argumentList
|
||||
public fun CallArgumentTranslator.ArgumentsInfo.argsWithReceiver(receiver: JsExpression): List<JsExpression> {
|
||||
val allArguments = ArrayList<JsExpression>(1 + reifiedArguments.size() + valueArguments.size())
|
||||
allArguments.addAll(reifiedArguments)
|
||||
allArguments.add(receiver)
|
||||
allArguments.addAll(valueArguments)
|
||||
return allArguments
|
||||
}
|
||||
|
||||
|
||||
// call may be native and|or with spreadOperator
|
||||
object DefaultFunctionCallCase : FunctionCallCase {
|
||||
// TODO: refactor after fix ArgumentsInfo - duplicate code
|
||||
@@ -118,13 +115,13 @@ object DefaultFunctionCallCase : FunctionCallCase {
|
||||
functionRef
|
||||
}
|
||||
|
||||
return JsInvocation(referenceToCall, addReceiverToArgs(extensionReceiver!!, argumentsInfo.translateArguments))
|
||||
return JsInvocation(referenceToCall, argumentsInfo.argsWithReceiver(extensionReceiver!!))
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.bothReceivers(): JsExpression {
|
||||
// TODO: think about crazy case: spreadOperator + native
|
||||
val functionRef = JsNameRef(functionName, dispatchReceiver!!)
|
||||
return JsInvocation(functionRef, addReceiverToArgs(extensionReceiver!!, argumentsInfo.translateArguments))
|
||||
return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(extensionReceiver!!))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +197,7 @@ object InvokeIntrinsic : FunctionCallCase {
|
||||
* extLambda.call(obj, some, args)
|
||||
*/
|
||||
override fun FunctionCallInfo.bothReceivers(): JsExpression {
|
||||
return JsInvocation(Namer.getFunctionCallRef(dispatchReceiver!!), addReceiverToArgs(extensionReceiver!!, argumentsInfo.translateArguments))
|
||||
return JsInvocation(Namer.getFunctionCallRef(dispatchReceiver!!), argumentsInfo.argsWithReceiver(extensionReceiver!!))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +224,7 @@ object SuperCallCase : FunctionCallCase {
|
||||
// TODO: spread operator
|
||||
val prototypeClass = JsNameRef(Namer.getPrototypeName(), dispatchReceiver!!)
|
||||
val functionRef = Namer.getFunctionCallRef(JsNameRef(functionName, prototypeClass))
|
||||
return JsInvocation(functionRef, addReceiverToArgs(JsLiteral.THIS, argumentsInfo.translateArguments))
|
||||
return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(JsLiteral.THIS))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -45,10 +45,14 @@ public class CallArgumentTranslator private (
|
||||
) : AbstractTranslator(context) {
|
||||
|
||||
public data class ArgumentsInfo(
|
||||
public val translateArguments: List<JsExpression>,
|
||||
public val valueArguments: List<JsExpression>,
|
||||
public val hasSpreadOperator: Boolean,
|
||||
public val cachedReceiver: TemporaryConstVariable?
|
||||
)
|
||||
public val cachedReceiver: TemporaryConstVariable?,
|
||||
public val reifiedArguments: List<JsExpression> = listOf()
|
||||
) {
|
||||
public val translateArguments: List<JsExpression>
|
||||
get() = reifiedArguments + valueArguments
|
||||
}
|
||||
|
||||
private enum class ArgumentsKind {
|
||||
HAS_EMPTY_EXPRESSION_ARGUMENT
|
||||
@@ -349,5 +353,5 @@ private fun Map<TypeParameterDescriptor, JetType>.addReifiedTypeArgsTo(
|
||||
reifiedTypeArguments.add(isCheckCallable)
|
||||
}
|
||||
|
||||
return info.copy(translateArguments = reifiedTypeArguments + info.translateArguments)
|
||||
return info.copy(reifiedArguments = reifiedTypeArguments)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: canBeCastedTo
|
||||
|
||||
open class A
|
||||
class B
|
||||
class C : A()
|
||||
|
||||
inline fun Any.canBeCastedTo<reified T>(): Boolean = this is T
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(true, A().canBeCastedTo<A>(), "A().canBeCastedTo<A>()")
|
||||
assertEquals(false, A().canBeCastedTo<B>(), "A().canBeCastedTo<B>()")
|
||||
assertEquals(true, C().canBeCastedTo<A>(), "C().canBeCastedTo<A>()")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user