[JS IR BE] Lower property accessors in PrimitiveCompanionLowering
This commit is contained in:
+54
-8
@@ -9,27 +9,73 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
|
||||
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
||||
import org.jetbrains.kotlin.ir.types.isString
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.irCall
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
class PrimitiveCompanionLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
|
||||
private fun getActualPrimitiveCompanion(irClass: IrClass): IrClass? {
|
||||
if (!irClass.isCompanion)
|
||||
return null
|
||||
|
||||
val parent = irClass.parent as IrClass
|
||||
|
||||
if (!parent.defaultType.isPrimitiveType() && !parent.defaultType.isString())
|
||||
return null
|
||||
|
||||
return context.primitiveCompanionObjects[parent.name]?.owner
|
||||
}
|
||||
|
||||
private fun getActualPrimitiveCompanionPropertyAccessor(function: IrSimpleFunction): IrSimpleFunction? {
|
||||
val property = function.correspondingPropertySymbol?.owner
|
||||
?: return null
|
||||
|
||||
val companion = property.parent as? IrClass
|
||||
?: return null
|
||||
|
||||
val actualCompanion = getActualPrimitiveCompanion(companion)
|
||||
?: return null
|
||||
|
||||
val actualFunction =
|
||||
actualCompanion.declarations
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.find { it.name == function.name }
|
||||
|
||||
return actualFunction!!
|
||||
}
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {
|
||||
val symbol = expression.symbol
|
||||
if (!symbol.isBound) return expression
|
||||
val declaration = symbol.owner
|
||||
if (!declaration.isCompanion) return expression
|
||||
val parent = declaration.parent as IrClass
|
||||
if (!parent.defaultType.isPrimitiveType() && !parent.defaultType.isString()) return expression
|
||||
val actualCompanion = context.primitiveCompanionObjects[parent.name] ?: return expression
|
||||
return expression.run { IrGetObjectValueImpl(startOffset, endOffset, actualCompanion.owner.defaultType, actualCompanion) }
|
||||
val irClass = expression.symbol.owner
|
||||
val actualCompanion = getActualPrimitiveCompanion(irClass) ?: return expression
|
||||
return IrGetObjectValueImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
actualCompanion.defaultType,
|
||||
actualCompanion.symbol
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val newCall = super.visitCall(expression) as IrCall
|
||||
|
||||
val function = expression.symbol.owner as? IrSimpleFunction
|
||||
?: return newCall
|
||||
|
||||
val actualFunction = getActualPrimitiveCompanionPropertyAccessor(function)
|
||||
?: return newCall
|
||||
|
||||
return irCall(newCall, actualFunction)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user