[JS IR BE] Fix object instance reference
* set it in primary constructor prior to constructor body
This commit is contained in:
+5
-2
@@ -6,19 +6,22 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.util.isObject
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsFunction
|
import org.jetbrains.kotlin.js.backend.ast.JsFunction
|
||||||
|
|
||||||
open class IrFunctionToJsTransformer : BaseIrElementToJsNodeTransformer<JsFunction, JsGenerationContext> {
|
open class IrFunctionToJsTransformer : BaseIrElementToJsNodeTransformer<JsFunction, JsGenerationContext> {
|
||||||
override fun visitSimpleFunction(declaration: IrSimpleFunction, context: JsGenerationContext): JsFunction {
|
override fun visitSimpleFunction(declaration: IrSimpleFunction, context: JsGenerationContext): JsFunction {
|
||||||
val funcName = context.getNameForSymbol(declaration.symbol)
|
val funcName = context.getNameForSymbol(declaration.symbol)
|
||||||
return translateFunction(declaration, funcName, context)
|
return translateFunction(declaration, funcName, false, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitConstructor(declaration: IrConstructor, context: JsGenerationContext): JsFunction {
|
override fun visitConstructor(declaration: IrConstructor, context: JsGenerationContext): JsFunction {
|
||||||
assert(declaration.isPrimary)
|
assert(declaration.isPrimary)
|
||||||
val funcName = context.getNameForSymbol(declaration.symbol)
|
val funcName = context.getNameForSymbol(declaration.symbol)
|
||||||
return translateFunction(declaration, funcName, context)
|
val constructedClass = declaration.parent as IrClass
|
||||||
|
return translateFunction(declaration, funcName, constructedClass.isObject, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -100,7 +100,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun maybeGenerateObjectInstance(): List<JsStatement> {
|
private fun maybeGenerateObjectInstance(): List<JsStatement> {
|
||||||
val instanceVarName = "${className.ident}_instance"
|
val instanceVarName = className.objectInstanceName()
|
||||||
val getInstanceFunName = "${className.ident}_getInstance"
|
val getInstanceFunName = "${className.ident}_getInstance"
|
||||||
val jsVarNode = context.currentScope.declareName(instanceVarName)
|
val jsVarNode = context.currentScope.declareName(instanceVarName)
|
||||||
val varStmt = JsVars(JsVars.JsVar(jsVarNode))
|
val varStmt = JsVars(JsVars.JsVar(jsVarNode))
|
||||||
|
|||||||
+12
-3
@@ -35,12 +35,19 @@ fun jsAssignment(left: JsExpression, right: JsExpression) = JsBinaryOperation(Js
|
|||||||
|
|
||||||
fun prototypeOf(classNameRef: JsExpression) = JsNameRef(Namer.PROTOTYPE_NAME, classNameRef)
|
fun prototypeOf(classNameRef: JsExpression) = JsNameRef(Namer.PROTOTYPE_NAME, classNameRef)
|
||||||
|
|
||||||
fun translateFunction(declaration: IrFunction, name: JsName?, context: JsGenerationContext): JsFunction {
|
fun translateFunction(declaration: IrFunction, name: JsName?, isObjectConstructor: Boolean, context: JsGenerationContext): JsFunction {
|
||||||
val functionScope = JsFunctionScope(context.currentScope, "scope for ${name ?: "annon"}")
|
val functionScope = JsFunctionScope(context.currentScope, "scope for ${name ?: "annon"}")
|
||||||
val functionContext = context.newDeclaration(functionScope, declaration)
|
val functionContext = context.newDeclaration(functionScope, declaration)
|
||||||
val functionParams = declaration.valueParameters.map { functionContext.getNameForSymbol(it.symbol) }
|
val functionParams = declaration.valueParameters.map { functionContext.getNameForSymbol(it.symbol) }
|
||||||
val body = declaration.body?.accept(IrElementToJsStatementTransformer(), functionContext) as? JsBlock ?: JsBlock()
|
val body = declaration.body?.accept(IrElementToJsStatementTransformer(), functionContext) as? JsBlock ?: JsBlock()
|
||||||
val function = JsFunction(functionScope, body, "member function ${name ?: "annon"}")
|
|
||||||
|
val functionBody = if (isObjectConstructor) {
|
||||||
|
val instanceName = context.currentScope.declareName(name!!.objectInstanceName())
|
||||||
|
val assignObject = jsAssignment(JsNameRef(instanceName), JsThisRef())
|
||||||
|
JsBlock(assignObject.makeStmt(), body)
|
||||||
|
} else body
|
||||||
|
|
||||||
|
val function = JsFunction(functionScope, functionBody, "member function ${name ?: "annon"}")
|
||||||
|
|
||||||
function.name = name
|
function.name = name
|
||||||
|
|
||||||
@@ -74,4 +81,6 @@ fun translateCallArguments(expression: IrMemberAccessExpression, context: JsGene
|
|||||||
|
|
||||||
val IrFunction.isStatic: Boolean get() = this.dispatchReceiverParameter == null
|
val IrFunction.isStatic: Boolean get() = this.dispatchReceiverParameter == null
|
||||||
|
|
||||||
fun JsStatement.asBlock() = this as? JsBlock ?: JsBlock(this)
|
fun JsStatement.asBlock() = this as? JsBlock ?: JsBlock(this)
|
||||||
|
|
||||||
|
fun JsName.objectInstanceName() = "${ident}_instance"
|
||||||
Reference in New Issue
Block a user