[K/Wasm] Add simple TypeScript definitions generating ^KT-65009 Fixed

This commit is contained in:
Artem Kobzar
2024-01-16 11:10:27 +00:00
committed by Space Team
parent baa0748375
commit a55c65e3e2
35 changed files with 1176 additions and 32 deletions
@@ -27,6 +27,7 @@ data class ExportedModule(
class ExportedNamespace(
val name: String,
val declarations: List<ExportedDeclaration>,
val isPrivate: Boolean = false
) : ExportedDeclaration()
data class ExportedFunction(
@@ -100,7 +101,7 @@ data class ExportedObject(
override val members: List<ExportedDeclaration>,
override val nestedClasses: List<ExportedClass>,
override val ir: IrClass,
val irGetter: IrSimpleFunction
val irGetter: IrSimpleFunction? = null
) : ExportedClass()
class ExportedParameter(
@@ -113,6 +114,7 @@ sealed class ExportedType {
sealed class Primitive(val typescript: kotlin.String) : ExportedType() {
object Boolean : Primitive("boolean")
object Number : Primitive("number")
object BigInt : Primitive("bigint")
object ByteArray : Primitive("Int8Array")
object ShortArray : Primitive("Int16Array")
object IntArray : Primitive("Int32Array")
@@ -121,11 +123,14 @@ sealed class ExportedType {
object String : Primitive("string")
object Throwable : Primitive("Error")
object Any : Primitive("any")
object Unknown : Primitive("unknown")
object Undefined : Primitive("undefined")
object Unit : Primitive("void")
object Nothing : Primitive("never")
object UniqueSymbol : Primitive("unique symbol")
object Unknown : Primitive("unknown") {
override fun withNullability(nullable: kotlin.Boolean) =
if (nullable) this else NonNullable(this)
}
}
sealed class LiteralType<T : Any>(val value: T) : ExportedType() {
@@ -142,6 +147,7 @@ sealed class ExportedType {
class ClassType(val name: String, val arguments: List<ExportedType>, val ir: IrClass) : ExportedType()
class TypeParameter(val name: String, val constraint: ExportedType? = null) : ExportedType()
class Nullable(val baseType: ExportedType) : ExportedType()
class NonNullable(val baseType: ExportedType) : ExportedType()
class ErrorType(val comment: String) : ExportedType()
class TypeOf(val name: String) : ExportedType()
@@ -524,7 +524,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
return ExportedType.ErrorType("UnknownType ${type.render()}")
}
private fun exportTypeParameter(typeParameter: IrTypeParameter): ExportedType.TypeParameter {
fun exportTypeParameter(typeParameter: IrTypeParameter): ExportedType.TypeParameter {
val constraint = typeParameter.superTypes.asSequence()
.filter { it != context.irBuiltIns.anyNType }
.map {
@@ -550,12 +550,6 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
)
}
private fun ExportedDeclaration.withAttributesFor(declaration: IrDeclaration): ExportedDeclaration {
declaration.getDeprecated()?.let { attributes.add(ExportedAttribute.DeprecatedAttribute(it)) }
return this
}
private val currentlyProcessedTypes = hashSetOf<IrType>()
private fun exportType(type: IrType, shouldCalculateExportedSupertypeForImplicit: Boolean = true): ExportedType {
@@ -639,13 +633,6 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
.also { currentlyProcessedTypes.remove(type) }
}
private fun IrDeclarationWithName.getExportedIdentifier(): String =
with(getJsNameOrKotlinName()) {
if (isSpecial)
error("Cannot export special name: ${name.asString()} for declaration $fqNameWhenAvailable")
else identifier
}
private fun functionExportability(function: IrSimpleFunction): Exportability {
if (function.isInline && function.typeParameters.any { it.isReified })
return Exportability.Prohibited("Inline reified function")
@@ -811,7 +798,7 @@ fun IrDeclaration.isExportedImplicitlyOrExplicitly(context: JsIrBackendContext):
return shouldDeclarationBeExportedImplicitlyOrExplicitly(candidate, context)
}
private fun DescriptorVisibility.toExportedVisibility() =
fun DescriptorVisibility.toExportedVisibility() =
when (this) {
DescriptorVisibilities.PROTECTED -> ExportedVisibility.PROTECTED
else -> ExportedVisibility.DEFAULT
@@ -870,3 +857,17 @@ val strictModeReservedWords = setOf(
)
private val allReservedWords = reservedWords + strictModeReservedWords
fun ExportedDeclaration.withAttributesFor(declaration: IrDeclaration): ExportedDeclaration {
declaration.getDeprecated()?.let { attributes.add(ExportedAttribute.DeprecatedAttribute(it)) }
return this
}
fun IrDeclarationWithName.getExportedIdentifier(): String =
with(getJsNameOrKotlinName()) {
if (isSpecial)
error("Cannot export special name: ${name.asString()} for declaration $fqNameWhenAvailable")
else identifier
}
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.util.companionObject
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isObject
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
@@ -140,7 +141,10 @@ class ExportModelToJsStatements(
defineProperty(
namespace,
declaration.name,
staticContext.getNameForStaticDeclaration(declaration.irGetter).makeRef(),
staticContext.getNameForStaticDeclaration(
declaration.irGetter
?: error("Expect to have an object getter in its export model, but ${declaration.ir.fqNameWhenAvailable ?: declaration.name} doesn't have it")
).makeRef(),
null,
staticContext
).makeStmt()
@@ -8,7 +8,6 @@ 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.lower.isSyntheticPrimaryConstructor
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
@@ -25,6 +24,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import org.jetbrains.kotlin.utils.findIsInstanceAnd
private const val NonNullable = "NonNullable"
private const val Nullable = "Nullable"
private const val objects = "_objects_"
private const val declare = "declare "
@@ -127,7 +127,7 @@ class ExportModelToTsDeclarations {
}
private fun ExportedNamespace.generateTypeScriptString(indent: String, prefix: String): String {
return "${prefix}namespace $name {\n" + declarations.toTypeScript("$indent ") + "$indent}"
return "${prefix.takeIf { !isPrivate } ?: "declare "}namespace $name {\n" + declarations.toTypeScript("$indent ") + "$indent}"
}
private fun ExportedConstructor.generateTypeScriptString(indent: String): String {
@@ -445,6 +445,7 @@ class ExportModelToTsDeclarations {
is ExportedType.ErrorType -> if (isInCommentContext) comment else "any /*$comment*/"
is ExportedType.Nullable -> "$Nullable<" + baseType.toTypeScript(indent, isInCommentContext) + ">"
is ExportedType.NonNullable -> "$NonNullable<" + baseType.toTypeScript(indent, isInCommentContext) + ">"
is ExportedType.InlineInterfaceType -> {
members.joinToString(prefix = "{\n", postfix = "$indent}", separator = "") { it.toTypeScript("$indent ") + "\n" }
}