Implement object class in JS BE
This commit is contained in:
+11
-2
@@ -73,10 +73,19 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
override fun visitGetValue(expression: IrGetValue, context: JsGenerationContext): JsExpression =
|
||||
context.getNameForSymbol(expression.symbol).makeRef()
|
||||
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue, data: JsGenerationContext): JsExpression {
|
||||
TODO()
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue, context: JsGenerationContext) = when (expression.symbol.kind) {
|
||||
ClassKind.OBJECT -> {
|
||||
if (expression.type.isUnit()) JsNullLiteral()
|
||||
else {
|
||||
val className = context.getNameForSymbol(expression.symbol)
|
||||
val getInstanceName = className.ident + "_getInstance"
|
||||
JsInvocation(JsNameRef(getInstanceName))
|
||||
}
|
||||
}
|
||||
else -> TODO()
|
||||
}
|
||||
|
||||
|
||||
override fun visitSetField(expression: IrSetField, context: JsGenerationContext): JsExpression {
|
||||
val fieldName = context.getNameForSymbol(expression.symbol)
|
||||
val dest = JsNameRef(fieldName, expression.receiver?.accept(this, context))
|
||||
|
||||
+24
@@ -53,9 +53,33 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
}
|
||||
|
||||
classBlock.statements += generateClassMetadata()
|
||||
irClass.onlyIf({ kind == ClassKind.OBJECT }) { classBlock.statements += maybeGenerateObjectInstance() }
|
||||
return classBlock
|
||||
}
|
||||
|
||||
private fun maybeGenerateObjectInstance(): List<JsStatement> {
|
||||
val instanceVarName = "${className.ident}_instance"
|
||||
val getInstanceFunName = "${className.ident}_getInstance"
|
||||
val jsVarNode = context.currentScope.declareName(instanceVarName)
|
||||
val varStmt = JsVars(JsVars.JsVar(jsVarNode, JsNullLiteral()))
|
||||
val function = generateGetInstanceFunction(jsVarNode, getInstanceFunName)
|
||||
return listOf(varStmt, function.makeStmt())
|
||||
}
|
||||
|
||||
private fun generateGetInstanceFunction(instanceVar: JsName, instanceFunName: String): JsFunction {
|
||||
val functionBody = JsBlock()
|
||||
val func = JsFunction(JsFunctionScope(context.currentScope, "getInstance for ${irClass.name} object"), functionBody, "getInstance")
|
||||
func.name = context.currentScope.declareName(instanceFunName)
|
||||
|
||||
functionBody.statements += JsIf(
|
||||
JsBinaryOperation(JsBinaryOperator.REF_EQ, instanceVar.makeRef(), JsNullLiteral()),
|
||||
jsAssignment(instanceVar.makeRef(), JsNew(classNameRef)).makeStmt()
|
||||
)
|
||||
functionBody.statements += JsReturn(instanceVar.makeRef())
|
||||
|
||||
return func
|
||||
}
|
||||
|
||||
private fun maybeGeneratePrimaryConstructor() {
|
||||
if (!irClass.declarations.any { it is IrConstructor }) {
|
||||
val func = JsFunction(JsFunctionScope(context.currentScope, "Ctor for ${irClass.name}"), JsBlock(), "Ctor for ${irClass.name}")
|
||||
|
||||
Reference in New Issue
Block a user