Change BodyLoweringPass API; add DeclarationTransformer + helper methods
This commit is contained in:
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.backend.common
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
@@ -58,7 +60,7 @@ interface FunctionLoweringPass : FileLoweringPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface BodyLoweringPass : FileLoweringPass {
|
interface BodyLoweringPass : FileLoweringPass {
|
||||||
fun lower(irBody: IrBody)
|
fun lower(irBody: IrBody, container: IrDeclaration)
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
@@ -110,17 +112,30 @@ fun DeclarationContainerLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
|||||||
this.lower(irFile as IrDeclarationContainer)
|
this.lower(irFile as IrDeclarationContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BodyLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
fun BodyLoweringPass.runOnFilePostfix(irFile: IrFile, withLocalDeclarations: Boolean = false) {
|
||||||
irFile.acceptVoid(object : IrElementVisitorVoid {
|
ArrayList(irFile.declarations).forEach {
|
||||||
override fun visitElement(element: IrElement) {
|
it.accept(object : IrElementVisitor<Unit, IrDeclaration?> {
|
||||||
element.acceptChildrenVoid(this)
|
override fun visitElement(element: IrElement, data: IrDeclaration?) {
|
||||||
}
|
element.acceptChildren(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitBody(body: IrBody) {
|
override fun visitDeclaration(declaration: IrDeclaration, data: IrDeclaration?) {
|
||||||
body.acceptChildrenVoid(this)
|
declaration.acceptChildren(this, declaration)
|
||||||
lower(body)
|
}
|
||||||
}
|
|
||||||
})
|
override fun visitClass(declaration: IrClass, data: IrDeclaration?) {
|
||||||
|
declaration.thisReceiver?.accept(this, declaration)
|
||||||
|
declaration.typeParameters.forEach { it.accept(this, declaration) }
|
||||||
|
ArrayList(declaration.declarations).forEach { it.accept(this, declaration) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBody(body: IrBody, data: IrDeclaration?) {
|
||||||
|
if (withLocalDeclarations) body.acceptChildren(this, null)
|
||||||
|
|
||||||
|
lower(body, data!!)
|
||||||
|
}
|
||||||
|
}, null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FunctionLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
fun FunctionLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
||||||
@@ -134,4 +149,92 @@ fun FunctionLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
|||||||
lower(declaration)
|
lower(declaration)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DeclarationTransformer: FileLoweringPass {
|
||||||
|
fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>?
|
||||||
|
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
runPostfix().toFileLoweringPass().lower(irFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DeclarationTransformer.transformFlatRestricted(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||||
|
return transformFlat(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DeclarationTransformer.toFileLoweringPass(): FileLoweringPass {
|
||||||
|
return object : FileLoweringPass {
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
irFile.declarations.transformFlat(this@toFileLoweringPass::transformFlat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DeclarationTransformer.runPostfix(withLocalDeclarations: Boolean = false): DeclarationTransformer {
|
||||||
|
return object : DeclarationTransformer {
|
||||||
|
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||||
|
declaration.acceptVoid(object : IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBody(body: IrBody) {
|
||||||
|
if (withLocalDeclarations) {
|
||||||
|
super.visitBody(body)
|
||||||
|
}
|
||||||
|
// else stop
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFunction(declaration: IrFunction) {
|
||||||
|
declaration.acceptChildrenVoid(this)
|
||||||
|
|
||||||
|
for (v in declaration.valueParameters) {
|
||||||
|
val result = this@runPostfix.transformFlatRestricted(v)
|
||||||
|
if (result != null) error("Don't know how to add value parameters")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitProperty(declaration: IrProperty) {
|
||||||
|
// TODO This is a hack to allow lowering a getter separately from the enclosing property
|
||||||
|
|
||||||
|
val visitor = this
|
||||||
|
|
||||||
|
fun IrDeclaration.transform() {
|
||||||
|
|
||||||
|
acceptVoid(visitor)
|
||||||
|
|
||||||
|
val result = this@runPostfix.transformFlatRestricted(this)
|
||||||
|
if (result != null) {
|
||||||
|
(parent as? IrDeclarationContainer)?.let {
|
||||||
|
var index = it.declarations.indexOf(this)
|
||||||
|
if (index == -1) {
|
||||||
|
index = it.declarations.indexOf(declaration)
|
||||||
|
} else {
|
||||||
|
it.declarations.removeAt(index)
|
||||||
|
--index
|
||||||
|
}
|
||||||
|
|
||||||
|
it.declarations.addAll(index + 1, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declaration.backingField?.transform()
|
||||||
|
declaration.getter?.transform()
|
||||||
|
declaration.setter?.transform()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClass(declaration: IrClass) {
|
||||||
|
declaration.thisReceiver?.accept(this, null)
|
||||||
|
declaration.typeParameters.forEach { it.accept(this, null) }
|
||||||
|
ArrayList(declaration.declarations).forEach { it.accept(this, null) }
|
||||||
|
|
||||||
|
declaration.declarations.transformFlat(this@runPostfix::transformFlatRestricted)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return this@runPostfix.transformFlatRestricted(declaration)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -207,7 +207,7 @@ open class DefaultParameterInjector(
|
|||||||
irFile.transformChildrenVoid(this)
|
irFile.transformChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun lower(irBody: IrBody) {
|
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||||
irBody.transformChildrenVoid(this)
|
irBody.transformChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
|
|||||||
val BIND_CALL = object : IrStatementOriginImpl("BIND_CALL") {}
|
val BIND_CALL = object : IrStatementOriginImpl("BIND_CALL") {}
|
||||||
|
|
||||||
class JsDefaultCallbackGenerator(val context: JsIrBackendContext): BodyLoweringPass {
|
class JsDefaultCallbackGenerator(val context: JsIrBackendContext): BodyLoweringPass {
|
||||||
override fun lower(irBody: IrBody) {
|
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
super.visitCall(expression)
|
super.visitCall(expression)
|
||||||
|
|||||||
Reference in New Issue
Block a user