[JS] Support secondary constructors in JsExport

This commit is contained in:
Svyatoslav Kuzmich
2020-05-20 18:00:03 +03:00
parent f128e5222a
commit 695d383ed1
14 changed files with 233 additions and 17 deletions
@@ -5,7 +5,9 @@
package org.jetbrains.kotlin.ir.backend.js.export
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
sealed class ExportedDeclaration
@@ -56,7 +58,7 @@ class ExportedClass(
val superInterfaces: List<ExportedType> = emptyList(),
val typeParameters: List<String>,
val members: List<ExportedDeclaration>,
val statics: List<ExportedDeclaration>,
val nestedClasses: List<ExportedClass>,
val ir: IrClass
) : ExportedDeclaration()
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.ir.backend.js.export
import org.jetbrains.kotlin.backend.common.ir.isExpect
import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
@@ -23,8 +22,6 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.utils.addIfNotNull
class ExportModelGenerator(val context: JsIrBackendContext) {
@@ -139,14 +136,14 @@ class ExportModelGenerator(val context: JsIrBackendContext) {
private fun exportClass(
klass: IrClass
): ExportedDeclaration? {
): ExportedClass? {
when (val exportability = classExportability(klass)) {
is Exportability.Prohibited -> return ErrorDeclaration(exportability.reason)
is Exportability.Prohibited -> return error(exportability.reason)
is Exportability.NotNeeded -> return null
}
val members = mutableListOf<ExportedDeclaration>()
val statics = mutableListOf<ExportedDeclaration>()
val nestedClasses = mutableListOf<ExportedClass>()
for (declaration in klass.declarations) {
val candidate = getExportCandidate(declaration) ?: continue
@@ -163,7 +160,7 @@ class ExportModelGenerator(val context: JsIrBackendContext) {
members.addIfNotNull(exportProperty(candidate))
is IrClass ->
statics.addIfNotNull(exportClass(candidate))
nestedClasses.addIfNotNull(exportClass(candidate))
is IrField -> {
assert(candidate.correspondingPropertySymbol != null) {
@@ -198,7 +195,7 @@ class ExportModelGenerator(val context: JsIrBackendContext) {
superInterfaces = superInterfaces,
typeParameters = typeParameters,
members = members,
statics = statics,
nestedClasses = nestedClasses,
ir = klass
)
}
@@ -413,4 +410,4 @@ val strictModeReservedWords = setOf(
"yield"
)
private val allReservedWords = reservedWords + strictModeReservedWords
private val allReservedWords = reservedWords + strictModeReservedWords
@@ -8,7 +8,8 @@ package org.jetbrains.kotlin.ir.backend.js.export
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsAstUtils
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.defineProperty
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.jsAssignment
import org.jetbrains.kotlin.ir.backend.js.utils.*
import org.jetbrains.kotlin.ir.backend.js.utils.NameTable
import org.jetbrains.kotlin.ir.backend.js.utils.NameTables
import org.jetbrains.kotlin.js.backend.ast.*
@@ -85,7 +86,12 @@ class ExportModelToJsStatements(
)
)
).makeStmt()
val staticsExport = declaration.statics.flatMap { generateDeclarationExport(it, newNameSpace) }
val staticFunctions = declaration.members.filter { it is ExportedFunction && it.isStatic }
val staticsExport = (staticFunctions + declaration.nestedClasses)
.flatMap { generateDeclarationExport(it, newNameSpace) }
listOf(klassExport) + staticsExport
}
}
@@ -75,7 +75,7 @@ fun ExportedDeclaration.toTypeScript(indent: String): String = indent + when (th
val modifiers = if (isAbstract && !isInterface) "abstract " else ""
val klassExport = "$modifiers$keyword $name$renderedTypeParameters$superClassClause$superInterfacesClause {\n$membersString$indent}"
val staticsExport = if (statics.isNotEmpty()) "\n" + ExportedNamespace(name, statics).toTypeScript(indent) else ""
val staticsExport = if (nestedClasses.isNotEmpty()) "\n" + ExportedNamespace(name, nestedClasses).toTypeScript(indent) else ""
klassExport + staticsExport
}
}
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.utils.getJsName
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
@@ -176,9 +177,10 @@ private fun buildFactoryDeclaration(constructor: IrConstructor, irClass: IrClass
Modality.FINAL,
constructor.isInline,
constructor.isExternal
).also {
it.copyTypeParametersFrom(constructor.parentAsClass)
it.valueParameters += constructor.valueParameters.map { p -> p.copyTo(it) }
).also { factory ->
factory.copyTypeParametersFrom(constructor.parentAsClass)
factory.valueParameters += constructor.valueParameters.map { p -> p.copyTo(factory) }
factory.annotations = constructor.annotations
}
}