From ab7615adaffe88087f61e6ef1906f2102f838a7c Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Fri, 17 Dec 2021 14:22:46 +0000 Subject: [PATCH] fix: fake override on interfaces. --- .../transformers/irToJs/JsClassGenerator.kt | 7 +++++- .../testData/box/export/exportInterface.kt | 24 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt index 0e601295218..e14788747f4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt @@ -141,7 +141,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo // so we need regenerate `defineProperty` with setter. // P.S. If the overridden property is owned by an interface - we should generate defineProperty // for overridden property in the first class which override those properties - val hasOverriddenExportedInterfaceProperties = overriddenSymbols.any { it.owner.parentClassOrNull.isExportedInterface() } + val hasOverriddenExportedInterfaceProperties = overriddenSymbols.any { it.owner.isDefinedInsideExportedInterface() } && !overriddenSymbols.any { it.owner.parentClassOrNull.isExportedClass() } val getterOverridesExternal = property.getter?.overridesExternal() == true @@ -212,6 +212,11 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo return if (modality == Modality.FINAL) accessorRef() else generateFunc() } + private fun IrSimpleFunction.isDefinedInsideExportedInterface(): Boolean { + return (!isFakeOverride && parentClassOrNull.isExportedInterface()) || + overriddenSymbols.any { it.owner.isDefinedInsideExportedInterface() } + } + private fun IrSimpleFunction?.shouldExportAccessor(): Boolean { if (this == null) return false diff --git a/js/js.translator/testData/box/export/exportInterface.kt b/js/js.translator/testData/box/export/exportInterface.kt index da204b4e0a7..9feb043f26a 100644 --- a/js/js.translator/testData/box/export/exportInterface.kt +++ b/js/js.translator/testData/box/export/exportInterface.kt @@ -5,22 +5,34 @@ // MODULE: export_interface // FILE: lib.kt +interface ParentI { + val str: String +} + @JsExport -interface I { +interface I : ParentI { val value: Int var variable: Int fun foo(): String } -open class NotExportedClass(override var value: Int) : I { +interface ExtendedI: I { + fun bar(): Int +} + +open class NotExportedClass(override var value: Int) : ExtendedI { override var variable: Int = value override open fun foo(): String = "Not Exported" + override val str: String = "test 1" + override open fun bar(): Int = 42 } @JsExport -class ExportedClass(override val value: Int) : I { +class ExportedClass(override val value: Int) : ExtendedI { override var variable: Int = value override fun foo(): String = "Exported" + override val str: String = "test 2" + override open fun bar(): Int = 43 } @JsExport @@ -75,5 +87,11 @@ function box() { if (consume(another) !== "Value is 42, variable is 102 and result is 'Another One Exported'") return "Fail: methods or fields of AnotherOne was mangled" if (consume(notExported) !== "Value is 3, variable is 103 and result is 'Not Exported'") return "Fail: methods or fields of NotExported was mangled" + if (notExported.str !== undefined) return "Fail: str should not exist inside NotExportedClass" + if (exported.str !== undefined) return "Fail: str should not exist inside ExportedClass" + + if (notExported.bar !== undefined) return "Fail: bar should not exist inside NotExportedClass" + if (exported.bar !== undefined) return "Fail: bar should not exist inside ExportedClass" + return "OK" } \ No newline at end of file