JS: support cross-module inlining of suspend functions
See KT-18063
This commit is contained in:
+42
-4
@@ -211,6 +211,22 @@ public final class DebugJsAstProtoBuf {
|
||||
* <code>UNBOX_CHAR = 4;</code>
|
||||
*/
|
||||
UNBOX_CHAR(3, 4),
|
||||
/**
|
||||
* <code>SUSPEND_CALL = 5;</code>
|
||||
*/
|
||||
SUSPEND_CALL(4, 5),
|
||||
/**
|
||||
* <code>COROUTINE_RESULT = 6;</code>
|
||||
*/
|
||||
COROUTINE_RESULT(5, 6),
|
||||
/**
|
||||
* <code>COROUTINE_CONTROLLER = 7;</code>
|
||||
*/
|
||||
COROUTINE_CONTROLLER(6, 7),
|
||||
/**
|
||||
* <code>COROUTINE_RECEIVER = 8;</code>
|
||||
*/
|
||||
COROUTINE_RECEIVER(7, 8),
|
||||
;
|
||||
|
||||
/**
|
||||
@@ -229,6 +245,22 @@ public final class DebugJsAstProtoBuf {
|
||||
* <code>UNBOX_CHAR = 4;</code>
|
||||
*/
|
||||
public static final int UNBOX_CHAR_VALUE = 4;
|
||||
/**
|
||||
* <code>SUSPEND_CALL = 5;</code>
|
||||
*/
|
||||
public static final int SUSPEND_CALL_VALUE = 5;
|
||||
/**
|
||||
* <code>COROUTINE_RESULT = 6;</code>
|
||||
*/
|
||||
public static final int COROUTINE_RESULT_VALUE = 6;
|
||||
/**
|
||||
* <code>COROUTINE_CONTROLLER = 7;</code>
|
||||
*/
|
||||
public static final int COROUTINE_CONTROLLER_VALUE = 7;
|
||||
/**
|
||||
* <code>COROUTINE_RECEIVER = 8;</code>
|
||||
*/
|
||||
public static final int COROUTINE_RECEIVER_VALUE = 8;
|
||||
|
||||
|
||||
public final int getNumber() { return value; }
|
||||
@@ -239,6 +271,10 @@ public final class DebugJsAstProtoBuf {
|
||||
case 2: return WRAP_FUNCTION;
|
||||
case 3: return TO_BOXED_CHAR;
|
||||
case 4: return UNBOX_CHAR;
|
||||
case 5: return SUSPEND_CALL;
|
||||
case 6: return COROUTINE_RESULT;
|
||||
case 7: return COROUTINE_CONTROLLER;
|
||||
case 8: return COROUTINE_RECEIVER;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
@@ -49361,10 +49397,12 @@ public final class DebugJsAstProtoBuf {
|
||||
"t.Fragment*@\n\013SideEffects\022\021\n\rAFFECTS_STA" +
|
||||
"TE\020\001\022\024\n\020DEPENDS_ON_STATE\020\002\022\010\n\004PURE\020\003*?\n\016" +
|
||||
"InlineStrategy\022\017\n\013AS_FUNCTION\020\000\022\014\n\010IN_PL" +
|
||||
"ACE\020\001\022\016\n\nNOT_INLINE\020\002*c\n\017SpecialFunction" +
|
||||
"\022\032\n\026DEFINE_INLINE_FUNCTION\020\001\022\021\n\rWRAP_FUN" +
|
||||
"CTION\020\002\022\021\n\rTO_BOXED_CHAR\020\003\022\016\n\nUNBOX_CHAR" +
|
||||
"\020\004B\024B\022DebugJsAstProtoBuf"
|
||||
"ACE\020\001\022\016\n\nNOT_INLINE\020\002*\275\001\n\017SpecialFunctio" +
|
||||
"n\022\032\n\026DEFINE_INLINE_FUNCTION\020\001\022\021\n\rWRAP_FU" +
|
||||
"NCTION\020\002\022\021\n\rTO_BOXED_CHAR\020\003\022\016\n\nUNBOX_CHA" +
|
||||
"R\020\004\022\020\n\014SUSPEND_CALL\020\005\022\024\n\020COROUTINE_RESUL" +
|
||||
"T\020\006\022\030\n\024COROUTINE_CONTROLLER\020\007\022\026\n\022COROUTI" +
|
||||
"NE_RECEIVER\020\010B\024B\022DebugJsAstProtoBuf"
|
||||
};
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
|
||||
// MODULE: lib(support)
|
||||
// FILE: lib.kt
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
var continuation: () -> Unit = { }
|
||||
var log = ""
|
||||
var finished = false
|
||||
|
||||
suspend fun <T> foo(v: T): T = suspendCoroutineOrReturn { x ->
|
||||
continuation = {
|
||||
x.resume(v)
|
||||
}
|
||||
log += "foo($v);"
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
inline suspend fun bar(v: String) {
|
||||
log += "before bar($v);"
|
||||
foo("1:$v")
|
||||
log += "inside bar($v);"
|
||||
foo("2:$v")
|
||||
log += "after bar($v);"
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(handleResultContinuation {
|
||||
continuation = { }
|
||||
finished = true
|
||||
})
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
suspend fun baz() {
|
||||
bar("A")
|
||||
log += "between bar;"
|
||||
bar("B")
|
||||
}
|
||||
|
||||
val expectedString =
|
||||
"before bar(A);foo(1:A);@;inside bar(A);foo(2:A);@;after bar(A);" +
|
||||
"between bar;" +
|
||||
"before bar(B);foo(1:B);@;inside bar(B);foo(2:B);@;after bar(B);"
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
baz()
|
||||
}
|
||||
|
||||
while (!finished) {
|
||||
log += "@;"
|
||||
continuation()
|
||||
}
|
||||
|
||||
if (log != expectedString) return "fail: $log"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: JVM
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
|
||||
// MODULE: lib(support)
|
||||
// FILE: lib.kt
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
var continuation: () -> Unit = { }
|
||||
var log = ""
|
||||
var finished = false
|
||||
|
||||
suspend fun <T> foo(v: T): T = suspendCoroutineOrReturn { x ->
|
||||
continuation = {
|
||||
x.resume(v)
|
||||
}
|
||||
log += "foo($v);"
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
interface I {
|
||||
suspend fun bar()
|
||||
}
|
||||
|
||||
class A(val v: String) : I {
|
||||
override inline suspend fun bar() {
|
||||
log += "before bar($v);"
|
||||
foo("1:$v")
|
||||
log += "inside bar($v);"
|
||||
foo("2:$v")
|
||||
log += "after bar($v);"
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(handleResultContinuation {
|
||||
continuation = { }
|
||||
finished = true
|
||||
})
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
suspend fun baz() {
|
||||
val a = A("A")
|
||||
a.bar()
|
||||
|
||||
log += "between bar;"
|
||||
|
||||
val b: I = A("B")
|
||||
b.bar()
|
||||
}
|
||||
|
||||
val expectedString =
|
||||
"before bar(A);foo(1:A);@;inside bar(A);foo(2:A);@;after bar(A);" +
|
||||
"between bar;" +
|
||||
"before bar(B);foo(1:B);@;inside bar(B);foo(2:B);@;after bar(B);"
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
baz()
|
||||
}
|
||||
|
||||
while (!finished) {
|
||||
log += "@;"
|
||||
continuation()
|
||||
}
|
||||
|
||||
if (log != expectedString) return "fail: $log"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
|
||||
// MODULE: lib(support)
|
||||
// FILE: lib.kt
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
var continuation: () -> Unit = { }
|
||||
var log = ""
|
||||
var finished = false
|
||||
|
||||
class C {
|
||||
var v: String = ""
|
||||
|
||||
inline suspend fun bar() {
|
||||
log += "before bar($v);"
|
||||
foo("1:$v")
|
||||
log += "inside bar($v);"
|
||||
foo("2:$v")
|
||||
log += "after bar($v);"
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun <T> foo(v: T): T = suspendCoroutineOrReturn { x ->
|
||||
continuation = {
|
||||
x.resume(v)
|
||||
}
|
||||
log += "foo($v);"
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
fun C.builder(c: suspend C.() -> Unit) {
|
||||
c.startCoroutine(this, handleResultContinuation {
|
||||
continuation = { }
|
||||
finished = true
|
||||
})
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
suspend fun C.baz() {
|
||||
v = "A"
|
||||
bar()
|
||||
log += "between bar;"
|
||||
v = "B"
|
||||
bar()
|
||||
}
|
||||
|
||||
val expectedString =
|
||||
"before bar(A);foo(1:A);@;inside bar(A);foo(2:A);@;after bar(A);" +
|
||||
"between bar;" +
|
||||
"before bar(B);foo(1:B);@;inside bar(B);foo(2:B);@;after bar(B);"
|
||||
|
||||
fun box(): String {
|
||||
var c = C()
|
||||
|
||||
c.builder {
|
||||
baz()
|
||||
}
|
||||
|
||||
while (!finished) {
|
||||
log += "@;"
|
||||
continuation()
|
||||
}
|
||||
|
||||
if (log != expectedString) return "fail: $log"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+24
@@ -5788,6 +5788,30 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModule.kt")
|
||||
public void testInlineMultiModule() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModule.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModuleOverride.kt")
|
||||
public void testInlineMultiModuleOverride() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleOverride.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModuleWithController.kt")
|
||||
public void testInlineMultiModuleWithController() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleWithController.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/simple.kt");
|
||||
|
||||
@@ -5788,6 +5788,30 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModule.kt")
|
||||
public void testInlineMultiModule() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModule.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModuleOverride.kt")
|
||||
public void testInlineMultiModuleOverride() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleOverride.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModuleWithController.kt")
|
||||
public void testInlineMultiModuleWithController() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleWithController.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/simple.kt");
|
||||
|
||||
@@ -5778,6 +5778,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MultiModule extends AbstractLightAnalysisModeTest {
|
||||
@TestMetadata("inlineMultiModuleOverride.kt")
|
||||
public void ignoreInlineMultiModuleOverride() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleOverride.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMultiModule() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/multiModule"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
@@ -5788,6 +5800,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModule.kt")
|
||||
public void testInlineMultiModule() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModule.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModuleWithController.kt")
|
||||
public void testInlineMultiModuleWithController() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleWithController.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/simple.kt");
|
||||
|
||||
@@ -59,19 +59,26 @@ public abstract class JsVisitorWithContext {
|
||||
doAcceptStatementList(statements);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsExpression x, @NotNull JsContext ctx) {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsArrayAccess x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsArrayLiteral x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsBinaryOperation x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsBlock x, @NotNull JsContext ctx) {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsBooleanLiteral x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsBreak x, @NotNull JsContext ctx) {
|
||||
@@ -84,6 +91,7 @@ public abstract class JsVisitorWithContext {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsConditional x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsContinue x, @NotNull JsContext ctx) {
|
||||
@@ -111,12 +119,14 @@ public abstract class JsVisitorWithContext {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsFunction x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsIf x, @NotNull JsContext ctx) {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsInvocation x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsLabel x, @NotNull JsContext ctx) {
|
||||
@@ -126,27 +136,33 @@ public abstract class JsVisitorWithContext {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsNameRef x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsNew x, @NotNull JsContext ctx) {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsNullLiteral x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsNumberLiteral x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsObjectLiteral x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsParameter x, @NotNull JsContext ctx) {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsPostfixOperation x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsPrefixOperation x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsProgram x, @NotNull JsContext ctx) {
|
||||
@@ -156,18 +172,21 @@ public abstract class JsVisitorWithContext {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsRegExp x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsReturn x, @NotNull JsContext ctx) {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsStringLiteral x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsSwitch x, @NotNull JsContext ctx) {
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsThisRef x, @NotNull JsContext ctx) {
|
||||
endVisit((JsExpression) x, ctx);
|
||||
}
|
||||
|
||||
public void endVisit(@NotNull JsThrow x, @NotNull JsContext ctx) {
|
||||
|
||||
@@ -147,6 +147,10 @@ enum class SpecialFunction(val suggestedName: String) {
|
||||
WRAP_FUNCTION("wrapFunction"),
|
||||
TO_BOXED_CHAR("toBoxedChar"),
|
||||
UNBOX_CHAR("unboxChar"),
|
||||
SUSPEND_CALL("suspendCall"),
|
||||
COROUTINE_RESULT("coroutineResult"),
|
||||
COROUTINE_CONTROLLER("coroutineController"),
|
||||
COROUTINE_RECEIVER("coroutineReceiver")
|
||||
}
|
||||
|
||||
enum class BoxingKind {
|
||||
|
||||
@@ -49,7 +49,10 @@ private val JS_IDENTIFIER_PART = "$JS_IDENTIFIER_START\\p{Pc}\\p{Mc}\\p{Mn}\\d"
|
||||
private val JS_IDENTIFIER="[$JS_IDENTIFIER_START][$JS_IDENTIFIER_PART]*"
|
||||
private val DEFINE_MODULE_PATTERN = ("($JS_IDENTIFIER)\\.defineModule\\(\\s*(['\"])([^'\"]+)\\2\\s*,\\s*(\\w+)\\s*\\)").toRegex().toPattern()
|
||||
private val DEFINE_MODULE_FIND_PATTERN = ".defineModule("
|
||||
private val WRAP_FUNCTION_PATTERN = Regex("var\\s+($JS_IDENTIFIER)\\s*=\\s*($JS_IDENTIFIER)\\.wrapFunction\\s*;").toPattern()
|
||||
|
||||
private val specialFunctions = enumValues<SpecialFunction>().joinToString("|") { it.suggestedName }
|
||||
private val specialFunctionsByName = enumValues<SpecialFunction>().associateBy { it.suggestedName }
|
||||
private val SPECIAL_FUNCTION_PATTERN = Regex("var\\s+($JS_IDENTIFIER)\\s*=\\s*($JS_IDENTIFIER)\\.($specialFunctions)\\s*;").toPattern()
|
||||
|
||||
class FunctionReader(
|
||||
private val reporter: JsConfig.Reporter,
|
||||
@@ -72,13 +75,15 @@ class FunctionReader(
|
||||
val fileContent: String,
|
||||
val moduleVariable: String,
|
||||
val kotlinVariable: String,
|
||||
val wrapFunctionVariable: String?,
|
||||
val specialFunctions: Map<String, SpecialFunction>,
|
||||
offsetToSourceMappingProvider: () -> OffsetToSourceMapping,
|
||||
val sourceMap: SourceMap?
|
||||
) {
|
||||
val offsetToSourceMapping by lazy(offsetToSourceMappingProvider)
|
||||
|
||||
val wrapFunctionRegex = wrapFunctionVariable?.let { Regex("\\s*$it\\s*\\(\\s*").toPattern() }
|
||||
val wrapFunctionRegex = specialFunctions.entries
|
||||
.singleOrNull { (_, v) -> v == SpecialFunction.WRAP_FUNCTION }?.key
|
||||
?.let { Regex("\\s*$it\\s*\\(\\s*").toPattern() }
|
||||
}
|
||||
|
||||
private val moduleNameToInfo by lazy {
|
||||
@@ -100,8 +105,12 @@ class FunctionReader(
|
||||
val moduleVariable = preciseMatcher.group(4)
|
||||
val kotlinVariable = preciseMatcher.group(1)
|
||||
|
||||
val wrapFunctionVariable = WRAP_FUNCTION_PATTERN.matcher(content).let { matcher ->
|
||||
if (matcher.find() && matcher.group(2) == kotlinVariable) matcher.group(1) else null
|
||||
val matcher = SPECIAL_FUNCTION_PATTERN.matcher(content)
|
||||
val specialFunctions = mutableMapOf<String, SpecialFunction>()
|
||||
while (matcher.find()) {
|
||||
if (matcher.group(2) == kotlinVariable) {
|
||||
specialFunctions[matcher.group(1)] = specialFunctionsByName[matcher.group(3)]!!
|
||||
}
|
||||
}
|
||||
|
||||
val sourceMap = sourceMapContent?.let {
|
||||
@@ -120,7 +129,7 @@ class FunctionReader(
|
||||
fileContent = content,
|
||||
moduleVariable = moduleVariable,
|
||||
kotlinVariable = kotlinVariable,
|
||||
wrapFunctionVariable = wrapFunctionVariable,
|
||||
specialFunctions = specialFunctions,
|
||||
offsetToSourceMappingProvider = { OffsetToSourceMapping(content) },
|
||||
sourceMap = sourceMap
|
||||
)
|
||||
@@ -246,9 +255,9 @@ class FunctionReader(
|
||||
function.markInlineArguments(descriptor)
|
||||
markDefaultParams(function)
|
||||
|
||||
info.wrapFunctionVariable.let { wrapFunction ->
|
||||
for (externalName in (collectReferencedNames(function) - allDefinedNames).filter { it.ident == wrapFunction }) {
|
||||
externalName.specialFunction = SpecialFunction.WRAP_FUNCTION
|
||||
for (externalName in (collectReferencedNames(function) - allDefinedNames)) {
|
||||
info.specialFunctions[externalName.ident]?.let {
|
||||
externalName.specialFunction = it
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jetbrains.kotlin.js.inline.util.CollectUtilsKt.getImportTag;
|
||||
import static org.jetbrains.kotlin.js.translate.declaration.InlineCoroutineUtilKt.transformSpecialFunctionsToCoroutineMetadata;
|
||||
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.flattenStatement;
|
||||
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn;
|
||||
|
||||
@@ -348,6 +349,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
||||
}
|
||||
|
||||
JsFunction function = functionWithWrapper.getFunction().deepCopy();
|
||||
function.setBody(transformSpecialFunctionsToCoroutineMetadata(function.getBody()));
|
||||
if (functionWithWrapper.getWrapperBody() != null) {
|
||||
applyWrapper(functionWithWrapper.getWrapperBody(), function, functionWithWrapper.getFunction(), inliningContext);
|
||||
}
|
||||
|
||||
@@ -61,3 +61,16 @@ Kotlin.andPredicate = function (a, b) {
|
||||
|
||||
Kotlin.kotlinModuleMetadata = function (abiVersion, moduleName, data) {
|
||||
};
|
||||
|
||||
Kotlin.suspendCall = function(value) {
|
||||
return value;
|
||||
};
|
||||
|
||||
Kotlin.coroutineResult = function(qualifier) {
|
||||
};
|
||||
|
||||
Kotlin.coroutineController = function(qualifier) {
|
||||
};
|
||||
|
||||
Kotlin.coroutineReceiver = function(qualifier) {
|
||||
};
|
||||
@@ -435,6 +435,10 @@ enum SpecialFunction {
|
||||
WRAP_FUNCTION = 2;
|
||||
TO_BOXED_CHAR = 3;
|
||||
UNBOX_CHAR = 4;
|
||||
SUSPEND_CALL = 5;
|
||||
COROUTINE_RESULT = 6;
|
||||
COROUTINE_CONTROLLER = 7;
|
||||
COROUTINE_RECEIVER = 8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -522,6 +522,10 @@ class JsAstDeserializer(program: JsProgram, private val sourceRoots: Iterable<Fi
|
||||
JsAstProtoBuf.SpecialFunction.WRAP_FUNCTION -> SpecialFunction.WRAP_FUNCTION
|
||||
JsAstProtoBuf.SpecialFunction.TO_BOXED_CHAR -> SpecialFunction.TO_BOXED_CHAR
|
||||
JsAstProtoBuf.SpecialFunction.UNBOX_CHAR -> SpecialFunction.UNBOX_CHAR
|
||||
JsAstProtoBuf.SpecialFunction.SUSPEND_CALL -> SpecialFunction.SUSPEND_CALL
|
||||
JsAstProtoBuf.SpecialFunction.COROUTINE_RESULT -> SpecialFunction.COROUTINE_RESULT
|
||||
JsAstProtoBuf.SpecialFunction.COROUTINE_CONTROLLER -> SpecialFunction.COROUTINE_CONTROLLER
|
||||
JsAstProtoBuf.SpecialFunction.COROUTINE_RECEIVER -> SpecialFunction.COROUTINE_RECEIVER
|
||||
}
|
||||
|
||||
private fun <T : JsNode> withLocation(fileId: Int?, location: Location?, action: () -> T): T {
|
||||
|
||||
@@ -159,6 +159,22 @@ public final class JsAstProtoBuf {
|
||||
* <code>UNBOX_CHAR = 4;</code>
|
||||
*/
|
||||
UNBOX_CHAR(3, 4),
|
||||
/**
|
||||
* <code>SUSPEND_CALL = 5;</code>
|
||||
*/
|
||||
SUSPEND_CALL(4, 5),
|
||||
/**
|
||||
* <code>COROUTINE_RESULT = 6;</code>
|
||||
*/
|
||||
COROUTINE_RESULT(5, 6),
|
||||
/**
|
||||
* <code>COROUTINE_CONTROLLER = 7;</code>
|
||||
*/
|
||||
COROUTINE_CONTROLLER(6, 7),
|
||||
/**
|
||||
* <code>COROUTINE_RECEIVER = 8;</code>
|
||||
*/
|
||||
COROUTINE_RECEIVER(7, 8),
|
||||
;
|
||||
|
||||
/**
|
||||
@@ -177,6 +193,22 @@ public final class JsAstProtoBuf {
|
||||
* <code>UNBOX_CHAR = 4;</code>
|
||||
*/
|
||||
public static final int UNBOX_CHAR_VALUE = 4;
|
||||
/**
|
||||
* <code>SUSPEND_CALL = 5;</code>
|
||||
*/
|
||||
public static final int SUSPEND_CALL_VALUE = 5;
|
||||
/**
|
||||
* <code>COROUTINE_RESULT = 6;</code>
|
||||
*/
|
||||
public static final int COROUTINE_RESULT_VALUE = 6;
|
||||
/**
|
||||
* <code>COROUTINE_CONTROLLER = 7;</code>
|
||||
*/
|
||||
public static final int COROUTINE_CONTROLLER_VALUE = 7;
|
||||
/**
|
||||
* <code>COROUTINE_RECEIVER = 8;</code>
|
||||
*/
|
||||
public static final int COROUTINE_RECEIVER_VALUE = 8;
|
||||
|
||||
|
||||
public final int getNumber() { return value; }
|
||||
@@ -187,6 +219,10 @@ public final class JsAstProtoBuf {
|
||||
case 2: return WRAP_FUNCTION;
|
||||
case 3: return TO_BOXED_CHAR;
|
||||
case 4: return UNBOX_CHAR;
|
||||
case 5: return SUSPEND_CALL;
|
||||
case 6: return COROUTINE_RESULT;
|
||||
case 7: return COROUTINE_CONTROLLER;
|
||||
case 8: return COROUTINE_RECEIVER;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,6 +558,10 @@ class JsAstSerializer(private val pathResolver: (File) -> String) {
|
||||
SpecialFunction.WRAP_FUNCTION -> JsAstProtoBuf.SpecialFunction.WRAP_FUNCTION
|
||||
SpecialFunction.TO_BOXED_CHAR -> JsAstProtoBuf.SpecialFunction.TO_BOXED_CHAR
|
||||
SpecialFunction.UNBOX_CHAR -> JsAstProtoBuf.SpecialFunction.UNBOX_CHAR
|
||||
SpecialFunction.SUSPEND_CALL -> JsAstProtoBuf.SpecialFunction.SUSPEND_CALL
|
||||
SpecialFunction.COROUTINE_RESULT -> JsAstProtoBuf.SpecialFunction.COROUTINE_RESULT
|
||||
SpecialFunction.COROUTINE_CONTROLLER -> JsAstProtoBuf.SpecialFunction.COROUTINE_CONTROLLER
|
||||
SpecialFunction.COROUTINE_RECEIVER -> JsAstProtoBuf.SpecialFunction.COROUTINE_RECEIVER
|
||||
}
|
||||
|
||||
private fun serialize(name: JsName): Int = nameMap.getOrPut(name) {
|
||||
|
||||
+18
@@ -6424,6 +6424,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModule.kt")
|
||||
public void testInlineMultiModule() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModule.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModuleOverride.kt")
|
||||
public void testInlineMultiModuleOverride() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleOverride.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineMultiModuleWithController.kt")
|
||||
public void testInlineMultiModuleWithController() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleWithController.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/simple.kt");
|
||||
|
||||
@@ -95,7 +95,6 @@ public final class Namer {
|
||||
|
||||
public static final JsNameRef IS_ARRAY_FUN_REF = new JsNameRef("isArray", "Array");
|
||||
public static final String DEFINE_INLINE_FUNCTION = "defineInlineFunction";
|
||||
private static final String WRAP_FUNCTION = "wrapFunction";
|
||||
public static final String DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX = "$default";
|
||||
|
||||
private static final JsNameRef JS_OBJECT = new JsNameRef("Object");
|
||||
@@ -324,30 +323,9 @@ public final class Namer {
|
||||
return pureFqn("Long", kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsNameRef createInlineFunction() {
|
||||
return pureFqn(DEFINE_INLINE_FUNCTION, kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsNameRef wrapFunction() {
|
||||
return pureFqn(WRAP_FUNCTION, kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression createSpecialFunction(@NotNull SpecialFunction specialFunction) {
|
||||
switch (specialFunction) {
|
||||
case DEFINE_INLINE_FUNCTION:
|
||||
return createInlineFunction();
|
||||
case WRAP_FUNCTION:
|
||||
return wrapFunction();
|
||||
case TO_BOXED_CHAR:
|
||||
return pureFqn("toBoxedChar", kotlinObject());
|
||||
case UNBOX_CHAR:
|
||||
return pureFqn("unboxChar", kotlinObject());
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown function: " + specialFunction);
|
||||
}
|
||||
return pureFqn(specialFunction.getSuggestedName(), kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+33
-9
@@ -21,15 +21,17 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.isOverridable
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.coroutineMetadata
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.shouldBeExported
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.expression.translateAndAliasParameters
|
||||
import org.jetbrains.kotlin.js.translate.expression.translateFunction
|
||||
import org.jetbrains.kotlin.js.translate.expression.wrapWithInlineMetadata
|
||||
import org.jetbrains.kotlin.js.translate.expression.*
|
||||
import org.jetbrains.kotlin.js.translate.general.TranslatorVisitor
|
||||
import org.jetbrains.kotlin.js.translate.utils.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtensionProperty
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
|
||||
abstract class AbstractDeclarationVisitor : TranslatorVisitor<Unit>() {
|
||||
override fun emptyResult(context: TranslationContext) { }
|
||||
@@ -52,7 +54,7 @@ abstract class AbstractDeclarationVisitor : TranslatorVisitor<Unit>() {
|
||||
val defaultTranslator = DefaultPropertyTranslator(descriptor, context, getBackingFieldReference(descriptor))
|
||||
val getter = descriptor.getter!!
|
||||
val getterExpr = if (expression.hasCustomGetter()) {
|
||||
translateFunction(getter, expression.getter!!, propertyContext)
|
||||
translateFunction(getter, expression.getter!!, propertyContext).first
|
||||
}
|
||||
else {
|
||||
val function = context.getFunctionObject(getter)
|
||||
@@ -64,7 +66,7 @@ abstract class AbstractDeclarationVisitor : TranslatorVisitor<Unit>() {
|
||||
val setterExpr = if (descriptor.isVar) {
|
||||
val setter = descriptor.setter!!
|
||||
if (expression.hasCustomSetter()) {
|
||||
translateFunction(setter, expression.setter!!, propertyContext)
|
||||
translateFunction(setter, expression.setter!!, propertyContext).first
|
||||
}
|
||||
else {
|
||||
val function = context.getFunctionObject(setter)
|
||||
@@ -88,8 +90,23 @@ abstract class AbstractDeclarationVisitor : TranslatorVisitor<Unit>() {
|
||||
|
||||
override fun visitNamedFunction(expression: KtNamedFunction, context: TranslationContext) {
|
||||
val descriptor = BindingUtils.getFunctionDescriptor(context.bindingContext(), expression)
|
||||
val jsFunction = if (descriptor.modality != Modality.ABSTRACT) translateFunction(descriptor, expression, context) else null
|
||||
addFunction(descriptor, jsFunction, expression)
|
||||
val functionAndContext = if (descriptor.modality != Modality.ABSTRACT) {
|
||||
translateFunction(descriptor, expression, context)
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
addFunction(descriptor, functionAndContext?.first, expression)
|
||||
|
||||
if (descriptor.isSuspend && descriptor.isInline && descriptor.shouldBeExported(context.config) && functionAndContext != null) {
|
||||
val innerContext = functionAndContext.second
|
||||
val inlineFunction = transformCoroutineMetadataToSpecialFunctions(context, functionAndContext.first.deepCopy() as JsFunction)
|
||||
inlineFunction.name = null
|
||||
inlineFunction.coroutineMetadata = null
|
||||
val metadata = InlineMetadata.compose(inlineFunction, descriptor, innerContext)
|
||||
val functionWithMetadata = metadata.functionWithMetadata(context, descriptor.source.getPsi())
|
||||
context.addDeclarationStatement(functionWithMetadata.makeStmt())
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitTypeAlias(typeAlias: KtTypeAlias, data: TranslationContext?) {}
|
||||
@@ -98,7 +115,7 @@ abstract class AbstractDeclarationVisitor : TranslatorVisitor<Unit>() {
|
||||
descriptor: FunctionDescriptor,
|
||||
expression: KtDeclarationWithBody,
|
||||
context: TranslationContext
|
||||
): JsExpression {
|
||||
): Pair<JsExpression, TranslationContext> {
|
||||
val function = context.getFunctionObject(descriptor)
|
||||
function.source = expression.finalElement
|
||||
val innerContext = context.newDeclaration(descriptor).translateAndAliasParameters(descriptor, function.parameters)
|
||||
@@ -113,7 +130,14 @@ abstract class AbstractDeclarationVisitor : TranslatorVisitor<Unit>() {
|
||||
function.body.statements += FunctionBodyTranslator.setDefaultValueForArguments(descriptor, innerContext)
|
||||
}
|
||||
innerContext.translateFunction(expression, function)
|
||||
return innerContext.wrapWithInlineMetadata(context, function, descriptor)
|
||||
val result = if (descriptor.isSuspend && descriptor.shouldBeExported(context.config)) {
|
||||
function
|
||||
}
|
||||
else {
|
||||
innerContext.wrapWithInlineMetadata(context, function, descriptor)
|
||||
}
|
||||
|
||||
return Pair(result, innerContext)
|
||||
}
|
||||
|
||||
// used from kotlinx.serialization
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.declaration
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.*
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.name
|
||||
|
||||
fun <T : JsNode> transformCoroutineMetadataToSpecialFunctions(context: TranslationContext, node: T): T {
|
||||
val visitor = object : JsVisitorWithContextImpl() {
|
||||
override fun endVisit(x: JsNameRef, ctx: JsContext<in JsExpression>) {
|
||||
val specialFunction = when {
|
||||
x.coroutineController -> SpecialFunction.COROUTINE_CONTROLLER
|
||||
x.coroutineReceiver -> SpecialFunction.COROUTINE_RECEIVER
|
||||
x.coroutineResult -> SpecialFunction.COROUTINE_RESULT
|
||||
else -> null
|
||||
}
|
||||
if (specialFunction != null) {
|
||||
val arguments = listOfNotNull(x.qualifier).toTypedArray()
|
||||
ctx.replaceMe(TranslationUtils.invokeSpecialFunction(context, specialFunction, *arguments).source(x.source))
|
||||
}
|
||||
else {
|
||||
super.endVisit(x, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
override fun endVisit(x: JsExpression, ctx: JsContext<in JsExpression>) {
|
||||
if (x.isSuspend) {
|
||||
x.isSuspend = false
|
||||
ctx.replaceMe(TranslationUtils.invokeSpecialFunction(context, SpecialFunction.SUSPEND_CALL, x).source(x.source))
|
||||
}
|
||||
}
|
||||
}
|
||||
return visitor.accept(node)
|
||||
}
|
||||
|
||||
fun <T : JsNode> transformSpecialFunctionsToCoroutineMetadata(node: T): T {
|
||||
val visitor = object : JsVisitorWithContextImpl() {
|
||||
override fun endVisit(x: JsInvocation, ctx: JsContext<in JsExpression>) {
|
||||
x.qualifier.name?.specialFunction?.let { specialFunction ->
|
||||
val replacement = when (specialFunction) {
|
||||
SpecialFunction.COROUTINE_CONTROLLER -> {
|
||||
JsNameRef("\$\$controller\$\$", x.arguments.getOrNull(0)).apply {
|
||||
coroutineController = true
|
||||
}
|
||||
}
|
||||
SpecialFunction.COROUTINE_RECEIVER -> {
|
||||
JsNameRef("\$this\$", x.arguments.getOrNull(0)).apply {
|
||||
coroutineReceiver = true
|
||||
}
|
||||
}
|
||||
SpecialFunction.COROUTINE_RESULT -> {
|
||||
JsNameRef("\$result\$", x.arguments.getOrNull(0)).apply {
|
||||
coroutineResult = true
|
||||
}
|
||||
}
|
||||
SpecialFunction.SUSPEND_CALL -> {
|
||||
x.arguments[0].apply {
|
||||
isSuspend = true
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
replacement?.let { ctx.replaceMe(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
return visitor.accept(node)
|
||||
}
|
||||
+1
-1
@@ -112,7 +112,7 @@ fun TranslationContext.wrapWithInlineMetadata(
|
||||
if (descriptor.shouldBeExported(config)) {
|
||||
val metadata = InlineMetadata.compose(function, descriptor, this)
|
||||
val functionWithMetadata = metadata.functionWithMetadata(outerContext, sourceInfo)
|
||||
config.configuration[JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER]?.apply {
|
||||
config.configuration[JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER]?.apply {
|
||||
val psiFile = (descriptor.source.containingFile as? PsiSourceFile)?.psiFile ?: return@apply
|
||||
val file = VfsUtilCore.virtualToIoFile(psiFile.virtualFile)
|
||||
|
||||
|
||||
@@ -526,7 +526,7 @@ public final class TranslationUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsInvocation invokeSpecialFunction(
|
||||
public static JsInvocation invokeSpecialFunction(
|
||||
@NotNull TranslationContext context,
|
||||
@NotNull SpecialFunction function, @NotNull JsExpression... arguments
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user