diff options
author | Anton Bannykh <anton.bannykh@jetbrains.com> | 2022-05-11 13:24:26 +0000 |
---|---|---|
committer | Space <> | 2022-05-11 13:24:26 +0000 |
commit | db6b2cc11ab4f98ee39f1cadf5fbb1c3c2881021 (patch) | |
tree | 858ee99d42d6b9cfa01a9d47859fe506e86de2d1 | |
parent | ba36c2ce1e41f276063552e0cb8bedf9d6a95d92 (diff) | |
download | kotlin-db6b2cc11ab4f98ee39f1cadf5fbb1c3c2881021.tar.gz |
rra/ilgonmic/kt-51973
[JS IR] Add non overridden property and method insode exported class
[JS IR] Add method into exported interface in test
[JS IR] Add interface properties cases to all file export test
[JS IR] Fix usage of isExported inside IrJsUtils
Co-authored-by: Anton Bannykh <Anton.Bannykh@jetbrains.com>
Merge-request: KT-MR-6087
Merged-by: Ilya Goncharov <Ilya.Goncharov@jetbrains.com>
^KT-51973 fixed
(cherry picked from commit 90ee8662dab5face7381da88c8b20bcd57ef573f)
Co-authored-by: Anton Bannykh <Anton.Bannykh@jetbrains.com>
Merge-request: KT-MR-6266
Merged-by: Ilya Goncharov <Ilya.Goncharov@jetbrains.com>
5 files changed, 152 insertions, 15 deletions
diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt index 6c4b708582d..abf43464ce6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt @@ -668,7 +668,7 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont } fun IrOverridableDeclaration<*>.isAllowedFakeOverriddenDeclaration(context: JsIrBackendContext): Boolean { - if (this.resolveFakeOverride(allowAbstract = true)?.parentClassOrNull.isExportedInterface()) { + if (this.resolveFakeOverride(allowAbstract = true)?.parentClassOrNull.isExportedInterface(context)) { return true } 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 113e2ee887c..bf2e19b24d2 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 @@ -135,6 +135,8 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo val overriddenSymbols = property.getter?.overriddenSymbols.orEmpty() + val backendContext = context.staticContext.backendContext + // Don't generate `defineProperty` if the property overrides a property from an exported class, // because we've already generated `defineProperty` for the base class property. // In other words, we only want to generate `defineProperty` once for each property. @@ -143,7 +145,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo // 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.isDefinedInsideExportedInterface() } - && !overriddenSymbols.any { it.owner.parentClassOrNull.isExportedClass() } + && !overriddenSymbols.any { it.owner.parentClassOrNull.isExportedClass(backendContext) } val getterOverridesExternal = property.getter?.overridesExternal() == true val overriddenExportedGetter = !property.getter?.overriddenSymbols.isNullOrEmpty() && @@ -214,7 +216,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo } private fun IrSimpleFunction.isDefinedInsideExportedInterface(): Boolean { - return (!isFakeOverride && parentClassOrNull.isExportedInterface()) || + return (!isFakeOverride && parentClassOrNull.isExportedInterface(context.staticContext.backendContext)) || overriddenSymbols.any { it.owner.isDefinedInsideExportedInterface() } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt index 31e1f913692..354ef1113ec 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt @@ -124,7 +124,7 @@ fun translateCall( val property = function.correspondingPropertySymbol?.owner if ( property != null && - (property.isEffectivelyExternal() || property.isExportedMember()) + (property.isEffectivelyExternal() || property.isExportedMember(context.staticContext.backendContext)) ) { if (function.overriddenSymbols.isEmpty() || function.overriddenStableProperty(context.staticContext.backendContext)) { val propertyName = context.getNameForProperty(property) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt index 6d317617d35..0e8a5c2d8c0 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.ir.backend.js.utils import org.jetbrains.kotlin.descriptors.isClass import org.jetbrains.kotlin.descriptors.isInterface +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext +import org.jetbrains.kotlin.ir.backend.js.export.isExported import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithVisibility @@ -14,18 +16,15 @@ import org.jetbrains.kotlin.ir.expressions.IrReturn import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol import org.jetbrains.kotlin.ir.util.parentClassOrNull -fun IrDeclaration.isExportedMember() = +fun IrDeclaration.isExportedMember(context: JsIrBackendContext) = (this is IrDeclarationWithVisibility && visibility.isPublicAPI) && - parentClassOrNull.let { it is IrClass && it.isJsExport() } + parentClassOrNull?.isExported(context) == true -fun IrDeclaration?.isExportedClass() = - this is IrClass && kind.isClass && isJsExport() +fun IrDeclaration?.isExportedClass(context: JsIrBackendContext) = + this is IrClass && kind.isClass && isExported(context) -fun IrDeclaration?.isExportedInterface() = - this is IrClass && kind.isInterface && isJsExport() - -fun IrDeclaration.isExportedInterfaceMember() = - parentClassOrNull.isExportedInterface() +fun IrDeclaration?.isExportedInterface(context: JsIrBackendContext) = + this is IrClass && kind.isInterface && isExported(context) fun IrReturn.isTheLastReturnStatementIn(target: IrReturnableBlockSymbol): Boolean { return target.owner.statements.lastOrNull() === this diff --git a/js/js.translator/testData/box/export/exportAllFile.kt b/js/js.translator/testData/box/export/exportAllFile.kt index 6224acf1cdf..d82c36d9f9f 100644 --- a/js/js.translator/testData/box/export/exportAllFile.kt +++ b/js/js.translator/testData/box/export/exportAllFile.kt @@ -9,15 +9,151 @@ abstract class A { abstract fun foo(k: String): String + + abstract val bar: String + + abstract val baz: String + + abstract var bay: String + + abstract var bat: String } -class B : A() { +open class B : A() { override fun foo(k: String): String { return "O" + k } + + override val bar: String = "bar" + + override val baz: String + get() = "baz" + + override var bay: String = "bay" + + private var _bat: String = "bat" + + override var bat: String + get() = _bat + set(value) { + _bat = value + } +} + +interface I { + val gap: String + + val hap: String + + var baz: String + + var bay: String + + fun foo(): String +} + +open class C : I { + override val gap: String = "gap" + + override val hap: String + get() = "hap" + + override var bay: String = "bay" + + private var _baz = "baz" + + override var baz: String + get() = _baz + set(value) { + _baz = value + } + + val koo: String = "koo" + + override fun foo(): String { + return "foo" + } + + fun foi() = "foi" +} + +fun topFoo(a: A): String { + if (a.bar != "bar3") return "fail" + if (a.baz != "baz3") return "fail" + return "OK" +} + +fun topBar(c: C): String { + if (c.bay != "bay3") return "fail" + if (c.baz != "baz3") return "fail" + return "OK" } // FILE: test.js + function box() { - return new this["export_all_file"].B().foo("K"); + var exportObject = this["export_all_file"] + + function H() { + } + + H.prototype = Object.create(exportObject.B.prototype); + H.prototype.constructor = H; + Object.defineProperty(H.prototype, "bar", { + get: function() { + return "bar3" + } + }) + + Object.defineProperty(H.prototype, "baz", { + get: function() { + return "baz3" + } + }) + + function J() { + } + + J.prototype = Object.create(exportObject.C.prototype); + J.prototype.constructor = J; + Object.defineProperty(J.prototype, "bay", { + get: function() { + return "bay3" + } + }) + + Object.defineProperty(J.prototype, "baz", { + get: function() { + return "baz3" + } + }) + + var b = new exportObject.B() + if (b.foo("K") != "OK") return "fail 1"; + if (b.bar != "bar") return "fail 2" + if (b.baz != "baz") return "fail 3" + if (b.bay != "bay") return "fail 4" + b.bay = "bay2" + if (b.bay != "bay2") return "fail 5" + if (b.bat != "bat") return "fail6" + b.bat = "bat2" + if (b.bat != "bat2") return "fail7" + + var c = new exportObject.C() + if (c.gap != "gap") return "fail 8" + if (c.hap != "hap") return "fail 9" + if (c.bay != "bay") return "fail 10" + c.bay = c.bay + "2" + if (c.bay != "bay2") return "fail 11" + if (c.baz != "baz") return "fail 12" + c.baz = c.baz + "2" + if (c.baz != "baz2") return "fail 13" + if (c.foo() != "foo") return "fail 14" + if (c.koo != "koo") return "fail 15" + if (c.foi() != "foi") return "fail 16" + + if (exportObject.topFoo(new H()) != "OK") return "fail 17" + if (exportObject.topBar(new J()) != "OK") return "fail 18" + + return "OK" }
\ No newline at end of file |