JS: support unsigned primitive vararg's
This commit is contained in:
committed by
Ilya Gorbunov
parent
944c5b6044
commit
934e11aa60
+1
-1
@@ -60,7 +60,7 @@ abstract class FunctionsFromAnyGenerator(protected val declaration: KtClassOrObj
|
||||
generateEqualsMethod(function, properties)
|
||||
}
|
||||
|
||||
private val primaryConstructorProperties: List<PropertyDescriptor>
|
||||
protected val primaryConstructorProperties: List<PropertyDescriptor>
|
||||
get() = primaryConstructorParameters
|
||||
.filter { it.hasValOrVar() }
|
||||
.map { bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it)!! }
|
||||
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
// WITH_UNSIGNED
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun box(): String {
|
||||
var sum = 0u
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_UNSIGNED
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
|
||||
fun uint(vararg us: UInt): UIntArray = us
|
||||
|
||||
|
||||
+5
@@ -2495,6 +2495,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/expression/function/vararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("varargUInt.kt")
|
||||
public void testVarargUInt() throws Exception {
|
||||
runTest("js/js.translator/testData/box/expression/function/varargUInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("whenFunction.kt")
|
||||
public void testWhenFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/box/expression/function/whenFunction.kt");
|
||||
|
||||
+5
@@ -2495,6 +2495,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/expression/function/vararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("varargUInt.kt")
|
||||
public void testVarargUInt() throws Exception {
|
||||
runTest("js/js.translator/testData/box/expression/function/varargUInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("whenFunction.kt")
|
||||
public void testWhenFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/box/expression/function/whenFunction.kt");
|
||||
|
||||
+26
@@ -18,13 +18,18 @@ package org.jetbrains.kotlin.js.translate.declaration;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.UtilsKt;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -49,6 +54,15 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
|
||||
this.isInline = isInline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate() {
|
||||
if (isInline) {
|
||||
generateUnboxFunction();
|
||||
}
|
||||
|
||||
super.generate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull ValueParameterDescriptor parameter) {
|
||||
if (isInline) return;
|
||||
@@ -213,6 +227,18 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
|
||||
functionObj.getBody().getStatements().add(returnStatement);
|
||||
}
|
||||
|
||||
private void generateUnboxFunction() {
|
||||
PropertyDescriptor boxee = getPrimaryConstructorProperties().get(0);
|
||||
|
||||
JsFunction unboxFunction = context.createRootScopedFunction("unbox");
|
||||
JsExpression prototypeRef = JsAstUtils.prototypeOf(context.getInnerReference(getClassDescriptor()));
|
||||
JsExpression functionRef = new JsNameRef("unbox", prototypeRef);
|
||||
|
||||
unboxFunction.getBody().getStatements().add(new JsReturn(JsAstUtils.pureFqn(context.getNameForDescriptor(boxee), new JsThisRef())));
|
||||
|
||||
context.addDeclarationStatement(JsAstUtils.assignment(functionRef, unboxFunction).makeStmt());
|
||||
}
|
||||
|
||||
private JsFunction generateJsMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
JsFunction functionObject = context.createRootScopedFunction(functionDescriptor);
|
||||
functionObject.setSource(getDeclaration());
|
||||
|
||||
+31
-5
@@ -40,6 +40,8 @@ import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntri
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineStrategy
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
object ArrayFIF : CompositeFIF() {
|
||||
@@ -64,14 +66,38 @@ object ArrayFIF : CompositeFIF() {
|
||||
@JvmStatic
|
||||
fun typedArraysEnabled(config: JsConfig) = config.configuration.get(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, true)
|
||||
|
||||
fun castOrCreatePrimitiveArray(ctx: TranslationContext, type: PrimitiveType?, arg: JsArrayLiteral): JsExpression {
|
||||
if (type == null || !typedArraysEnabled(ctx.config)) return arg
|
||||
fun unsignedPrimitiveToSigned(type: KotlinType): PrimitiveType? {
|
||||
// short-circuit
|
||||
if (!type.isInlineClassType() || type.isMarkedNullable) return null
|
||||
|
||||
return if (type in TYPED_ARRAY_MAP) {
|
||||
createTypedArray(type, arg)
|
||||
return when {
|
||||
KotlinBuiltIns.isUByte(type) -> BYTE
|
||||
KotlinBuiltIns.isUShort(type) -> SHORT
|
||||
KotlinBuiltIns.isUInt(type) -> INT
|
||||
KotlinBuiltIns.isULong(type) -> LONG
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun castOrCreatePrimitiveArray(ctx: TranslationContext, type: KotlinType, arg: JsArrayLiteral): JsExpression {
|
||||
if (type.isMarkedNullable) return arg
|
||||
|
||||
val unsignedPrimitiveType = unsignedPrimitiveToSigned(type)
|
||||
|
||||
if (unsignedPrimitiveType != null) {
|
||||
val conversionFunction = "to${unsignedPrimitiveType.typeName}"
|
||||
arg.expressions.replaceAll { JsInvocation(JsNameRef(conversionFunction, it)) }
|
||||
}
|
||||
|
||||
val primitiveType = unsignedPrimitiveType ?: KotlinBuiltIns.getPrimitiveType(type)?.takeUnless { type.isMarkedNullable}
|
||||
|
||||
if (primitiveType == null || !typedArraysEnabled(ctx.config)) return arg
|
||||
|
||||
return if (primitiveType in TYPED_ARRAY_MAP) {
|
||||
createTypedArray(primitiveType, arg)
|
||||
}
|
||||
else {
|
||||
JsAstUtils.invokeKotlinFunction(type.lowerCaseName + "ArrayOf", *arg.expressions.toTypedArray())
|
||||
JsAstUtils.invokeKotlinFunction(primitiveType.lowerCaseName + "ArrayOf", *arg.expressions.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+73
-48
@@ -5,12 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.reference
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||
@@ -25,6 +26,8 @@ import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.getReferenceToJsClass
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||
@@ -33,6 +36,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType
|
||||
import java.util.*
|
||||
|
||||
class CallArgumentTranslator private constructor(
|
||||
@@ -77,7 +81,7 @@ class CallArgumentTranslator private constructor(
|
||||
var argsBeforeVararg: List<JsExpression>? = null
|
||||
var concatArguments: MutableList<JsExpression>? = null
|
||||
val argsToJsExpr = translateUnresolvedArguments(context(), resolvedCall)
|
||||
var varargPrimitiveType: PrimitiveType? = null
|
||||
var varargElementType: KotlinType? = null
|
||||
|
||||
for (parameterDescriptor in valueParameters) {
|
||||
val actualArgument = valueArgumentsByIndex[parameterDescriptor.index]
|
||||
@@ -90,8 +94,7 @@ class CallArgumentTranslator private constructor(
|
||||
hasSpreadOperator = arguments.any { it.getSpreadElement() != null }
|
||||
}
|
||||
|
||||
val varargElementType = parameterDescriptor.original.varargElementType!!
|
||||
varargPrimitiveType = KotlinBuiltIns.getPrimitiveType(varargElementType).takeUnless { varargElementType.isMarkedNullable }
|
||||
varargElementType = parameterDescriptor.original.varargElementType!!
|
||||
|
||||
if (hasSpreadOperator) {
|
||||
if (isNativeFunctionCall) {
|
||||
@@ -102,10 +105,10 @@ class CallArgumentTranslator private constructor(
|
||||
null)
|
||||
}
|
||||
else {
|
||||
result.addAll(translateVarargArgument(actualArgument,
|
||||
argsToJsExpr,
|
||||
actualArgument.arguments.size > 1,
|
||||
varargPrimitiveType))
|
||||
translateVarargArgument(actualArgument,
|
||||
argsToJsExpr,
|
||||
actualArgument.arguments.size > 1,
|
||||
varargElementType)?.let { result.add(it) }
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -113,7 +116,7 @@ class CallArgumentTranslator private constructor(
|
||||
result.addAll(translateResolvedArgument(actualArgument, argsToJsExpr))
|
||||
}
|
||||
else {
|
||||
result.addAll(translateVarargArgument(actualArgument, argsToJsExpr, true, varargPrimitiveType))
|
||||
translateVarargArgument(actualArgument, argsToJsExpr, true, varargElementType)?.let { result.add(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +137,7 @@ class CallArgumentTranslator private constructor(
|
||||
concatArguments!!.add(0, toArray(null, argsBeforeVararg))
|
||||
}
|
||||
|
||||
result = mutableListOf(concatArgumentsIfNeeded(concatArguments!!, varargPrimitiveType, true))
|
||||
result = mutableListOf(concatArgumentsIfNeeded(concatArguments!!, varargElementType, true))
|
||||
|
||||
if (receiver != null) {
|
||||
cachedReceiver = context().getOrDeclareTemporaryConstVariable(receiver)
|
||||
@@ -207,44 +210,64 @@ class CallArgumentTranslator private constructor(
|
||||
return result
|
||||
}
|
||||
|
||||
// Cache UTypeArray descriptor lookup
|
||||
private val typeToUTypeArray = mutableMapOf<PrimitiveType, ClassDescriptor>()
|
||||
|
||||
private fun JsExpression.wrapInUArray(elementType: KotlinType): JsExpression {
|
||||
return ArrayFIF.unsignedPrimitiveToSigned(elementType)?.let { primitiveType ->
|
||||
val kotlinMemberScope = context.currentModule.getPackage(FqNameUnsafe("kotlin").toSafe()).memberScope
|
||||
val classDescriptor = typeToUTypeArray.computeIfAbsent(primitiveType) {
|
||||
val className = Name.identifier("U${primitiveType.typeName}Array")
|
||||
kotlinMemberScope.getContributedClassifier(className, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
}
|
||||
JsNew(ReferenceTranslator.translateAsTypeReference(classDescriptor, context), listOf(this))
|
||||
} ?: this
|
||||
}
|
||||
|
||||
private fun translateVarargArgument(
|
||||
resolvedArgument: ResolvedValueArgument,
|
||||
translatedArgs: Map<ValueArgument, JsExpression>,
|
||||
shouldWrapVarargInArray: Boolean,
|
||||
varargPrimitiveType: PrimitiveType?
|
||||
): List<JsExpression> {
|
||||
resolvedArgument: ResolvedValueArgument,
|
||||
translatedArgs: Map<ValueArgument, JsExpression>,
|
||||
shouldWrapVarargInArray: Boolean,
|
||||
varargElementType: KotlinType
|
||||
): JsExpression? {
|
||||
val arguments = resolvedArgument.arguments
|
||||
if (arguments.isEmpty()) {
|
||||
return if (shouldWrapVarargInArray) {
|
||||
return listOf(toArray(varargPrimitiveType, listOf()))
|
||||
}
|
||||
else {
|
||||
listOf()
|
||||
return toArray(varargElementType, listOf()).wrapInUArray(varargElementType)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
val list = translateResolvedArgument(resolvedArgument, translatedArgs)
|
||||
|
||||
return if (shouldWrapVarargInArray) {
|
||||
val concatArguments = prepareConcatArguments(arguments, list, varargPrimitiveType)
|
||||
val concatExpression = concatArgumentsIfNeeded(concatArguments, varargPrimitiveType, false)
|
||||
listOf(concatExpression)
|
||||
}
|
||||
else {
|
||||
listOf(JsAstUtils.invokeMethod(list[0], "slice"))
|
||||
}
|
||||
val concatArguments = prepareConcatArguments(arguments, list, varargElementType)
|
||||
val concatExpression = concatArgumentsIfNeeded(concatArguments, varargElementType, false)
|
||||
concatExpression
|
||||
} else {
|
||||
val arg = ArrayFIF.unsignedPrimitiveToSigned(varargElementType)?.let {type ->
|
||||
JsInvocation(JsNameRef("unbox", list[0]))
|
||||
} ?: list[0]
|
||||
JsAstUtils.invokeMethod(arg, "slice")
|
||||
}.wrapInUArray(varargElementType)
|
||||
}
|
||||
|
||||
private fun toArray(varargPrimitiveType: PrimitiveType?, elements: List<JsExpression>): JsExpression {
|
||||
return ArrayFIF.castOrCreatePrimitiveArray(context(),
|
||||
varargPrimitiveType,
|
||||
JsArrayLiteral(elements).apply { sideEffects = SideEffectKind.PURE })
|
||||
private fun toArray(varargElementType: KotlinType?, elements: List<JsExpression>): JsExpression {
|
||||
val argument = JsArrayLiteral(elements).apply { sideEffects = SideEffectKind.PURE }
|
||||
|
||||
if (varargElementType == null) return argument
|
||||
|
||||
return ArrayFIF.castOrCreatePrimitiveArray(
|
||||
context(),
|
||||
varargElementType,
|
||||
argument)
|
||||
}
|
||||
|
||||
private fun prepareConcatArguments(
|
||||
arguments: List<ValueArgument>,
|
||||
list: List<JsExpression>,
|
||||
varargPrimitiveType: PrimitiveType?
|
||||
arguments: List<ValueArgument>,
|
||||
list: List<JsExpression>,
|
||||
varargElementType: KotlinType?
|
||||
): MutableList<JsExpression> {
|
||||
assert(arguments.isNotEmpty()) { "arguments.size should not be 0" }
|
||||
assert(arguments.size == list.size) { "arguments.size: " + arguments.size + " != list.size: " + list.size }
|
||||
@@ -259,17 +282,19 @@ class CallArgumentTranslator private constructor(
|
||||
|
||||
if (valueArgument.getSpreadElement() != null) {
|
||||
if (lastArrayContent.size > 0) {
|
||||
concatArguments.add(toArray(varargPrimitiveType, lastArrayContent))
|
||||
concatArguments.add(toArray(varargElementType, lastArrayContent))
|
||||
lastArrayContent = mutableListOf()
|
||||
}
|
||||
concatArguments.add(expressionArgument)
|
||||
}
|
||||
else {
|
||||
val e = if (varargElementType != null && ArrayFIF.unsignedPrimitiveToSigned(varargElementType) != null) {
|
||||
JsInvocation(JsNameRef("unbox", expressionArgument))
|
||||
} else expressionArgument
|
||||
concatArguments.add(e)
|
||||
} else {
|
||||
lastArrayContent.add(expressionArgument)
|
||||
}
|
||||
}
|
||||
if (lastArrayContent.size > 0) {
|
||||
concatArguments.add(toArray(varargPrimitiveType, lastArrayContent))
|
||||
concatArguments.add(toArray(varargElementType, lastArrayContent))
|
||||
}
|
||||
|
||||
return concatArguments
|
||||
@@ -306,23 +331,23 @@ class CallArgumentTranslator private constructor(
|
||||
}
|
||||
|
||||
private fun concatArgumentsIfNeeded(
|
||||
concatArguments: List<JsExpression>,
|
||||
varargPrimitiveType: PrimitiveType?,
|
||||
isMixed: Boolean
|
||||
concatArguments: List<JsExpression>,
|
||||
varargElementType: KotlinType?,
|
||||
isMixed: Boolean
|
||||
): JsExpression {
|
||||
assert(concatArguments.isNotEmpty()) { "concatArguments.size should not be 0" }
|
||||
|
||||
return if (concatArguments.size > 1) {
|
||||
if (varargPrimitiveType != null) {
|
||||
if (varargElementType != null && (varargElementType.isPrimitiveNumberType() || ArrayFIF.unsignedPrimitiveToSigned(varargElementType) != null)) {
|
||||
val method = if (isMixed) "arrayConcat" else "primitiveArrayConcat"
|
||||
JsAstUtils.invokeKotlinFunction(method, concatArguments[0],
|
||||
*concatArguments.subList(1, concatArguments.size).toTypedArray())
|
||||
}
|
||||
else {
|
||||
JsAstUtils.invokeKotlinFunction(
|
||||
method, concatArguments[0],
|
||||
*concatArguments.subList(1, concatArguments.size).toTypedArray()
|
||||
)
|
||||
} else {
|
||||
JsInvocation(JsNameRef("concat", concatArguments[0]), concatArguments.subList(1, concatArguments.size))
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
concatArguments[0]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// LANGUAGE_VERSION: 1.3
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1566
|
||||
package foo
|
||||
|
||||
fun testSize(expectedSize: Int, vararg i: UInt): Boolean {
|
||||
return (i.size == expectedSize)
|
||||
}
|
||||
|
||||
fun testSum(expectedSum: UInt, vararg i: UInt): Boolean {
|
||||
var sum = 0u
|
||||
for (j in i) {
|
||||
sum += j
|
||||
}
|
||||
|
||||
return (expectedSum == sum)
|
||||
}
|
||||
|
||||
fun testSpreadOperator(vararg args: UInt): Boolean {
|
||||
var sum = 0u
|
||||
for (a in args) sum += a
|
||||
|
||||
return testSize(args.size, *args) && testSum(sum, *args)
|
||||
}
|
||||
|
||||
class Bar(val size: Int, val sum: UInt) {
|
||||
fun test(vararg args: UInt) = testSize(size, *args) && testSum(sum, *args)
|
||||
}
|
||||
|
||||
object obj {
|
||||
fun test(size: Int, sum: UInt, vararg args: UInt) = testSize(size, *args) && testSum(sum, *args)
|
||||
}
|
||||
|
||||
fun spreadInMethodCall(size: Int, sum: UInt, vararg args: UInt) = Bar(size, sum).test(*args)
|
||||
|
||||
fun spreadInObjectMethodCall(size: Int, sum: UInt, vararg args: UInt) = obj.test(size, sum, *args)
|
||||
|
||||
fun testVarargWithFunLit(vararg args: UInt, f: (a: UIntArray) -> Boolean): Boolean = f(args)
|
||||
|
||||
fun <T> idVarArgs(vararg a: T) = a
|
||||
|
||||
fun <T> idArrayVarArg(vararg a: Array<T>) = a
|
||||
|
||||
fun sumFunValuesOnParameters(x: UInt, y: UInt, vararg a: UInt, f: (UInt) -> UInt): UInt {
|
||||
var result = f(x) + f(y)
|
||||
for(u in a) {
|
||||
result += f(u)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (!testSize(0))
|
||||
return "wrong vararg size when call function without args"
|
||||
|
||||
if (!testSum(0u))
|
||||
return "wrong vararg sum (arguments) when call function without args"
|
||||
|
||||
if (!testSize(6, 1u, 1u, 1u, 2u, 3u, 4u))
|
||||
return "wrong vararg size when call function with some args (1)"
|
||||
|
||||
if (!testSum(30, 10u, 20u, 0u))
|
||||
return "wrong vararg sum (arguments) when call function with some args (1)"
|
||||
|
||||
if (!testSpreadOperator(30u, 10u, 20u, 0u))
|
||||
return "failed when call function using spread operator"
|
||||
|
||||
if (!Bar(3, 30u).test(10u, 20u, 0u))
|
||||
return "failed when call method"
|
||||
|
||||
if (!spreadInMethodCall(2, 3u, 1u, 2u))
|
||||
return "failed when call method using spread operator"
|
||||
|
||||
if (!obj.test(5, 15u, 1u, 2u, 3u, 4u, 5u))
|
||||
return "failed when call method of object"
|
||||
|
||||
if (!spreadInObjectMethodCall(2, 3u, 1u, 2u))
|
||||
return "failed when call method of object using spread operator"
|
||||
|
||||
if (!testVarargWithFunLit(1u, 2u, 3u) { args -> args.size == 3 })
|
||||
return "failed when call function with vararg and fun literal"
|
||||
|
||||
val a = arrayOf(1u, 2u, 3u)
|
||||
val b = arrayOf(4u, 5u)
|
||||
|
||||
assertEquals(5, arrayOf(*a, *b).size)
|
||||
assertEquals(8, arrayOf(10u, *a, 20u, *b, 30u).size)
|
||||
|
||||
assertEquals(5, idVarArgs(*a, *b).size)
|
||||
assertEquals(8, idVarArgs(10u, *a, 20u, *b, 30u).size)
|
||||
|
||||
assertEquals(9, arrayOf(1u, *a, *a, 1u, 2u).size)
|
||||
assertEquals(9, idVarArgs(1u, *a, *a, 1u, 2u).size)
|
||||
|
||||
assertEquals(9, arrayOf(1u, *a, *arrayOf(1u, 2u, 3u), 1u, 2u).size)
|
||||
assertEquals(9, idVarArgs(1u, *a, *arrayOf(1u, 2u, 3u), 1u, 2u).size)
|
||||
|
||||
assertEquals(90u, sumFunValuesOnParameters(1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u) { 2u*it })
|
||||
assertEquals(90u, sumFunValuesOnParameters(1u, 2u, *uintArrayOf(3u, 4u, 5u, 6u, 7u, 8u, 9u)) { 2u*it })
|
||||
assertEquals(90u, sumFunValuesOnParameters(1u, 2u, 3u, 4u, *uintArrayOf(5u, 6u, 7u, 8u, 9u)) { 2u*it })
|
||||
assertEquals(90u, sumFunValuesOnParameters(1u, 2u, *uintArrayOf(3u, 4u, 5u, 6u, 7u), 8u, 9u) { 2u*it })
|
||||
assertEquals(90u, sumFunValuesOnParameters(1u, 2u, *uintArrayOf(3u, 4u, 5u), *uintArrayOf(6u, 7u, 8u, 9u)) { 2u*it })
|
||||
assertEquals(90u, sumFunValuesOnParameters(1u, 2u, *uintArrayOf(3u, 4u), 5u, 6u, *uintArrayOf(7u, 8u, 9u)) { 2u*it })
|
||||
|
||||
assertEquals(2, idArrayVarArg(arrayOf(1u), *arrayOf(arrayOf(2u, 3u, 4u))).size)
|
||||
assertEquals(3, idArrayVarArg(arrayOf(1u, 2u), *arrayOf(arrayOf(3u, 4u), arrayOf(5u, 6u))).size)
|
||||
assertEquals(6, idArrayVarArg(arrayOf(1u, 2u), *arrayOf(arrayOf(3u, 4u), arrayOf(5u, 6u)), arrayOf(7u), *arrayOf(arrayOf(8u, 9u), arrayOf(10u, 11u))).size)
|
||||
|
||||
val c = arrayOf(*a)
|
||||
assertFalse(a === c, "Spread operator should copy its argument")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user