diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/PropertiesLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/PropertiesLowering.kt index e6018cc5561..ee558b6e460 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/PropertiesLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/PropertiesLowering.kt @@ -43,20 +43,6 @@ class PropertiesLowering : DeclarationTransformer { return null } - - companion object { - fun checkNoProperties(irFile: IrFile) { - irFile.acceptVoid(object : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitProperty(declaration: IrProperty) { - error("No properties should remain at this stage") - } - }) - } - } } class LocalDelegatedPropertiesLowering : IrElementTransformerVoid(), BodyLoweringPass { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLoweringPhases.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLoweringPhases.kt index 14f9418d0f1..583ffd4c229 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLoweringPhases.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLoweringPhases.kt @@ -83,6 +83,12 @@ private val validateIrAfterLowering = makeCustomPhase( description = "Validate IR after lowering" ) +private val validateJvmIrAfterLowering = makeCustomPhase( + { _, module -> validateJvmIr(module) }, + name = "ValidateJvmIrAfterLowering", + description = "Validate that IR after lowering is correctly structured by Kotlin JVM rules" +) + // TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase private val provisionalFunctionExpressionPhase = makeIrFilePhase( { ProvisionalFunctionExpressionLowering() }, @@ -112,7 +118,6 @@ internal val propertiesPhase = makeIrFilePhase( description = "Move fields and accessors for properties to their classes, " + "replace calls to default property accessors with field accesses, " + "remove unused accessors and create synthetic methods for property annotations", - stickyPostconditions = setOf(PropertiesLowering.Companion::checkNoProperties) ) internal val IrClass.isGeneratedLambdaClass: Boolean @@ -243,17 +248,6 @@ private val initializersCleanupPhase = makeIrFilePhase( }, name = "InitializersCleanup", description = "Remove non-static anonymous initializers and non-constant non-static field init expressions", - stickyPostconditions = setOf(fun(irFile: IrFile) { - irFile.acceptVoid(object : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) { - error("No anonymous initializers should remain at this stage") - } - }) - }), prerequisite = setOf(initializersPhase) ) @@ -487,7 +481,8 @@ private fun buildJvmLoweringPhases( buildLoweringsPhase(phases) then generateMultifileFacadesPhase then resolveInlineCallsPhase then - validateIrAfterLowering + validateIrAfterLowering then + validateJvmIrAfterLowering ) } diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt index 16f44dc976c..f81e77107a9 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt @@ -54,15 +54,8 @@ internal val fileClassPhase = makeIrModulePhase( ::FileClassLowering, name = "FileClass", description = "Put file level function and property declaration into a class", - stickyPostconditions = setOf(::checkAllFileLevelDeclarationsAreClasses) ) -internal fun checkAllFileLevelDeclarationsAreClasses(irModuleFragment: IrModuleFragment) { - assert(irModuleFragment.files.all { irFile -> - irFile.declarations.all { it is IrClass } - }) -} - private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass { override fun lower(irFile: IrFile) { val classes = ArrayList() diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/irValidation.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/irValidation.kt index a289fb81cf6..1af8ca61521 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/irValidation.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/irValidation.kt @@ -7,9 +7,40 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.phaser.validationCallback import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.IrAnonymousInitializer +import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.ir.visitors.acceptVoid fun validateIr(context: JvmBackendContext, module: IrModuleFragment) { if (!context.config.shouldValidateIr) return validationCallback(context, module, checkProperties = true) } + +private fun checkAllFileLevelDeclarationsAreClasses(module: IrModuleFragment) { + assert(module.files.all { irFile -> + irFile.declarations.all { it is IrClass } + }) +} + +fun validateJvmIr(module: IrModuleFragment) { + checkAllFileLevelDeclarationsAreClasses(module) + val validator = object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitProperty(declaration: IrProperty) { + error("No properties should remain at this stage") + } + + override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) { + error("No anonymous initializers should remain at this stage") + } + } + module.acceptVoid(validator) +}