Make LocalClassPopupLowering a BodyLoweringPass

This commit is contained in:
Anton Bannykh
2019-12-19 19:02:27 +03:00
parent d228de9008
commit 1eec2acf43
@@ -5,38 +5,39 @@
package org.jetbrains.kotlin.backend.common.lower package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.ScopeWithIr
import org.jetbrains.kotlin.backend.common.ir.addChild import org.jetbrains.kotlin.backend.common.ir.addChild
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrScript
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
//This lower takes part of old LocalDeclarationLowering job to pop up local classes from functions //This lower takes part of old LocalDeclarationLowering job to pop up local classes from functions
open class LocalClassPopupLowering(val context: BackendContext) : FileLoweringPass { open class LocalClassPopupLowering(val context: BackendContext) : BodyLoweringPass {
override fun lower(irFile: IrFile) { override fun lower(irFile: IrFile) {
runOnFilePostfix(irFile, withLocalDeclarations = true)
}
override fun lower(irBody: IrBody, container: IrDeclaration) {
val extractedLocalClasses = arrayListOf<Pair<IrClass, IrDeclarationContainer>>() val extractedLocalClasses = arrayListOf<Pair<IrClass, IrDeclarationContainer>>()
irFile.transform(object : IrElementTransformerVoidWithContext() { irBody.transform(object : IrElementTransformerVoidWithContext() {
override fun visitClassNew(declaration: IrClass): IrStatement { override fun visitClassNew(declaration: IrClass): IrStatement {
val newDeclaration = super.visitClassNew(declaration) val currentScope =
if (newDeclaration !is IrClass) return newDeclaration if (allScopes.size > 1) allScopes[allScopes.lastIndex - 1] else createScope(container as IrSymbolOwner)
if (!shouldPopUp(declaration, currentScope)) return declaration
val currentScope = allScopes[allScopes.lastIndex - 1] val newContainer = run {
if (!shouldPopUp(declaration, currentScope)) return newDeclaration var currentParent = declaration.parent
while (currentParent is IrDeclaration && currentParent !is IrClass && currentParent !is IrScript) {
currentParent = currentParent.parent
}
val newContainer = allScopes.asReversed().drop(1/*skip self*/).firstOrNull { currentParent as IrDeclarationContainer // IrClass or IrScript or IrPackageFragment
//find first class local or not; }
// to reproduce original LocalDeclarationLowering behaviour add: '&& !it.irElement.isLocal' condition
it.irElement is IrClass || it.irElement is IrScript extractedLocalClasses.add(declaration to newContainer)
}?.irElement?.let { it as? IrClass ?: it as? IrScript } ?: currentFile
extractedLocalClasses.add(newDeclaration to newContainer)
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType) return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType)
} }
}, null) }, null)