[JS IR] .d.ts generation for module systems
Support .d.ts generation for UMD, AMD, CommonJS module kinds in addition to existing "plain" module kind.
This commit is contained in:
+25
-9
@@ -6,23 +6,39 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.export
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
|
||||
// TODO: Support module kinds other than plain
|
||||
|
||||
fun ExportedModule.toTypeScript(): String {
|
||||
val prefix = " type Nullable<T> = T | null | undefined\n"
|
||||
val body = declarations.joinToString("\n") { it.toTypeScript(" ") }
|
||||
return "declare namespace ${sanitizeName(name)} {\n$prefix$body\n}\n"
|
||||
val indent = if (moduleKind == ModuleKind.PLAIN) " " else ""
|
||||
val types = "${indent}type Nullable<T> = T | null | undefined\n"
|
||||
|
||||
val declarationsDts =
|
||||
types + declarations.joinToString("\n") {
|
||||
it.toTypeScript(
|
||||
indent = indent,
|
||||
prefix = if (moduleKind == ModuleKind.PLAIN) "" else "export "
|
||||
)
|
||||
}
|
||||
|
||||
val namespaceName = sanitizeName(name)
|
||||
|
||||
return when (moduleKind) {
|
||||
ModuleKind.PLAIN -> "declare namespace $namespaceName {\n$declarationsDts\n}\n"
|
||||
ModuleKind.AMD, ModuleKind.COMMON_JS -> declarationsDts
|
||||
ModuleKind.UMD -> "$declarationsDts\nexport as namespace $namespaceName;"
|
||||
}
|
||||
}
|
||||
|
||||
fun List<ExportedDeclaration>.toTypeScript(indent: String): String =
|
||||
joinToString("") { it.toTypeScript(indent) + "\n" }
|
||||
|
||||
fun ExportedDeclaration.toTypeScript(indent: String): String = indent + when (this) {
|
||||
fun ExportedDeclaration.toTypeScript(indent: String, prefix: String = ""): String = indent + when (this) {
|
||||
is ErrorDeclaration -> "/* ErrorDeclaration: $message */"
|
||||
|
||||
is ExportedNamespace ->
|
||||
"namespace $name {\n" + declarations.toTypeScript("$indent ") + "$indent}"
|
||||
"${prefix}namespace $name {\n" + declarations.toTypeScript("$indent ") + "$indent}"
|
||||
|
||||
is ExportedFunction -> {
|
||||
val keyword: String = when {
|
||||
@@ -44,7 +60,7 @@ fun ExportedDeclaration.toTypeScript(indent: String): String = indent + when (th
|
||||
|
||||
val renderedReturnType = returnType.toTypeScript()
|
||||
|
||||
"$keyword$name$renderedTypeParameters($renderedParameters): $renderedReturnType;"
|
||||
"${prefix}$keyword$name$renderedTypeParameters($renderedParameters): $renderedReturnType;"
|
||||
}
|
||||
is ExportedConstructor ->
|
||||
"constructor(${parameters.joinToString(", ") { it.toTypeScript() }});"
|
||||
@@ -54,7 +70,7 @@ fun ExportedDeclaration.toTypeScript(indent: String): String = indent + when (th
|
||||
isMember -> (if (isAbstract) "abstract " else "") + (if (!mutable) "readonly " else "")
|
||||
else -> if (mutable) "let " else "const "
|
||||
}
|
||||
keyword + name + ": " + type.toTypeScript() + ";"
|
||||
prefix + keyword + name + ": " + type.toTypeScript() + ";"
|
||||
}
|
||||
|
||||
is ExportedClass -> {
|
||||
@@ -85,8 +101,8 @@ fun ExportedDeclaration.toTypeScript(indent: String): String = indent + when (th
|
||||
|
||||
val bodyString = privateCtorString + membersString + indent
|
||||
|
||||
val klassExport = "$modifiers$keyword $name$renderedTypeParameters$superClassClause$superInterfacesClause {\n$bodyString}"
|
||||
val staticsExport = if (nestedClasses.isNotEmpty()) "\n" + ExportedNamespace(name, nestedClasses).toTypeScript(indent) else ""
|
||||
val klassExport = "$prefix$modifiers$keyword $name$renderedTypeParameters$superClassClause$superInterfacesClause {\n$bodyString}"
|
||||
val staticsExport = if (nestedClasses.isNotEmpty()) "\n" + ExportedNamespace(name, nestedClasses).toTypeScript(indent, prefix) else ""
|
||||
klassExport + staticsExport
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user