JVM IR: Validate corresponding properties

This commit is contained in:
Steven Schäfer
2020-04-20 17:30:14 +02:00
committed by Alexander Udalov
parent 13f15a702b
commit 9bc8fdcb3c
5 changed files with 24 additions and 13 deletions
@@ -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 <T> visitConst(expression: IrConst<T>) {
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)
}
@@ -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 {
@@ -123,12 +123,13 @@ fun <Data, Context> dumpToStdout(
val defaultDumper = makeDumpAction(dumpToStdout(::dumpIrElement) + dumpToFile("ir", ::dumpIrElement))
fun <Fragment : IrElement> validationCallback(context: CommonBackendContext, fragment: Fragment) {
fun <Fragment : IrElement> 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)
@@ -46,13 +46,13 @@ private fun makePatchParentsPhase(number: Int) = namedIrFilePhase(
)
private val validateIrBeforeLowering = makeCustomPhase<JvmBackendContext, IrModuleFragment>(
{ context, module -> validationCallback(context, module) },
{ context, module -> validationCallback(context, module, checkProperties = true) },
name = "ValidateIrBeforeLowering",
description = "Validate IR before lowering"
)
private val validateIrAfterLowering = makeCustomPhase<JvmBackendContext, IrModuleFragment>(
{ context, module -> validationCallback(context, module) },
{ context, module -> validationCallback(context, module, checkProperties = true) },
name = "ValidateIrAfterLowering",
description = "Validate IR after lowering"
)
@@ -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