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 =
|
override fun visitGetValue(expression: IrGetValue, context: JsGenerationContext): JsExpression =
|
||||||
context.getNameForSymbol(expression.symbol).makeRef()
|
context.getNameForSymbol(expression.symbol).makeRef()
|
||||||
|
|
||||||
override fun visitGetObjectValue(expression: IrGetObjectValue, data: JsGenerationContext): JsExpression {
|
override fun visitGetObjectValue(expression: IrGetObjectValue, context: JsGenerationContext) = when (expression.symbol.kind) {
|
||||||
TODO()
|
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 {
|
override fun visitSetField(expression: IrSetField, context: JsGenerationContext): JsExpression {
|
||||||
val fieldName = context.getNameForSymbol(expression.symbol)
|
val fieldName = context.getNameForSymbol(expression.symbol)
|
||||||
val dest = JsNameRef(fieldName, expression.receiver?.accept(this, context))
|
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()
|
classBlock.statements += generateClassMetadata()
|
||||||
|
irClass.onlyIf({ kind == ClassKind.OBJECT }) { classBlock.statements += maybeGenerateObjectInstance() }
|
||||||
return classBlock
|
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() {
|
private fun maybeGeneratePrimaryConstructor() {
|
||||||
if (!irClass.declarations.any { it is IrConstructor }) {
|
if (!irClass.declarations.any { it is IrConstructor }) {
|
||||||
val func = JsFunction(JsFunctionScope(context.currentScope, "Ctor for ${irClass.name}"), JsBlock(), "Ctor for ${irClass.name}")
|
val func = JsFunction(JsFunctionScope(context.currentScope, "Ctor for ${irClass.name}"), JsBlock(), "Ctor for ${irClass.name}")
|
||||||
|
|||||||
Reference in New Issue
Block a user