[K/JS] Fix Companion object overriding problem inside TypeScript Definitions ^JBAI-680 Fixed

This commit is contained in:
Artem Kobzar
2024-02-29 17:48:24 +00:00
committed by Space Team
parent f1ed07d3bb
commit 1c2570ed7e
6 changed files with 63 additions and 6 deletions
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.export
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
import org.jetbrains.kotlin.ir.backend.js.lower.isEs6PrimaryConstructorReplacement
import org.jetbrains.kotlin.ir.backend.js.utils.JsAnnotations
import org.jetbrains.kotlin.ir.backend.js.utils.getFqNameWithJsNameWhenAvailable
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
import org.jetbrains.kotlin.ir.backend.js.utils.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.util.*
@@ -323,7 +320,13 @@ class ExportModelToTsDeclarations {
val realNestedClasses = nonInnerClasses + innerClasses.map { it.withProtectedConstructors() }
val tsIgnoreForPrivateConstructorInheritance = if (hasSuperClassWithPrivateConstructor()) {
tsIgnore("extends class with private primary constructor") + "\n$indent"
} else ""
} else null
val tsIgnoreForCompanionInheritance = if (hasSuperClassAndCompanion()) {
tsIgnore("https://github.com/microsoft/TypeScript/issues/4628") + "\n$indent"
} else null
val tsIgnore = tsIgnoreForPrivateConstructorInheritance ?: tsIgnoreForCompanionInheritance ?: ""
val klassExport =
"$prefix$modifiers$keyword $name$renderedTypeParameters$superClassClause$superInterfacesClause {\n$bodyString}"
@@ -338,7 +341,7 @@ class ExportModelToTsDeclarations {
)
} else ""
return if (name.isValidES5Identifier()) tsIgnoreForPrivateConstructorInheritance + klassExport + staticsExport + interfaceCompanionsString else ""
return if (name.isValidES5Identifier()) tsIgnore + klassExport + staticsExport + interfaceCompanionsString else ""
}
private fun ExportedRegularClass.hasSuperClassWithPrivateConstructor(): Boolean {
@@ -347,6 +350,11 @@ class ExportModelToTsDeclarations {
return exportedConstructor?.let { it.visibility == DescriptorVisibilities.PRIVATE || it.hasAnnotation(JsAnnotations.jsExportIgnoreFqn) } ?: true
}
private fun ExportedRegularClass.hasSuperClassAndCompanion(): Boolean {
val superClass = superClasses.firstIsInstanceOrNull<ExportedType.ClassType>()?.ir?.takeIf { !it.isObject }
return superClass != null && ir.companionObject()?.isJsExportIgnore() == false
}
private fun List<ExportedType>.toExtendsClause(indent: String): String {
if (isEmpty()) return ""
@@ -41,6 +41,18 @@ declare namespace JS_TESTS {
function createNested1(): typeof foo.Parent.Nested1;
function createNested2(): foo.Parent.Nested1.Nested2;
function createNested3(): foo.Parent.Nested1.Nested2.Companion.Nested3;
abstract class BaseWithCompanion {
constructor();
static get Companion(): {
get any(): string;
};
}
/* @ts-ignore: https://github.com/microsoft/TypeScript/issues/4628 */
class ChildWithCompanion extends foo.BaseWithCompanion {
constructor();
static get Companion(): {
};
}
}
namespace _objects_ {
const foo$Parent$Nested1: {
@@ -63,4 +63,15 @@ fun createNested2(): Parent.Nested1.Nested2 {
fun createNested3(): Parent.Nested1.Nested2.Companion.Nested3 {
return Parent.Nested1.Nested2.Companion.Nested3()
}
abstract class BaseWithCompanion {
companion object {
val any: String = "ANYTHING"
}
}
class ChildWithCompanion : BaseWithCompanion() {
companion object
}
@@ -7,6 +7,8 @@ import createNested1 = JS_TESTS.foo.createNested1;
import createNested2 = JS_TESTS.foo.createNested2;
import createNested3 = JS_TESTS.foo.createNested3;
import WithSimpleObjectInside = JS_TESTS.foo.WithSimpleObjectInside;
import BaseWithCompanion = JS_TESTS.foo.BaseWithCompanion;
import ChildWithCompanion = JS_TESTS.foo.ChildWithCompanion;
function assert(condition: boolean) {
if (!condition) {
@@ -34,5 +36,6 @@ function box(): string {
assert(WithSimpleObjectInside.value === "WithSimpleObjectInside");
assert(WithSimpleObjectInside.SimpleObject.value === "SimpleObject");
return "OK";
}
@@ -41,6 +41,18 @@ declare namespace JS_TESTS {
function createNested1(): typeof foo.Parent.Nested1;
function createNested2(): foo.Parent.Nested1.Nested2;
function createNested3(): foo.Parent.Nested1.Nested2.Companion.Nested3;
abstract class BaseWithCompanion {
constructor();
static get Companion(): {
get any(): string;
};
}
/* @ts-ignore: https://github.com/microsoft/TypeScript/issues/4628 */
class ChildWithCompanion extends foo.BaseWithCompanion {
constructor();
static get Companion(): {
};
}
}
namespace _objects_ {
const foo$Parent$Nested1: {
@@ -59,4 +59,15 @@ fun createNested2(): Parent.Nested1.Nested2 {
@JsExport
fun createNested3(): Parent.Nested1.Nested2.Companion.Nested3 {
return Parent.Nested1.Nested2.Companion.Nested3()
}
@JsExport
abstract class BaseWithCompanion {
companion object {
val any: String = "ANYTHING"
}
}
@JsExport
class ChildWithCompanion : BaseWithCompanion() {
companion object
}