[JS IR BE] Lower property accessors in PrimitiveCompanionLowering

This commit is contained in:
Svyatoslav Kuzmich
2019-04-05 16:58:02 +03:00
parent 19b0bb8d0f
commit 14ec30dd5a
@@ -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)
}
})
}