diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/AnnotationLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/AnnotationLowering.kt index 32436d16b6a..2334995a19d 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/AnnotationLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/AnnotationLowering.kt @@ -5,16 +5,12 @@ package org.jetbrains.kotlin.backend.jvm.lower -import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext -import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor -import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.util.isAnnotationClass -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid internal val annotationPhase = makeIrFilePhase( { AnnotationLowering() }, @@ -22,13 +18,10 @@ internal val annotationPhase = makeIrFilePhase( description = "Remove constructors of annotation classes" ) -private class AnnotationLowering : FileLoweringPass, IrElementTransformerVoid() { - override fun lower(irFile: IrFile) = irFile.transformChildrenVoid(this) - - override fun visitClass(declaration: IrClass): IrStatement = - declaration.transformPostfix { - if (isAnnotationClass) { - declarations.removeIf { it is IrConstructor } - } +private class AnnotationLowering : ClassLoweringPass { + override fun lower(irClass: IrClass) { + if (irClass.isAnnotationClass) { + irClass.declarations.removeIf { it is IrConstructor } } + } } diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index 798359c1c17..06f9feb33e7 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.backend.jvm.lower -import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.lower.SpecialMethodWithDefaultInfo import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irNot @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.backend.jvm.ir.* import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.addFunction import org.jetbrains.kotlin.ir.declarations.* @@ -30,7 +29,6 @@ import org.jetbrains.kotlin.ir.types.isNullable import org.jetbrains.kotlin.ir.types.isPrimitiveType import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.org.objectweb.asm.Type @@ -118,7 +116,7 @@ internal val bridgePhase = makeIrFilePhase( prerequisite = setOf(jvmValueClassPhase, inheritedDefaultMethodsOnClassesPhase) ) -internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoid() { +internal class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass { // Represents a synthetic bridge to `overridden` with a precomputed signature private class Bridge( val overridden: IrSimpleFunction, @@ -126,27 +124,21 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass val overriddenSymbols: MutableList = mutableListOf() ) - override fun lower(irFile: IrFile) { - irFile.transformChildrenVoid() - } + override fun lower(irClass: IrClass) { + // Bridges in DefaultImpls classes are handled in InterfaceLowering. + if (irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS || irClass.isAnnotationClass) return - override fun visitClass(declaration: IrClass): IrStatement { - // Bridges in DefaultImpl classes are handled in InterfaceLowering. - if (declaration.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS || declaration.isAnnotationClass) - return super.visitClass(declaration) + val bridgeTargets = irClass.functions.filterTo(SmartList()) { it.isPotentialBridgeTarget() } + if (bridgeTargets.isEmpty()) return - val bridgeTargets = declaration.functions.filterTo(SmartList()) { it.isPotentialBridgeTarget() } - if (bridgeTargets.isEmpty()) - return super.visitClass(declaration) + bridgeTargets.forEach { createBridges(irClass, it) } - bridgeTargets.forEach { createBridges(declaration, it) } - - if (declaration.isSingleFieldValueClass) { + if (irClass.isSingleFieldValueClass) { // Inline class (implementing 'MutableCollection', where T is Int or an inline class mapped to Int) // can contain a static replacement for a function 'remove', which forces value parameter boxing // in order to avoid signature clash with 'remove(int)' method in 'java.util.List'. // We should rewrite this static replacement as well ('remove' function itself is handled during special bridge processing). - val remove = declaration.functions.find { + val remove = irClass.functions.find { val original = context.inlineClassReplacements.originalFunctionForStaticReplacement[it] original != null && context.defaultMethodSignatureMapper.shouldBoxSingleValueParameterForSpecialCaseOfRemove(original) } @@ -156,8 +148,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass } } } - - return super.visitClass(declaration) } private fun IrSimpleFunction.isPotentialBridgeTarget(): Boolean { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt index 3a2b93c5894..c04256ad9cc 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt @@ -28,7 +28,9 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.expressions.putArgument import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.* +import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid internal val inheritedDefaultMethodsOnClassesPhase = makeIrFilePhase( ::InheritedDefaultMethodsOnClassesLowering, @@ -123,25 +125,24 @@ internal val replaceDefaultImplsOverriddenSymbolsPhase = makeIrFilePhase( description = "Replace overridden symbols for methods inherited from interfaces to classes" ) -private class ReplaceDefaultImplsOverriddenSymbols(private val context: JvmBackendContext) : FileLoweringPass, IrElementVisitorVoid { - override fun lower(irFile: IrFile) { - irFile.acceptVoid(this) - } - - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) +private class ReplaceDefaultImplsOverriddenSymbols(private val context: JvmBackendContext) : ClassLoweringPass { + override fun lower(irClass: IrClass) { + for (declaration in irClass.declarations) { + if (declaration is IrSimpleFunction) { + visitSimpleFunction(declaration) + } + } } // Functions introduced by InheritedDefaultMethodsOnClassesLowering may be inherited lower in the hierarchy. // Here we use the same logic as the delegation itself (`getTargetForRedirection`) to determine // if the overridden symbol has been, or will be, replaced and patch it accordingly. - override fun visitSimpleFunction(declaration: IrSimpleFunction) { + fun visitSimpleFunction(declaration: IrSimpleFunction) { declaration.overriddenSymbols = declaration.overriddenSymbols.map { symbol -> if (symbol.owner.findInterfaceImplementation(context.config.jvmDefaultMode) != null) context.cachedDeclarations.getDefaultImplsRedirection(symbol.owner).symbol else symbol } - super.visitSimpleFunction(declaration) } } diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt index 5f2b38ec88f..ee4eeea9ade 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt @@ -5,15 +5,13 @@ package org.jetbrains.kotlin.backend.jvm.lower -import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext +import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.DescriptorVisibilities -import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irExprBody import org.jetbrains.kotlin.ir.builders.irGetField @@ -31,23 +29,17 @@ internal val objectClassPhase = makeIrFilePhase( description = "Handle object classes" ) -private class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass { - - private var pendingTransformations = mutableListOf>() +private class ObjectClassLowering(val context: JvmBackendContext) : ClassLoweringPass { + private val pendingTransformations = mutableListOf>() override fun lower(irFile: IrFile) { - irFile.accept(this, null) - - pendingTransformations.forEach { it() } + super.lower(irFile) + for (transformation in pendingTransformations) { + transformation.invoke() + } } - override fun visitClassNew(declaration: IrClass): IrStatement { - process(declaration) - return super.visitClassNew(declaration) - } - - - private fun process(irClass: IrClass) { + override fun lower(irClass: IrClass) { if (!irClass.isObject) return val publicInstanceField = context.cachedDeclarations.getFieldForObjectInstance(irClass)