diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationsRemoveLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationsRemoveLowering.kt new file mode 100644 index 00000000000..2ad2c48dd6b --- /dev/null +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationsRemoveLowering.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.common.lower + +import org.jetbrains.kotlin.backend.common.BackendContext +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.util.ExpectDeclarationRemover +import org.jetbrains.kotlin.ir.util.patchDeclarationParents +import org.jetbrains.kotlin.ir.visitors.acceptVoid + +/** + * This pass removes all declarations with `isExpect == true`. + */ +class ExpectDeclarationsRemoveLowering(val context: BackendContext) : FileLoweringPass { + + val visitor = ExpectDeclarationRemover(context.ir.symbols.externalSymbolTable, true) + + override fun lower(irFile: IrFile) { + irFile.acceptVoid(visitor) + } +} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index 51471f9e878..dae90a7e1a7 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -87,7 +87,7 @@ private val moveBodilessDeclarationsToSeparatePlacePhase = makeCustomJsModulePha ) private val expectDeclarationsRemovingPhase = makeJsModulePhase( - ::ExpectDeclarationsRemoving, + ::ExpectDeclarationsRemoveLowering, name = "ExpectDeclarationsRemoving", description = "Remove expect declaration from module fragment" ) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt index ef1712dc87b..8a2fd9517e6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt @@ -157,8 +157,10 @@ internal class DeepCopyIrTreeWithSymbolsForInliner( if (type !is IrSimpleType) return type val substitutedType = typeArguments?.get(type.classifier) - if (substitutedType != null) { - substitutedType as IrSimpleType + + if (substitutedType is IrDynamicType) return substitutedType + + if (substitutedType is IrSimpleType) { return substitutedType.buildSimpleType { kotlinType = null hasQuestionMark = type.hasQuestionMark or substitutedType.isMarkedNullable() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt index 5930565b5bd..0d531ab0fcf 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt @@ -282,6 +282,8 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer T.findActualForExpect() = with(ExpectedActualResolver) { val descriptor = this@findActualForExpect diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index e5ea8404e13..d83c0c44723 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -29,7 +29,9 @@ import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.createJsK import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.* import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.util.ExpectDeclarationRemover import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult import org.jetbrains.kotlin.name.Name @@ -83,6 +85,9 @@ fun generateKLib( val moduleFragment = psi2IrContext.generateModuleFragment(files) val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME]!! + + moduleFragment.acceptVoid(ExpectDeclarationRemover(psi2IrContext.symbolTable, false)) + serializeModuleIntoKlib( moduleName, configuration.metadataVersion, diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedFunction.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedFunction.kt new file mode 100644 index 00000000000..d7db513626f --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedFunction.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +MultiPlatformProjects +// WITH_RUNTIME +// MODULE: lib +// FILE: common.kt + +expect fun foo(a: String, b: String = "O"): String + +// FILE: platform.kt + +actual fun foo(a: String, b: String) = a + b + +// MODULE: main(lib) +// FILE: main.kt + +fun box(): String { + return foo("") + foo("K", "") +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 197483e3ecf..c45e66fe0c0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -16150,6 +16150,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt"); } + @TestMetadata("inheritedFromExpectedFunction.kt") + public void testInheritedFromExpectedFunction() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedFunction.kt"); + } + @TestMetadata("inheritedFromExpectedInterface.kt") public void testInheritedFromExpectedInterface() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index ab5ee9baf1f..932c6d93c34 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16155,6 +16155,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt"); } + @TestMetadata("inheritedFromExpectedFunction.kt") + public void testInheritedFromExpectedFunction() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedFunction.kt"); + } + @TestMetadata("inheritedFromExpectedInterface.kt") public void testInheritedFromExpectedInterface() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 0ffe278b308..e45fa004454 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -16155,6 +16155,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt"); } + @TestMetadata("inheritedFromExpectedFunction.kt") + public void testInheritedFromExpectedFunction() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedFunction.kt"); + } + @TestMetadata("inheritedFromExpectedInterface.kt") public void testInheritedFromExpectedInterface() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index c3acfa0ffc5..bee60886e29 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -12365,6 +12365,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt"); } + @TestMetadata("inheritedFromExpectedFunction.kt") + public void testInheritedFromExpectedFunction() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedFunction.kt"); + } + @TestMetadata("inheritedFromExpectedInterface.kt") public void testInheritedFromExpectedInterface() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 6da5baffb00..0354b391b11 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -13520,6 +13520,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt"); } + @TestMetadata("inheritedFromExpectedFunction.kt") + public void testInheritedFromExpectedFunction() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedFunction.kt"); + } + @TestMetadata("inheritedFromExpectedInterface.kt") public void testInheritedFromExpectedInterface() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt"); diff --git a/js/js.translator/testData/box/jsModule/externalClass.js b/js/js.translator/testData/box/jsModule/externalClass.js index 676c34773db..438a3bc597e 100644 --- a/js/js.translator/testData/box/jsModule/externalClass.js +++ b/js/js.translator/testData/box/jsModule/externalClass.js @@ -6,5 +6,9 @@ define("lib", [], function() { return this.x + y; }; + A.prototype.bar = function() { + return "(" + Array.prototype.join.call(arguments, "") + ")"; + }; + return A; }); \ No newline at end of file diff --git a/js/js.translator/testData/box/jsModule/externalClass.kt b/js/js.translator/testData/box/jsModule/externalClass.kt index 1c7af34da2f..a45d2cc2dc7 100644 --- a/js/js.translator/testData/box/jsModule/externalClass.kt +++ b/js/js.translator/testData/box/jsModule/externalClass.kt @@ -7,12 +7,24 @@ external class A(x: Int = definedExternally) { val x: Int fun foo(y: Int): Int = definedExternally + + fun bar(vararg arg: String): String = definedExternally } +class C { + val e = arrayOf("e") + val f = arrayOf("f") + val a = A(1) + + fun qux() = a.bar(*e, *f) +} + + fun box(): String { val a = A(23) assertEquals(23, a.x) assertEquals(65, a.foo(42)) + assertEquals(C().qux(), "(ef)") return "OK" } \ No newline at end of file