[JS IR] Introduce the GENERATE_INLINE_ANONYMOUS_FUNCTIONS feature flag
This commit is contained in:
@@ -100,6 +100,9 @@ public class JSConfigurationKeys {
|
||||
public static final CompilerConfigurationKey<Boolean> PROPERTY_LAZY_INITIALIZATION =
|
||||
CompilerConfigurationKey.create("perform lazy initialization for properties");
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> GENERATE_INLINE_ANONYMOUS_FUNCTIONS =
|
||||
CompilerConfigurationKey.create("translate lambdas into in-line anonymous functions");
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> WASM_ENABLE_ARRAY_RANGE_CHECKS =
|
||||
CompilerConfigurationKey.create("enable array range checks");
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ fun main(args: Array<String>) {
|
||||
generateTestGroupSuiteWithJUnit5(args) {
|
||||
testGroup("js/js.tests/tests-gen", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
|
||||
testClass<AbstractBoxJsTest> {
|
||||
model("box/", pattern = "^([^_](.+))\\.kt$")
|
||||
model("box/", pattern = "^([^_](.+))\\.kt$", excludeDirs = listOf("closure/inlineAnonymousFunctions"))
|
||||
}
|
||||
|
||||
testClass<AbstractSourceMapGenerationSmokeTest> {
|
||||
|
||||
@@ -65,6 +65,12 @@ abstract class AbstractJsIrTest(
|
||||
::JsIrRecompiledArtifactsIdentityHandler,
|
||||
)
|
||||
}
|
||||
|
||||
forTestsMatching("${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/box/closure/inlineAnonymousFunctions/*") {
|
||||
defaultDirectives {
|
||||
+JsEnvironmentConfigurationDirectives.GENERATE_INLINE_ANONYMOUS_FUNCTIONS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -22,7 +22,7 @@ import java.util.regex.Pattern;
|
||||
public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInBox() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true, "closure/inlineAnonymousFunctions");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@@ -347,7 +347,7 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
public class Closure {
|
||||
@Test
|
||||
public void testAllFilesPresentInClosure() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/closure"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/closure"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true, "inlineAnonymousFunctions");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -356,12 +356,6 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/closure/closureArrayListInstance.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("closureCodeSize.kt")
|
||||
public void testClosureCodeSize() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/closureCodeSize.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("closureFunctionAsArgument.kt")
|
||||
public void testClosureFunctionAsArgument() throws Exception {
|
||||
|
||||
+52
-6
@@ -356,12 +356,6 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/closure/closureArrayListInstance.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("closureCodeSize.kt")
|
||||
public void testClosureCodeSize() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/closureCodeSize.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("closureFunctionAsArgument.kt")
|
||||
public void testClosureFunctionAsArgument() throws Exception {
|
||||
@@ -631,6 +625,58 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
public void testWrappedVariableInExtensionFun() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/wrappedVariableInExtensionFun.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("js/js.translator/testData/box/closure/inlineAnonymousFunctions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class InlineAnonymousFunctions {
|
||||
@Test
|
||||
public void testAllFilesPresentInInlineAnonymousFunctions() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/closure/inlineAnonymousFunctions"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("closureCodeSize.kt")
|
||||
public void testClosureCodeSize() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/inlineAnonymousFunctions/closureCodeSize.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("closureInWithInsideWith.kt")
|
||||
public void testClosureInWithInsideWith() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/inlineAnonymousFunctions/closureInWithInsideWith.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineChain.kt")
|
||||
public void testInlineChain() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/inlineAnonymousFunctions/inlineChain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaChain.kt")
|
||||
public void testLambdaChain() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/inlineAnonymousFunctions/lambdaChain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaParameters.kt")
|
||||
public void testLambdaParameters() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/inlineAnonymousFunctions/lambdaParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localParameterInCallback.kt")
|
||||
public void testLocalParameterInCallback() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/inlineAnonymousFunctions/localParameterInCallback.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twiceRegeneratedAnonymousObject.kt")
|
||||
public void testTwiceRegeneratedAnonymousObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/closure/inlineAnonymousFunctions/twiceRegeneratedAnonymousObject.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// KT-4237 With in with
|
||||
|
||||
package foo
|
||||
|
||||
class A {
|
||||
val ok = "OK"
|
||||
}
|
||||
|
||||
class B
|
||||
|
||||
fun <T> with(o: T, body: T.() -> Unit) {
|
||||
o.body()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var o = ""
|
||||
|
||||
with(A()) {
|
||||
with(B()) {
|
||||
o = ok
|
||||
}
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
interface A {
|
||||
fun run()
|
||||
}
|
||||
|
||||
inline fun testNested(crossinline f: (String) -> Unit) {
|
||||
object : A {
|
||||
override fun run() {
|
||||
f("OK")
|
||||
}
|
||||
}.run()
|
||||
}
|
||||
|
||||
inline fun test(crossinline f: (String) -> Unit) {
|
||||
testNested { it -> { f(it) }()}
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
test { it -> result = it }
|
||||
return result
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
inline fun <T> inlineFun(arg: T, f: (T) -> Unit) {
|
||||
f(arg)
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val param = "start"
|
||||
var result = "fail"
|
||||
inlineFun("1") { c ->
|
||||
{
|
||||
inlineFun("2") { a ->
|
||||
{
|
||||
{
|
||||
result = param + c + a
|
||||
}()
|
||||
}()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return if (result == "start12") "OK" else "fail: $result"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
fun <T> bar(x: T, y: (T) -> Boolean): Boolean = y(x) && jsTypeOf(x.asDynamic()) != "number"
|
||||
|
||||
fun typeOf(x: dynamic) = js("typeof x")
|
||||
|
||||
fun box(): String {
|
||||
val f = { x: Char ->
|
||||
val a: Char = x
|
||||
val b: Any = x
|
||||
typeOf(a) == "number" && typeOf(b) == "object"
|
||||
}
|
||||
|
||||
if (!f('Q')) return "fail1"
|
||||
if (!bar('W', f)) return "fail2"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
package foo
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val oneTwo = Array(2) {
|
||||
it + 1
|
||||
}
|
||||
val a = ArrayList<() -> Int>()
|
||||
for (i in oneTwo) {
|
||||
for (l in 1..2) {
|
||||
val j = l
|
||||
a.add({
|
||||
var res = 0
|
||||
for (t in 0..2) {
|
||||
res += i * j
|
||||
}
|
||||
res
|
||||
})
|
||||
}
|
||||
}
|
||||
var sum = 0
|
||||
for (f in a) {
|
||||
sum += f()
|
||||
}
|
||||
|
||||
if (sum != 27) return "fail: $sum"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
// WITH_STDLIB
|
||||
// WITH_COROUTINES
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun foo(crossinline x: () -> Unit) = suspend {
|
||||
try { } finally {
|
||||
// This object is regenerated twice (normal return & "catch Throwable, execute finally, and rethrow")
|
||||
// It doesn't *need* to be, but this should work regardless.
|
||||
{ x() }()
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import test.*
|
||||
|
||||
var result = "fail"
|
||||
fun box(): String {
|
||||
suspend {
|
||||
foo { result = "OK" }()
|
||||
}.startCoroutine(EmptyContinuation)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user