Skip to content

Commit ec54f0c

Browse files
mcpiromanSpace Team
authored andcommitted
[IR] Refactor IrValidatorConfig to become a list of checkers
Only the "tree consistency" and "unbound symbols" checkers remain as flags, because they are special and need to be run before all other. No checkers are enabled by default. The use-sites of IrValidatorConfig will be adjusted in the next commit. #KT-76601 Fixed KT-77819
1 parent 5d7cf50 commit ec54f0c

File tree

2 files changed

+77
-85
lines changed

2 files changed

+77
-85
lines changed

compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/IrValidator.kt

Lines changed: 13 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,10 @@
55

66
package org.jetbrains.kotlin.backend.common
77

8-
import org.jetbrains.kotlin.backend.common.checkers.IrElementChecker
9-
import org.jetbrains.kotlin.backend.common.checkers.IrValidationError
10-
import org.jetbrains.kotlin.backend.common.checkers.TreeConsistencyError
11-
import org.jetbrains.kotlin.backend.common.checkers.checkTreeConsistency
12-
import org.jetbrains.kotlin.backend.common.checkers.context.*
13-
import org.jetbrains.kotlin.backend.common.checkers.declaration.*
14-
import org.jetbrains.kotlin.backend.common.checkers.expression.*
15-
import org.jetbrains.kotlin.backend.common.checkers.symbol.IrVisibilityChecker
16-
import org.jetbrains.kotlin.backend.common.checkers.IrSymbolChecker
17-
import org.jetbrains.kotlin.backend.common.checkers.IrTypeChecker
18-
import org.jetbrains.kotlin.backend.common.checkers.type.IrTypeParameterScopeChecker
8+
import org.jetbrains.kotlin.backend.common.checkers.*
9+
import org.jetbrains.kotlin.backend.common.checkers.context.CheckerContext
10+
import org.jetbrains.kotlin.backend.common.checkers.context.ContextUpdater
11+
import org.jetbrains.kotlin.backend.common.checkers.context.ParentChainUpdater
1912
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
2013
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
2114
import org.jetbrains.kotlin.config.IrVerificationMode
@@ -36,21 +29,6 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
3629

3730
typealias ReportIrValidationError = (IrFile?, IrElement, String, List<IrElement>) -> Unit
3831

39-
data class IrValidatorConfig(
40-
val checkTreeConsistency: Boolean = true,
41-
val checkTypes: Boolean = false,
42-
val checkValueScopes: Boolean = false,
43-
val checkTypeParameterScopes: Boolean = false,
44-
val checkCrossFileFieldUsage: Boolean = false,
45-
val checkAllKotlinFieldsArePrivate: Boolean = false,
46-
val checkVisibilities: Boolean = false,
47-
val checkVarargTypes: Boolean = false,
48-
val checkIrExpressionBodyInFunction: Boolean = true,
49-
val checkUnboundSymbols: Boolean = false,
50-
val checkInlineFunctionUseSites: InlineFunctionUseSiteChecker? = null,
51-
val checkOverridePrivateDeclaration: Boolean = true,
52-
)
53-
5432
private class IrValidator(
5533
val validatorConfig: IrValidatorConfig,
5634
val irBuiltIns: IrBuiltIns,
@@ -78,62 +56,10 @@ private class IrFileValidator(
7856
config: IrValidatorConfig,
7957
private val context: CheckerContext
8058
) : IrTreeSymbolsVisitor() {
81-
private val contextUpdaters: MutableSet<ContextUpdater> = mutableSetOf(ParentChainUpdater)
82-
private val elementCheckers: MutableList<IrElementChecker<*>> = mutableListOf(
83-
IrSetValueAssignabilityChecker,
84-
IrFunctionDispatchReceiverChecker, IrFunctionParametersChecker, IrConstructorReceiverChecker,
85-
IrTypeOperatorTypeOperandChecker,
86-
IrPropertyAccessorsChecker, IrFunctionPropertiesChecker,
87-
)
88-
private val symbolCheckers: MutableList<IrSymbolChecker> = mutableListOf()
89-
private val typeCheckers: MutableList<IrTypeChecker> = mutableListOf()
90-
91-
init {
92-
if (config.checkValueScopes) {
93-
elementCheckers.add(IrValueAccessScopeChecker)
94-
}
95-
if (config.checkTypeParameterScopes) {
96-
typeCheckers.add(IrTypeParameterScopeChecker)
97-
}
98-
if (config.checkAllKotlinFieldsArePrivate) {
99-
elementCheckers.add(IrFieldVisibilityChecker)
100-
}
101-
if (config.checkCrossFileFieldUsage) {
102-
elementCheckers.add(IrCrossFileFieldUsageChecker)
103-
}
104-
if (config.checkVisibilities) {
105-
symbolCheckers.add(IrVisibilityChecker)
106-
}
107-
if (config.checkVarargTypes) {
108-
elementCheckers.add(IrVarargTypesChecker)
109-
elementCheckers.add(IrValueParameterVarargTypesChecker)
110-
}
111-
if (config.checkTypes) {
112-
elementCheckers.add(IrConstTypeChecker)
113-
elementCheckers.add(IrStringConcatenationTypeChecker)
114-
elementCheckers.add(IrGetObjectValueTypeChecker)
115-
elementCheckers.add(IrGetValueTypeChecker)
116-
elementCheckers.add(IrUnitTypeExpressionChecker)
117-
elementCheckers.add(IrNothingTypeExpressionChecker)
118-
elementCheckers.add(IrGetFieldTypeChecker)
119-
elementCheckers.add(IrCallTypeChecker)
120-
elementCheckers.add(IrTypeOperatorTypeChecker)
121-
elementCheckers.add(IrDynamicTypeFieldAccessChecker)
122-
}
123-
if (config.checkIrExpressionBodyInFunction) {
124-
elementCheckers.add(IrExpressionBodyInFunctionChecker)
125-
}
126-
if (config.checkOverridePrivateDeclaration) {
127-
elementCheckers.add(IrPrivateDeclarationOverrideChecker)
128-
}
129-
config.checkInlineFunctionUseSites?.let {
130-
elementCheckers.add(IrNoInlineUseSitesChecker(it))
131-
}
132-
133-
for (checker in elementCheckers + symbolCheckers + typeCheckers) {
134-
contextUpdaters += checker.requiredContextUpdaters
135-
}
136-
}
59+
private val contextUpdaters: List<ContextUpdater> = listOf(ParentChainUpdater) + config.checkers.flatMap { it.requiredContextUpdaters }
60+
private val elementCheckers: List<IrElementChecker<*>> = config.checkers.filterIsInstance<IrElementChecker<*>>()
61+
private val symbolCheckers: List<IrSymbolChecker> = config.checkers.filterIsInstance<IrSymbolChecker>()
62+
private val typeCheckers: List<IrTypeChecker> = config.checkers.filterIsInstance<IrTypeChecker>()
13763

13864
private val checkersPerElement = object : ClassValue<List<IrElementChecker<*>>>() {
13965
override fun computeValue(type: Class<*>): List<IrElementChecker<*>> =
@@ -193,9 +119,11 @@ private fun performBasicIrValidation(
193119
}
194120
}
195121

196-
// Phase 2: Traverse the IR tree again to run additional checks based on the validator configuration.
197-
val validator = IrValidator(validatorConfig, irBuiltIns, reportError)
198-
element.acceptVoid(validator)
122+
if (validatorConfig.checkers.isNotEmpty()) {
123+
// Phase 2: Traverse the IR tree again to run additional checks based on the validator configuration.
124+
val validator = IrValidator(validatorConfig, irBuiltIns, reportError)
125+
element.acceptVoid(validator)
126+
}
199127
}
200128

201129
/**
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.backend.common
7+
8+
import org.jetbrains.kotlin.backend.common.checkers.IrChecker
9+
import org.jetbrains.kotlin.backend.common.checkers.declaration.*
10+
import org.jetbrains.kotlin.backend.common.checkers.expression.*
11+
import org.jetbrains.kotlin.backend.common.checkers.symbol.IrVisibilityChecker
12+
import org.jetbrains.kotlin.backend.common.checkers.type.IrTypeParameterScopeChecker
13+
14+
data class IrValidatorConfig(
15+
val checkTreeConsistency: Boolean = false,
16+
val checkUnboundSymbols: Boolean = false,
17+
val checkers: Set<IrChecker> = emptySet(),
18+
) {
19+
fun withCheckers(vararg checkers: IrChecker) = copy(checkers = this.checkers + checkers)
20+
fun withoutCheckers(vararg checkers: IrChecker) = copy(checkers = this.checkers - checkers.toSet())
21+
}
22+
23+
fun IrValidatorConfig.withBasicChecks() = withCheckers(
24+
IrFunctionDispatchReceiverChecker, IrConstructorReceiverChecker, IrFunctionParametersChecker,
25+
IrPropertyAccessorsChecker, IrFunctionPropertiesChecker,
26+
IrSetValueAssignabilityChecker,
27+
IrTypeOperatorTypeOperandChecker,
28+
IrPrivateDeclarationOverrideChecker,
29+
)
30+
31+
fun IrValidatorConfig.withTypeChecks() = withCheckers(
32+
IrConstTypeChecker,
33+
IrStringConcatenationTypeChecker,
34+
IrGetObjectValueTypeChecker,
35+
IrGetValueTypeChecker,
36+
IrUnitTypeExpressionChecker,
37+
IrNothingTypeExpressionChecker,
38+
IrGetFieldTypeChecker,
39+
IrCallTypeChecker,
40+
IrTypeOperatorTypeChecker,
41+
IrDynamicTypeFieldAccessChecker,
42+
)
43+
44+
fun IrValidatorConfig.withVarargChecks() = withCheckers(
45+
IrVarargTypesChecker,
46+
IrValueParameterVarargTypesChecker,
47+
)
48+
49+
fun IrValidatorConfig.withInlineFunctionCallsiteCheck(checkInlineFunctionUseSites: InlineFunctionUseSiteChecker?) =
50+
if (checkInlineFunctionUseSites != null) {
51+
withCheckers(IrNoInlineUseSitesChecker(checkInlineFunctionUseSites))
52+
} else this
53+
54+
fun IrValidatorConfig.withAllChecks() = withBasicChecks()
55+
.withVarargChecks()
56+
.withTypeChecks()
57+
.withCheckers(
58+
IrVisibilityChecker,
59+
IrValueAccessScopeChecker,
60+
IrTypeParameterScopeChecker,
61+
IrCrossFileFieldUsageChecker,
62+
IrFieldVisibilityChecker,
63+
IrExpressionBodyInFunctionChecker
64+
)

0 commit comments

Comments
 (0)