|
5 | 5 |
|
6 | 6 | package org.jetbrains.kotlin.backend.common
|
7 | 7 |
|
8 |
| -import org.jetbrains.kotlin.backend.common.checkers.* |
| 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 |
9 | 12 | import org.jetbrains.kotlin.backend.common.checkers.context.*
|
10 | 13 | import org.jetbrains.kotlin.backend.common.checkers.declaration.*
|
11 | 14 | import org.jetbrains.kotlin.backend.common.checkers.expression.*
|
12 | 15 | import org.jetbrains.kotlin.backend.common.checkers.symbol.IrSymbolChecker
|
13 | 16 | import org.jetbrains.kotlin.backend.common.checkers.symbol.IrVisibilityChecker
|
14 |
| -import org.jetbrains.kotlin.backend.common.checkers.symbol.check |
15 | 17 | import org.jetbrains.kotlin.backend.common.checkers.type.IrTypeChecker
|
16 | 18 | import org.jetbrains.kotlin.backend.common.checkers.type.IrTypeParameterScopeChecker
|
17 |
| -import org.jetbrains.kotlin.backend.common.checkers.type.check |
18 | 19 | import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
19 | 20 | import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
20 | 21 | import org.jetbrains.kotlin.config.IrVerificationMode
|
21 | 22 | import org.jetbrains.kotlin.ir.IrBuiltIns
|
22 | 23 | import org.jetbrains.kotlin.ir.IrElement
|
23 |
| -import org.jetbrains.kotlin.ir.declarations.* |
24 |
| -import org.jetbrains.kotlin.ir.expressions.* |
| 24 | +import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase |
| 25 | +import org.jetbrains.kotlin.ir.declarations.IrFile |
| 26 | +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment |
| 27 | +import org.jetbrains.kotlin.ir.expressions.IrConstructorCall |
| 28 | +import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression |
25 | 29 | import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
26 | 30 | import org.jetbrains.kotlin.ir.types.IrType
|
27 | 31 | import org.jetbrains.kotlin.ir.util.IrTreeSymbolsVisitor
|
@@ -93,258 +97,92 @@ private class IrFileValidator(
|
93 | 97 | private val context: CheckerContext
|
94 | 98 | ) : IrTreeSymbolsVisitor() {
|
95 | 99 | private val contextUpdaters: MutableList<ContextUpdater> = mutableListOf(ParentChainUpdater)
|
96 |
| - |
97 |
| - private val fieldCheckers: MutableList<IrElementChecker<IrField>> = mutableListOf() |
98 |
| - private val fieldAccessExpressionCheckers: MutableList<IrElementChecker<IrFieldAccessExpression>> = mutableListOf() |
99 |
| - private val typeCheckers: MutableList<IrTypeChecker> = mutableListOf() |
100 |
| - private val symbolCheckers: MutableList<IrSymbolChecker> = mutableListOf() |
101 |
| - private val declarationReferenceCheckers: MutableList<IrElementChecker<IrDeclarationReference>> = mutableListOf() |
102 |
| - private val varargCheckers: MutableList<IrElementChecker<IrVararg>> = mutableListOf() |
103 |
| - private val valueParameterCheckers: MutableList<IrElementChecker<IrValueParameter>> = mutableListOf() |
104 |
| - private val valueAccessCheckers: MutableList<IrElementChecker<IrValueAccessExpression>> = mutableListOf() |
105 |
| - private val functionAccessCheckers: MutableList<IrElementChecker<IrFunctionAccessExpression>> = mutableListOf(IrNoInlineUseSitesChecker) |
106 |
| - private val functionReferenceCheckers: MutableList<IrElementChecker<IrFunctionReference>> = mutableListOf() |
107 |
| - private val constCheckers: MutableList<IrElementChecker<IrConst>> = mutableListOf() |
108 |
| - private val stringConcatenationCheckers: MutableList<IrElementChecker<IrStringConcatenation>> = mutableListOf() |
109 |
| - private val getObjectValueCheckers: MutableList<IrElementChecker<IrGetObjectValue>> = mutableListOf() |
110 |
| - private val getValueCheckers: MutableList<IrElementChecker<IrGetValue>> = mutableListOf() |
111 |
| - private val setValueCheckers: MutableList<IrElementChecker<IrSetValue>> = mutableListOf(IrSetValueAssignabilityChecker) |
112 |
| - private val getFieldCheckers: MutableList<IrElementChecker<IrGetField>> = mutableListOf() |
113 |
| - private val setFieldCheckers: MutableList<IrElementChecker<IrSetField>> = mutableListOf() |
114 |
| - private val delegatingConstructorCallCheckers: MutableList<IrElementChecker<IrDelegatingConstructorCall>> = mutableListOf() |
115 |
| - private val instanceInitializerCallCheckers: MutableList<IrElementChecker<IrInstanceInitializerCall>> = mutableListOf() |
116 |
| - private val loopCheckers: MutableList<IrElementChecker<IrLoop>> = mutableListOf() |
117 |
| - private val breakContinueCheckers: MutableList<IrElementChecker<IrBreakContinue>> = mutableListOf() |
118 |
| - private val returnCheckers: MutableList<IrElementChecker<IrReturn>> = mutableListOf() |
119 |
| - private val throwCheckers: MutableList<IrElementChecker<IrThrow>> = mutableListOf() |
120 |
| - private val functionCheckers: MutableList<IrElementChecker<IrFunction>> = mutableListOf( |
121 |
| - IrFunctionDispatchReceiverChecker, IrFunctionParametersChecker, IrConstructorReceiverChecker, IrFunctionPropertiesChecker |
| 100 | + private val elementCheckers: MutableList<IrElementChecker<*>> = mutableListOf( |
| 101 | + IrNoInlineUseSitesChecker, IrSetValueAssignabilityChecker, |
| 102 | + IrFunctionDispatchReceiverChecker, IrFunctionParametersChecker, IrConstructorReceiverChecker, |
| 103 | + IrTypeOperatorTypeOperandChecker, |
| 104 | + IrPropertyAccessorsChecker, IrFunctionPropertiesChecker, |
122 | 105 | )
|
123 |
| - private val declarationBaseCheckers: MutableList<IrElementChecker<IrDeclaration>> = mutableListOf() |
124 |
| - private val propertyReferenceCheckers: MutableList<IrElementChecker<IrPropertyReference>> = mutableListOf() |
125 |
| - private val localDelegatedPropertyReferenceCheckers: MutableList<IrElementChecker<IrLocalDelegatedPropertyReference>> = mutableListOf() |
126 |
| - private val expressionCheckers: MutableList<IrElementChecker<IrExpression>> = mutableListOf() |
127 |
| - private val typeOperatorCheckers: MutableList<IrElementChecker<IrTypeOperatorCall>> = mutableListOf(IrTypeOperatorTypeOperandChecker) |
128 |
| - private val propertyCheckers: MutableList<IrElementChecker<IrProperty>> = mutableListOf(IrPropertyAccessorsChecker) |
129 |
| - |
130 |
| - private val callCheckers: MutableList<IrElementChecker<IrCall>> = mutableListOf() |
| 106 | + private val symbolCheckers: MutableList<IrSymbolChecker> = mutableListOf() |
| 107 | + private val typeCheckers: MutableList<IrTypeChecker> = mutableListOf() |
131 | 108 |
|
132 | 109 | init {
|
133 | 110 | if (config.checkValueScopes) {
|
134 | 111 | contextUpdaters.add(ValueScopeUpdater)
|
135 |
| - valueAccessCheckers.add(IrValueAccessScopeChecker) |
| 112 | + elementCheckers.add(IrValueAccessScopeChecker) |
136 | 113 | }
|
137 | 114 | if (config.checkTypeParameterScopes) {
|
138 | 115 | contextUpdaters.add(TypeParameterScopeUpdater)
|
139 | 116 | typeCheckers.add(IrTypeParameterScopeChecker)
|
140 | 117 | }
|
141 | 118 | if (config.checkAllKotlinFieldsArePrivate) {
|
142 |
| - fieldCheckers.add(IrFieldVisibilityChecker) |
| 119 | + elementCheckers.add(IrFieldVisibilityChecker) |
143 | 120 | }
|
144 | 121 | if (config.checkCrossFileFieldUsage) {
|
145 |
| - fieldAccessExpressionCheckers.add(IrCrossFileFieldUsageChecker) |
| 122 | + elementCheckers.add(IrCrossFileFieldUsageChecker) |
146 | 123 | }
|
147 | 124 | if (config.checkVisibilities) {
|
148 | 125 | symbolCheckers.add(IrVisibilityChecker)
|
149 | 126 | }
|
150 | 127 | if (config.checkVarargTypes) {
|
151 |
| - varargCheckers.add(IrVarargTypesChecker) |
152 |
| - valueParameterCheckers.add(IrValueParameterVarargTypesChecker) |
| 128 | + elementCheckers.add(IrVarargTypesChecker) |
| 129 | + elementCheckers.add(IrValueParameterVarargTypesChecker) |
153 | 130 | }
|
154 | 131 | if (config.checkTypes) {
|
155 |
| - constCheckers.add(IrConstTypeChecker) |
156 |
| - stringConcatenationCheckers.add(IrStringConcatenationTypeChecker) |
157 |
| - getObjectValueCheckers.add(IrGetObjectValueTypeChecker) |
158 |
| - getValueCheckers.add(IrGetValueTypeChecker) |
159 |
| - setValueCheckers.add(IrUnitTypeExpressionChecker) |
160 |
| - getFieldCheckers.add(IrGetFieldTypeChecker) |
161 |
| - setFieldCheckers.add(IrUnitTypeExpressionChecker) |
162 |
| - callCheckers.add(IrCallTypeChecker) |
163 |
| - delegatingConstructorCallCheckers.add(IrUnitTypeExpressionChecker) |
164 |
| - instanceInitializerCallCheckers.add(IrUnitTypeExpressionChecker) |
165 |
| - typeOperatorCheckers.add(IrTypeOperatorTypeChecker) |
166 |
| - loopCheckers.add(IrUnitTypeExpressionChecker) |
167 |
| - breakContinueCheckers.add(IrNothingTypeExpressionChecker) |
168 |
| - returnCheckers.add(IrNothingTypeExpressionChecker) |
169 |
| - throwCheckers.add(IrNothingTypeExpressionChecker) |
170 |
| - fieldAccessExpressionCheckers.add(IrDynamicTypeFieldAccessChecker) |
| 132 | + elementCheckers.add(IrConstTypeChecker) |
| 133 | + elementCheckers.add(IrStringConcatenationTypeChecker) |
| 134 | + elementCheckers.add(IrGetObjectValueTypeChecker) |
| 135 | + elementCheckers.add(IrGetValueTypeChecker) |
| 136 | + elementCheckers.add(IrUnitTypeExpressionChecker) |
| 137 | + elementCheckers.add(IrNothingTypeExpressionChecker) |
| 138 | + elementCheckers.add(IrGetFieldTypeChecker) |
| 139 | + elementCheckers.add(IrCallTypeChecker) |
| 140 | + elementCheckers.add(IrTypeOperatorTypeChecker) |
| 141 | + elementCheckers.add(IrDynamicTypeFieldAccessChecker) |
171 | 142 | }
|
172 | 143 | if (config.checkIrExpressionBodyInFunction) {
|
173 |
| - functionCheckers.add(IrExpressionBodyInFunctionChecker) |
| 144 | + elementCheckers.add(IrExpressionBodyInFunctionChecker) |
174 | 145 | }
|
175 | 146 | if (config.checkOverridePrivateDeclaration) {
|
176 |
| - declarationBaseCheckers.add(IrPrivateDeclarationOverrideChecker) |
| 147 | + elementCheckers.add(IrPrivateDeclarationOverrideChecker) |
177 | 148 | }
|
178 | 149 | }
|
179 | 150 |
|
| 151 | + private val checkersPerElement = object : ClassValue<List<IrElementChecker<*>>>() { |
| 152 | + override fun computeValue(type: Class<*>): List<IrElementChecker<*>> = |
| 153 | + elementCheckers.filter { it.elementClass.isAssignableFrom(type) } |
| 154 | + } |
| 155 | + |
180 | 156 | override fun visitElement(element: IrElement) {
|
181 | 157 | var block = { element.acceptChildrenVoid(this) }
|
182 | 158 | for (contextUpdater in contextUpdaters) {
|
183 | 159 | val currentBlock = block
|
184 | 160 | block = { contextUpdater.runInNewContext(context, element, currentBlock) }
|
185 | 161 | }
|
186 | 162 | block()
|
187 |
| - } |
188 |
| - |
189 |
| - override fun visitConst(expression: IrConst) { |
190 |
| - super.visitConst(expression) |
191 |
| - constCheckers.check(expression, context) |
192 |
| - } |
193 |
| - |
194 |
| - override fun visitStringConcatenation(expression: IrStringConcatenation) { |
195 |
| - super.visitStringConcatenation(expression) |
196 |
| - stringConcatenationCheckers.check(expression, context) |
197 |
| - } |
198 |
| - |
199 |
| - override fun visitGetObjectValue(expression: IrGetObjectValue) { |
200 |
| - super.visitGetObjectValue(expression) |
201 |
| - getObjectValueCheckers.check(expression, context) |
202 |
| - } |
203 |
| - |
204 |
| - // TODO: visitGetEnumValue |
205 |
| - |
206 |
| - override fun visitGetValue(expression: IrGetValue) { |
207 |
| - super.visitGetValue(expression) |
208 |
| - getValueCheckers.check(expression, context) |
209 |
| - } |
210 |
| - |
211 |
| - override fun visitSetValue(expression: IrSetValue) { |
212 |
| - super.visitSetValue(expression) |
213 |
| - setValueCheckers.check(expression, context) |
214 |
| - } |
215 |
| - |
216 |
| - override fun visitGetField(expression: IrGetField) { |
217 |
| - super.visitGetField(expression) |
218 |
| - getFieldCheckers.check(expression, context) |
219 |
| - } |
220 |
| - |
221 |
| - override fun visitSetField(expression: IrSetField) { |
222 |
| - super.visitSetField(expression) |
223 |
| - setFieldCheckers.check(expression, context) |
224 |
| - } |
225 |
| - |
226 |
| - override fun visitCall(expression: IrCall) { |
227 |
| - super.visitCall(expression) |
228 |
| - callCheckers.check(expression, context) |
229 |
| - } |
230 |
| - |
231 |
| - override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) { |
232 |
| - super.visitDelegatingConstructorCall(expression) |
233 |
| - delegatingConstructorCallCheckers.check(expression, context) |
234 |
| - } |
235 |
| - |
236 |
| - override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall) { |
237 |
| - super.visitInstanceInitializerCall(expression) |
238 |
| - instanceInitializerCallCheckers.check(expression, context) |
239 |
| - } |
240 |
| - |
241 |
| - override fun visitTypeOperator(expression: IrTypeOperatorCall) { |
242 |
| - super.visitTypeOperator(expression) |
243 |
| - typeOperatorCheckers.check(expression, context) |
244 |
| - } |
245 |
| - |
246 |
| - override fun visitLoop(loop: IrLoop) { |
247 |
| - super.visitLoop(loop) |
248 |
| - loopCheckers.check(loop, context) |
249 |
| - } |
250 |
| - |
251 |
| - override fun visitBreakContinue(jump: IrBreakContinue) { |
252 |
| - super.visitBreakContinue(jump) |
253 |
| - breakContinueCheckers.check(jump, context) |
254 |
| - } |
255 |
| - |
256 |
| - override fun visitReturn(expression: IrReturn) { |
257 |
| - super.visitReturn(expression) |
258 |
| - returnCheckers.check(expression, context) |
259 |
| - } |
260 |
| - |
261 |
| - override fun visitThrow(expression: IrThrow) { |
262 |
| - super.visitThrow(expression) |
263 |
| - throwCheckers.check(expression, context) |
264 |
| - } |
265 |
| - |
266 |
| - override fun visitFunction(declaration: IrFunction) { |
267 |
| - super.visitFunction(declaration) |
268 |
| - functionCheckers.check(declaration, context) |
269 |
| - } |
270 | 163 |
|
271 |
| - override fun visitValueAccess(expression: IrValueAccessExpression) { |
272 |
| - super.visitValueAccess(expression) |
273 |
| - valueAccessCheckers.check(expression, context) |
| 164 | + for (checker in checkersPerElement.get(element.javaClass)) { |
| 165 | + @Suppress("UNCHECKED_CAST") |
| 166 | + (checker as IrElementChecker<IrElement>).check(element, context) |
| 167 | + } |
274 | 168 | }
|
275 | 169 |
|
276 |
| - override fun visitField(declaration: IrField) { |
277 |
| - super.visitField(declaration) |
278 |
| - fieldCheckers.check(declaration, context) |
| 170 | + override fun visitAnnotationUsage(annotationUsage: IrConstructorCall) { |
| 171 | + context.withinAnnotationUsageSubTree { |
| 172 | + super.visitAnnotationUsage(annotationUsage) |
| 173 | + } |
279 | 174 | }
|
280 | 175 |
|
281 |
| - override fun visitFieldAccess(expression: IrFieldAccessExpression) { |
282 |
| - super.visitFieldAccess(expression) |
283 |
| - fieldAccessExpressionCheckers.check(expression, context) |
| 176 | + override fun visitSymbol(container: IrElement, symbol: IrSymbol) { |
| 177 | + for (checker in symbolCheckers) { |
| 178 | + checker.check(symbol, container, context) |
| 179 | + } |
284 | 180 | }
|
285 | 181 |
|
286 | 182 | override fun visitType(container: IrElement, type: IrType) {
|
287 | 183 | super.visitType(container, type)
|
288 |
| - typeCheckers.check(type, container, context) |
289 |
| - } |
290 |
| - |
291 |
| - override fun visitSymbol(container: IrElement, symbol: IrSymbol) { |
292 |
| - symbolCheckers.check(symbol, container, context) |
293 |
| - } |
294 |
| - |
295 |
| - override fun visitDeclarationReference(expression: IrDeclarationReference) { |
296 |
| - super.visitDeclarationReference(expression) |
297 |
| - declarationReferenceCheckers.check(expression, context) |
298 |
| - } |
299 |
| - |
300 |
| - override fun visitDeclaration(declaration: IrDeclarationBase) { |
301 |
| - super.visitDeclaration(declaration) |
302 |
| - declarationBaseCheckers.check(declaration, context) |
303 |
| - } |
304 |
| - |
305 |
| - override fun visitPropertyReference(expression: IrPropertyReference) { |
306 |
| - super.visitPropertyReference(expression) |
307 |
| - propertyReferenceCheckers.check(expression, context) |
308 |
| - } |
309 |
| - |
310 |
| - override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference) { |
311 |
| - super.visitLocalDelegatedPropertyReference(expression) |
312 |
| - localDelegatedPropertyReferenceCheckers.check(expression, context) |
313 |
| - } |
314 |
| - |
315 |
| - override fun visitExpression(expression: IrExpression) { |
316 |
| - super.visitExpression(expression) |
317 |
| - expressionCheckers.check(expression, context) |
318 |
| - } |
319 |
| - |
320 |
| - override fun visitVararg(expression: IrVararg) { |
321 |
| - super.visitVararg(expression) |
322 |
| - varargCheckers.check(expression, context) |
323 |
| - } |
324 |
| - |
325 |
| - override fun visitValueParameter(declaration: IrValueParameter) { |
326 |
| - super.visitValueParameter(declaration) |
327 |
| - valueParameterCheckers.check(declaration, context) |
328 |
| - } |
329 |
| - |
330 |
| - override fun visitFunctionReference(expression: IrFunctionReference) { |
331 |
| - super.visitFunctionReference(expression) |
332 |
| - functionReferenceCheckers.check(expression, context) |
333 |
| - } |
334 |
| - |
335 |
| - override fun visitFunctionAccess(expression: IrFunctionAccessExpression) { |
336 |
| - super.visitFunctionAccess(expression) |
337 |
| - functionAccessCheckers.check(expression, context) |
338 |
| - } |
339 |
| - |
340 |
| - override fun visitProperty(declaration: IrProperty) { |
341 |
| - super.visitProperty(declaration) |
342 |
| - propertyCheckers.check(declaration, context) |
343 |
| - } |
344 |
| - |
345 |
| - override fun visitAnnotationUsage(annotationUsage: IrConstructorCall) { |
346 |
| - context.withinAnnotationUsageSubTree { |
347 |
| - super.visitAnnotationUsage(annotationUsage) |
| 184 | + for (checker in typeCheckers) { |
| 185 | + checker.check(type, container, context) |
348 | 186 | }
|
349 | 187 | }
|
350 | 188 | }
|
|
0 commit comments