[JS IR BE] Support codegen for external objects and properties
This commit is contained in:
+20
-2
@@ -79,9 +79,14 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue, context: JsGenerationContext) = when (expression.symbol.owner.kind) {
|
||||
ClassKind.OBJECT -> {
|
||||
val obj = expression.symbol.owner
|
||||
val className = context.getNameForSymbol(expression.symbol)
|
||||
val getInstanceName = className.ident + "_getInstance"
|
||||
JsInvocation(JsNameRef(getInstanceName))
|
||||
if (obj.isEffectivelyExternal()) {
|
||||
className.makeRef()
|
||||
} else {
|
||||
val getInstanceName = className.ident + "_getInstance"
|
||||
JsInvocation(JsNameRef(getInstanceName))
|
||||
}
|
||||
}
|
||||
else -> TODO()
|
||||
}
|
||||
@@ -131,6 +136,19 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
val jsExtensionReceiver = expression.extensionReceiver?.accept(this, context)
|
||||
val arguments = translateCallArguments(expression, context)
|
||||
|
||||
// Transform external property accessor call
|
||||
if (function is IrSimpleFunction) {
|
||||
val property = function.correspondingProperty
|
||||
if (property != null && property.isEffectivelyExternal()) {
|
||||
val nameRef = JsNameRef(property.name.identifier, jsDispatchReceiver)
|
||||
return when (function) {
|
||||
property.getter -> nameRef
|
||||
property.setter -> jsAssignment(nameRef, arguments.single())
|
||||
else -> error("Function must be an accessor of corresponding property")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNativeInvoke(expression)) {
|
||||
return JsInvocation(jsDispatchReceiver!!, arguments)
|
||||
}
|
||||
|
||||
@@ -403,9 +403,17 @@ fun IrFunction.isFakeOverriddenFromAny(): Boolean {
|
||||
fun IrCall.isSuperToAny() = superQualifier?.let { this.symbol.owner.isFakeOverriddenFromAny() } ?: false
|
||||
|
||||
fun IrDeclaration.isEffectivelyExternal(): Boolean {
|
||||
|
||||
fun IrFunction.effectiveParentDeclaration(): IrDeclaration? =
|
||||
when (this) {
|
||||
is IrSimpleFunction -> correspondingProperty ?: parent as? IrDeclaration
|
||||
else -> parent as? IrDeclaration
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is IrFunction -> isExternal || parent is IrDeclaration && parent.isEffectivelyExternal()
|
||||
is IrFunction -> isExternal || (effectiveParentDeclaration()?.isEffectivelyExternal() ?: false)
|
||||
is IrField -> isExternal || parent is IrDeclaration && parent.isEffectivelyExternal()
|
||||
is IrProperty -> isExternal || parent is IrDeclaration && parent.isEffectivelyExternal()
|
||||
is IrClass -> isExternal || parent is IrDeclaration && parent.isEffectivelyExternal()
|
||||
else -> false
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1287
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1203
|
||||
|
||||
external interface Foo {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1285
|
||||
// MODULE_KIND: AMD
|
||||
package foo
|
||||
|
||||
Reference in New Issue
Block a user