diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CheckIrElementVisitor.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CheckIrElementVisitor.kt index 08b5a7e2d04..23bbbc08f58 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CheckIrElementVisitor.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CheckIrElementVisitor.kt @@ -76,6 +76,19 @@ class CheckIrElementVisitor( } } + private fun IrElement.checkFunction(function: IrFunction) { + if (function is IrSimpleFunction && config.checkProperties) { + val property = function.correspondingPropertySymbol?.owner + if (property != null && property.getter != function && property.setter != function) { + reportError(this, "Orphaned property getter/setter ${function.render()}") + } + } + + if (function.dispatchReceiverParameter?.type is IrDynamicType) { + reportError(this, "Dispatch receivers with 'dynamic' type are not allowed") + } + } + override fun visitConst(expression: IrConst) { super.visitConst(expression) @@ -152,10 +165,8 @@ class CheckIrElementVisitor( super.visitCall(expression) val function = expression.symbol.owner + expression.checkFunction(function) - if (function.dispatchReceiverParameter?.type is IrDynamicType) { - reportError(expression, "Dispatch receivers with 'dynamic' type are not allowed") - } // TODO: Why don't we check parameters as well? val returnType = expression.symbol.owner.returnType @@ -267,10 +278,7 @@ class CheckIrElementVisitor( override fun visitFunction(declaration: IrFunction) { super.visitFunction(declaration) - - if (declaration.dispatchReceiverParameter?.type is IrDynamicType) { - reportError(declaration, "Dispatch receivers with 'dynamic' type are not allowed") - } + declaration.checkFunction(declaration) for ((i, p) in declaration.valueParameters.withIndex()) { if (p.index != i) { @@ -323,7 +331,7 @@ class CheckIrElementVisitor( override fun visitFunctionReference(expression: IrFunctionReference) { super.visitFunctionReference(expression) - + expression.checkFunction(expression.symbol.owner) expression.symbol.ensureBound(expression) } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/IrValidator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/IrValidator.kt index e4eef6fe5ad..12b1a35d6b3 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/IrValidator.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/IrValidator.kt @@ -53,7 +53,8 @@ data class IrValidatorConfig( val abortOnError: Boolean, val ensureAllNodesAreDifferent: Boolean, val checkTypes: Boolean = true, - val checkDescriptors: Boolean = true + val checkDescriptors: Boolean = true, + val checkProperties: Boolean = false, ) class IrValidator(val context: CommonBackendContext, val config: IrValidatorConfig) : IrElementVisitorVoid { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt index 4da8b8b5d93..04fe4e846e5 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt @@ -123,12 +123,13 @@ fun dumpToStdout( val defaultDumper = makeDumpAction(dumpToStdout(::dumpIrElement) + dumpToFile("ir", ::dumpIrElement)) -fun validationCallback(context: CommonBackendContext, fragment: Fragment) { +fun validationCallback(context: CommonBackendContext, fragment: Fragment, checkProperties: Boolean = false) { val validatorConfig = IrValidatorConfig( abortOnError = true, ensureAllNodesAreDifferent = true, checkTypes = false, - checkDescriptors = false + checkDescriptors = false, + checkProperties = checkProperties, ) fragment.accept(IrValidator(context, validatorConfig), null) fragment.accept(CheckDeclarationParentsVisitor, null) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index d4026b969e7..74c30b01427 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -46,13 +46,13 @@ private fun makePatchParentsPhase(number: Int) = namedIrFilePhase( ) private val validateIrBeforeLowering = makeCustomPhase( - { context, module -> validationCallback(context, module) }, + { context, module -> validationCallback(context, module, checkProperties = true) }, name = "ValidateIrBeforeLowering", description = "Validate IR before lowering" ) private val validateIrAfterLowering = makeCustomPhase( - { context, module -> validationCallback(context, module) }, + { context, module -> validationCallback(context, module, checkProperties = true) }, name = "ValidateIrAfterLowering", description = "Validate IR after lowering" ) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index 6e76d51bcd2..b5912214e79 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -255,6 +255,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class currentScope?.scope?.scopeOwnerSymbol ?: irClass.symbol, expression.startOffset, expression.endOffset ) .irBlock { + // TODO: Move this to the enclosing class, right now the parent field is wrong! +referenceClass +irCall(referenceClass.constructors.single()).apply { var index = 0