Make LocalClassPopupLowering a BodyLoweringPass
This commit is contained in:
+21
-20
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user