blob: 20c1bae11c0cbcedeeac8b02990cc7fb23aa9dc5 [file]
// TARGET_BACKEND: WASM
// ^^ KT-83093
// ISSUE: KT-89484
// MODULE: main
// FILE: main.kt
@JsExport
fun appendWithDefault(value: String = "K"): String = "O" + value
@JsExport
fun nullableStringWithDefault(value: String? = "default"): String = value ?: "null"
@JsExport
fun intWithDefault(x: Int = 42): Int = x
@JsExport
fun byteWithDefault(x: Byte = 7): Byte = x
@JsExport
fun charWithDefault(x: Char = 'K'): Char = x
@JsExport
fun booleanWithDefault(x: Boolean = true): Boolean = x
@JsExport
fun longWithDefault(x: Long = 5_000_000_000L): Long = x
@JsExport
fun doubleWithDefault(x: Double = 1.5): Double = x
@JsExport
fun uintWithDefault(x: UInt = 4_000_000_000u): UInt = x
@JsExport
fun nullableIntWithDefault(a: Int, b: Int? = null): Int = b ?: a
@JsExport
fun dependentDefaults(a: Int, b: Int = a + 1, c: String = "$a:$b"): String = "$a,$b,$c"
@JsExport
fun jsAnyWithDefault(x: JsAny? = "default".toJsString()): String = x?.toString() ?: "null"
@JsExport
fun lambdaWithDefault(x: Int, f: (Int) -> Int = { it + 1 }): Int = f(x)
var defaultEvaluations = 0
fun newJsObject(): JsAny = js("({})")
fun nextObject(): JsAny {
defaultEvaluations++
return newJsObject()
}
// `c` must see the same `b` instance, and `b`'s default must be evaluated exactly once.
@JsExport
fun defaultReferencesDefault(b: JsAny = nextObject(), c: JsAny = b): Boolean = b === c
@JsExport
fun getDefaultEvaluations(): Int = defaultEvaluations
fun box(): String {
if (appendWithDefault() != "OK") return "Fail: appendWithDefault from Kotlin"
if (intWithDefault() != 42) return "Fail: intWithDefault from Kotlin"
if (dependentDefaults(1) != "1,2,1:2") return "Fail: dependentDefaults from Kotlin"
if (dependentDefaults(1, c = "c") != "1,2,c") return "Fail: dependentDefaults with named argument from Kotlin"
if (lambdaWithDefault(1) != 2) return "Fail: lambdaWithDefault from Kotlin"
return "OK"
}
// FILE: entry.mjs
import {
appendWithDefault,
nullableStringWithDefault,
intWithDefault,
byteWithDefault,
charWithDefault,
booleanWithDefault,
longWithDefault,
doubleWithDefault,
uintWithDefault,
nullableIntWithDefault,
dependentDefaults,
jsAnyWithDefault,
lambdaWithDefault,
defaultReferencesDefault,
getDefaultEvaluations,
} from "./index.mjs"
function check(actual, expected, message) {
if (actual !== expected) {
throw `Fail: ${message}: expected ${expected}, got ${actual}`;
}
}
check(appendWithDefault("L"), "OL", "appendWithDefault explicit");
check(appendWithDefault(), "OK", "appendWithDefault omitted");
check(appendWithDefault(undefined), "OK", "appendWithDefault undefined");
check(nullableStringWithDefault("x"), "x", "nullableStringWithDefault explicit");
check(nullableStringWithDefault(null), "null", "nullableStringWithDefault null");
check(nullableStringWithDefault(), "default", "nullableStringWithDefault omitted");
check(intWithDefault(1), 1, "intWithDefault explicit");
check(intWithDefault(0), 0, "intWithDefault zero");
check(intWithDefault(), 42, "intWithDefault omitted");
check(intWithDefault(undefined), 42, "intWithDefault undefined");
check(byteWithDefault(1), 1, "byteWithDefault explicit");
check(byteWithDefault(), 7, "byteWithDefault omitted");
check(charWithDefault(76), 76, "charWithDefault explicit");
check(charWithDefault(), 75, "charWithDefault omitted");
check(booleanWithDefault(false), false, "booleanWithDefault explicit");
check(booleanWithDefault(), true, "booleanWithDefault omitted");
check(longWithDefault(1n), 1n, "longWithDefault explicit");
check(longWithDefault(), 5000000000n, "longWithDefault omitted");
check(doubleWithDefault(2.5), 2.5, "doubleWithDefault explicit");
check(doubleWithDefault(), 1.5, "doubleWithDefault omitted");
check(uintWithDefault(1), 1, "uintWithDefault explicit");
check(uintWithDefault(), 4000000000, "uintWithDefault omitted");
check(nullableIntWithDefault(42, 1), 1, "nullableIntWithDefault explicit");
check(nullableIntWithDefault(42, null), 42, "nullableIntWithDefault null");
check(nullableIntWithDefault(42), 42, "nullableIntWithDefault omitted");
check(dependentDefaults(1, 5, "c"), "1,5,c", "dependentDefaults explicit");
check(dependentDefaults(1, 5), "1,5,1:5", "dependentDefaults last omitted");
check(dependentDefaults(1), "1,2,1:2", "dependentDefaults two omitted");
check(dependentDefaults(1, undefined, "c"), "1,2,c", "dependentDefaults middle undefined");
check(jsAnyWithDefault("x"), "x", "jsAnyWithDefault explicit");
check(jsAnyWithDefault(null), "null", "jsAnyWithDefault null");
check(jsAnyWithDefault(), "default", "jsAnyWithDefault omitted");
check(lambdaWithDefault(1, (x) => x * 10), 10, "lambdaWithDefault explicit");
check(lambdaWithDefault(1), 2, "lambdaWithDefault omitted");
const evaluationsBefore = getDefaultEvaluations();
check(defaultReferencesDefault(), true, "defaultReferencesDefault omitted");
check(getDefaultEvaluations() - evaluationsBefore, 1, "defaultReferencesDefault evaluates default once");