diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/JsInliner.java b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/JsInliner.java index e749f58af96..2d6b1034f9d 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/JsInliner.java +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/JsInliner.java @@ -69,6 +69,8 @@ public class JsInliner extends JsVisitorWithContextImpl { private final List additionalNameBindings = new ArrayList<>(); + private final Set inlinedModuleAliases = new HashSet<>(); + public static void process( @NotNull JsConfig.Reporter reporter, @NotNull JsConfig config, @@ -94,9 +96,12 @@ public class JsInliner extends JsVisitorWithContextImpl { inliner.processImportStatement(statement); } + Map moduleMap = fillModuleMap(buildModuleMap(fragments), fragmentsToProcess); + for (JsProgramFragment fragment : fragmentsToProcess) { inliner.existingImports.clear(); inliner.additionalNameBindings.clear(); + inliner.inlinedModuleAliases.clear(); inliner.existingNameBindings = CollectUtilsKt.collectNameBindings(Collections.singletonList(fragment)); inliner.acceptStatement(fragment.getDeclarationBlock()); @@ -110,6 +115,7 @@ public class JsInliner extends JsVisitorWithContextImpl { fragment.getInitializerBlock().getStatements().addAll(0, initWrapper.getStatements()); fragment.getNameBindings().addAll(inliner.additionalNameBindings); + inliner.addInlinedModules(fragment, moduleMap); } for (JsProgramFragment fragment : fragmentsToProcess) { @@ -120,6 +126,29 @@ public class JsInliner extends JsVisitorWithContextImpl { } } + private void addInlinedModules(JsProgramFragment fragment, Map moduleMap) { + Set localMap = buildModuleMap(Collections.singletonList(fragment)).keySet(); + for (JsName inlinedModuleName : inlinedModuleAliases) { + if (!localMap.contains(inlinedModuleName)) { + fragment.getImportedModules().add(moduleMap.get(inlinedModuleName)); + } + } + } + + private static Map buildModuleMap(List fragments) { + return fillModuleMap(new HashMap<>(), fragments); + } + + private static Map fillModuleMap(Map map, List fragments) { + for (JsProgramFragment fragment : fragments) { + for (JsImportedModule module : fragment.getImportedModules()) { + map.put(module.getInternalName(), module); + } + } + return map; + } + + private JsInliner( @NotNull JsConfig config, @NotNull Map functions, @@ -489,7 +518,7 @@ public class JsInliner extends JsVisitorWithContextImpl { } } - private static void replaceExpressionsWithLocalAliases(@NotNull JsStatement statement) { + private void replaceExpressionsWithLocalAliases(@NotNull JsStatement statement) { new JsVisitorWithContextImpl() { @Override public void endVisit(@NotNull JsNameRef x, @NotNull JsContext ctx) { @@ -507,6 +536,7 @@ public class JsInliner extends JsVisitorWithContextImpl { @SuppressWarnings("unchecked") JsContext context = (JsContext) ctx; context.replaceMe(alias.makeRef()); + inlinedModuleAliases.add(alias); } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index d5f93db39a7..8fb536bda4d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -3523,6 +3523,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/incremental/inlineLambda.kt"); } + @TestMetadata("inlineModuleVariable.kt") + public void testInlineModuleVariable() throws Exception { + runTest("js/js.translator/testData/box/incremental/inlineModuleVariable.kt"); + } + @TestMetadata("jsModule.kt") public void testJsModule() throws Exception { runTest("js/js.translator/testData/box/incremental/jsModule.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrBoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrBoxJsTestGenerated.java index b17390c84f5..d9a95da970a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrBoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrBoxJsTestGenerated.java @@ -3523,6 +3523,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/incremental/inlineLambda.kt"); } + @TestMetadata("inlineModuleVariable.kt") + public void testInlineModuleVariable() throws Exception { + runTest("js/js.translator/testData/box/incremental/inlineModuleVariable.kt"); + } + @TestMetadata("jsModule.kt") public void testJsModule() throws Exception { runTest("js/js.translator/testData/box/incremental/jsModule.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt index 505401508b1..db666647346 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt @@ -156,6 +156,9 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam ) } } + if (node is JsExpression) { + node.localAlias = node.localAlias?.let { rename(it) } + } } }) return rootNode diff --git a/js/js.translator/testData/box/incremental/inlineModuleVariable.kt b/js/js.translator/testData/box/incremental/inlineModuleVariable.kt new file mode 100644 index 00000000000..3ab837070ff --- /dev/null +++ b/js/js.translator/testData/box/incremental/inlineModuleVariable.kt @@ -0,0 +1,19 @@ +// EXPECTED_REACHABLE_NODES: 1282 +// MODULE: lib +// FILE: lib.kt + +fun foo() = "OK" + +// MODULE: main(lib) +// FILE: mainAux.kt + +inline fun proxy() = foo() + +// FILE: mainDummy.kt +// RECOMPILE + +val dummy get() = js("\$module\$lib") + +// FILE: main.kt + +fun box() = proxy() \ No newline at end of file