diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/AbstractFirPropertyInitializationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/AbstractFirPropertyInitializationChecker.kt index 85ee137300e..768d3a3cb26 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/AbstractFirPropertyInitializationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/AbstractFirPropertyInitializationChecker.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.analysis.cfa +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNode import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph @@ -15,6 +16,7 @@ abstract class AbstractFirPropertyInitializationChecker { graph: ControlFlowGraph, reporter: DiagnosticReporter, data: Map, PathAwarePropertyInitializationInfo>, - properties: Set + properties: Set, + context: CheckerContext ) -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirCallsEffectAnalyzer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirCallsEffectAnalyzer.kt index f4b495535a9..a032d9da587 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirCallsEffectAnalyzer.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirCallsEffectAnalyzer.kt @@ -43,7 +43,7 @@ import kotlin.contracts.contract object FirCallsEffectAnalyzer : FirControlFlowChecker() { - override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, checkerContext: CheckerContext) { + override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) { val function = (graph.declaration as? FirFunction<*>) ?: return if (function !is FirContractDescriptionOwner) return if (function.contractDescription.coneEffects?.any { it is ConeCallsEffectDeclaration } != true) return @@ -73,10 +73,10 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() { for ((symbol, leakedPlaces) in leakedSymbols) { function.contractDescription.source?.let { - reporter.report(FirErrors.LEAKED_IN_PLACE_LAMBDA.on(it, symbol)) + reporter.report(FirErrors.LEAKED_IN_PLACE_LAMBDA.on(it, symbol), context) } leakedPlaces.forEach { - reporter.report(FirErrors.LEAKED_IN_PLACE_LAMBDA.on(it, symbol)) + reporter.report(FirErrors.LEAKED_IN_PLACE_LAMBDA.on(it, symbol), context) } } @@ -91,7 +91,7 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() { val requiredRange = effectDeclaration.kind val pathAwareInfo = invocationData.getValue(node) for (info in pathAwareInfo.values) { - if (investigate(info, symbol, requiredRange, function, reporter)) { + if (investigate(info, symbol, requiredRange, function, reporter, context)) { // To avoid duplicate reports, stop investigating remaining paths once reported. break } @@ -105,12 +105,13 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() { symbol: AbstractFirBasedSymbol<*>, requiredRange: EventOccurrencesRange, function: FirContractDescriptionOwner, - reporter: DiagnosticReporter + reporter: DiagnosticReporter, + context: CheckerContext ): Boolean { val foundRange = info[symbol] ?: EventOccurrencesRange.ZERO if (foundRange !in requiredRange) { function.contractDescription.source?.let { - reporter.report(FirErrors.WRONG_INVOCATION_KIND.on(it, symbol, requiredRange, foundRange)) + reporter.report(FirErrors.WRONG_INVOCATION_KIND.on(it, symbol, requiredRange, foundRange), context) return true } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirControlFlowAnalyzer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirControlFlowAnalyzer.kt index 23059a41cc8..15a55601371 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirControlFlowAnalyzer.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirControlFlowAnalyzer.kt @@ -29,27 +29,32 @@ class FirControlFlowAnalyzer(session: FirSession) { cfaCheckers.forEach { it.analyze(graph, reporter, context) } if (context.containingDeclarations.any { it is FirProperty || it is FirFunction<*> }) return - runAssignmentCfaCheckers(graph, reporter) + runAssignmentCfaCheckers(graph, reporter, context) } fun analyzePropertyInitializer(property: FirProperty, graph: ControlFlowGraph, context: CheckerContext, reporter: DiagnosticReporter) { if (graph.owner != null) return cfaCheckers.forEach { it.analyze(graph, reporter, context) } - runAssignmentCfaCheckers(graph, reporter) + runAssignmentCfaCheckers(graph, reporter, context) } - fun analyzePropertyAccessor(accessor: FirPropertyAccessor, graph: ControlFlowGraph, context: CheckerContext, reporter: DiagnosticReporter) { + fun analyzePropertyAccessor( + accessor: FirPropertyAccessor, + graph: ControlFlowGraph, + context: CheckerContext, + reporter: DiagnosticReporter + ) { if (graph.owner != null) return cfaCheckers.forEach { it.analyze(graph, reporter, context) } - runAssignmentCfaCheckers(graph, reporter) + runAssignmentCfaCheckers(graph, reporter, context) } - private fun runAssignmentCfaCheckers(graph: ControlFlowGraph, reporter: DiagnosticReporter) { + private fun runAssignmentCfaCheckers(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) { val properties = LocalPropertyCollector.collect(graph) if (properties.isEmpty()) return val data = PropertyInitializationInfoCollector(properties).getData(graph) - variableAssignmentCheckers.forEach { it.analyze(graph, reporter, data, properties) } + variableAssignmentCheckers.forEach { it.analyze(graph, reporter, data, properties, context) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt index 8a1fffdccf5..77f95118e22 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.cfa import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.isDefinitelyVisited +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.isLateInit @@ -23,7 +24,8 @@ object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChec graph: ControlFlowGraph, reporter: DiagnosticReporter, data: Map, PathAwarePropertyInitializationInfo>, - properties: Set + properties: Set, + context: CheckerContext ) { val localData = data.filter { val symbolFir = (it.key.fir as? FirVariableSymbol<*>)?.fir @@ -32,14 +34,15 @@ object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChec val localProperties = properties.filter { it.fir.initializer == null && it.fir.delegate == null }.toSet() - val reporterVisitor = UninitializedPropertyReporter(localData, localProperties, reporter) + val reporterVisitor = UninitializedPropertyReporter(localData, localProperties, reporter, context) graph.traverse(TraverseDirection.Forward, reporterVisitor) } private class UninitializedPropertyReporter( val data: Map, PathAwarePropertyInitializationInfo>, val localProperties: Set, - val reporter: DiagnosticReporter + val reporter: DiagnosticReporter, + val context: CheckerContext ) : ControlFlowGraphVisitorVoid() { override fun visitNode(node: CFGNode<*>) {} @@ -61,7 +64,7 @@ object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChec val kind = info[symbol] ?: EventOccurrencesRange.ZERO if (!kind.isDefinitelyVisited()) { node.fir.source?.let { - reporter.report(FirErrors.UNINITIALIZED_VARIABLE.on(it, symbol)) + reporter.report(FirErrors.UNINITIALIZED_VARIABLE.on(it, symbol), context) return true } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt index 02b2df564e2..9be1c19f66a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt @@ -36,7 +36,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull object FirReturnsImpliesAnalyzer : FirControlFlowChecker() { - override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, checkerContext: CheckerContext) { + override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) { val function = graph.declaration as? FirFunction<*> ?: return val graphRef = function.controlFlowGraphReference as FirControlFlowGraphReferenceImpl val dataFlowInfo = graphRef.dataFlowInfo @@ -62,7 +62,7 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() { if (wrongCondition) { function.contractDescription.source?.let { - reporter.report(FirErrors.WRONG_IMPLIES_CONDITION.on(it)) + reporter.report(FirErrors.WRONG_IMPLIES_CONDITION.on(it), context) } } } @@ -215,4 +215,4 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() { private fun FirFunction<*>.getParameterSymbol(index: Int): AbstractFirBasedSymbol<*> { return if (index == -1) this.symbol else this.valueParameters[index].symbol } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/cfa/FirControlFlowChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/cfa/FirControlFlowChecker.kt index 2444159e918..08ac0130776 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/cfa/FirControlFlowChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/cfa/FirControlFlowChecker.kt @@ -10,5 +10,5 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph abstract class FirControlFlowChecker { - abstract fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, checkerContext: CheckerContext) -} \ No newline at end of file + abstract fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationArgumentChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationArgumentChecker.kt index 3c0f14fea44..c0465b574f3 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationArgumentChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationArgumentChecker.kt @@ -5,21 +5,24 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.fir.FirAnnotationContainer +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.FirSymbolOwner import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0 import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirErrorNamedReference +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall import org.jetbrains.kotlin.fir.symbols.StandardClassIds -import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.expressions.* -import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.Name @@ -36,8 +39,8 @@ object FirAnnotationArgumentChecker : FirBasicDeclarationChecker() { for ((arg, _) in declarationOfAnnotation.argumentMapping ?: continue) { val expression = (arg as? FirNamedArgumentExpression)?.expression ?: arg - checkAnnotationArgumentWithSubElements(expression, context.session, reporter) - ?.let { reporter.report(expression.source, it) } + checkAnnotationArgumentWithSubElements(expression, context.session, reporter, context) + ?.let { reporter.reportOn(expression.source, it, context) } } } } @@ -45,7 +48,8 @@ object FirAnnotationArgumentChecker : FirBasicDeclarationChecker() { private fun checkAnnotationArgumentWithSubElements( expression: FirExpression, session: FirSession, - reporter: DiagnosticReporter + reporter: DiagnosticReporter, + context: CheckerContext ): FirDiagnosticFactory0? { when (expression) { is FirArrayOfCall -> { @@ -54,13 +58,13 @@ object FirAnnotationArgumentChecker : FirBasicDeclarationChecker() { for (arg in expression.argumentList.arguments) { val sourceForReport = arg.source - when (val err = checkAnnotationArgumentWithSubElements(arg, session, reporter)) { + when (val err = checkAnnotationArgumentWithSubElements(arg, session, reporter, context)) { null -> { //DO NOTHING } else -> { if (err != FirErrors.ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL) usedNonConst = true - reporter.report(sourceForReport, err) + reporter.reportOn(sourceForReport, err, context) } } } @@ -69,8 +73,8 @@ object FirAnnotationArgumentChecker : FirBasicDeclarationChecker() { } is FirVarargArgumentsExpression -> { for (arg in expression.arguments) - checkAnnotationArgumentWithSubElements(arg, session, reporter) - ?.let { reporter.report(arg.source, it) } + checkAnnotationArgumentWithSubElements(arg, session, reporter, context) + ?.let { reporter.reportOn(arg.source, it, context) } } else -> return checkAnnotationArgument(expression, session) @@ -224,14 +228,7 @@ object FirAnnotationArgumentChecker : FirBasicDeclarationChecker() { ?.toSymbol(session) ?.fir - private inline fun DiagnosticReporter.report( - source: T?, - factory: FirDiagnosticFactory0 - ) { - source?.let { report(factory.on(it)) } - } - private val CONVERSION_NAMES = listOf( "toInt", "toLong", "toShort", "toByte", "toFloat", "toDouble", "toChar", "toBoolean" ).mapTo(hashSetOf()) { Name.identifier(it) } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt index d040ea5648d..62d53ae7478 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt @@ -5,28 +5,26 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.KtNodeTypes.FUN +import org.jetbrains.kotlin.KtNodeTypes.VALUE_PARAMETER import org.jetbrains.kotlin.descriptors.ClassKind.ANNOTATION_CLASS import org.jetbrains.kotlin.descriptors.ClassKind.ENUM_CLASS -import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.* +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.StandardClassIds.primitiveArrayTypeByElementType import org.jetbrains.kotlin.fir.symbols.StandardClassIds.primitiveTypes import org.jetbrains.kotlin.fir.symbols.StandardClassIds.unsignedTypes import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.KtNodeTypes.FUN -import org.jetbrains.kotlin.KtNodeTypes.VALUE_PARAMETER -import org.jetbrains.kotlin.fir.analysis.diagnostics.* import org.jetbrains.kotlin.name.ClassId object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() { override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { if (declaration.classKind != ANNOTATION_CLASS) return - if (declaration.isLocal) reporter.report(declaration.source, FirErrors.LOCAL_ANNOTATION_CLASS_ERROR) + if (declaration.isLocal) reporter.reportOn(declaration.source, FirErrors.LOCAL_ANNOTATION_CLASS_ERROR, context) for (it in declaration.declarations) { when { @@ -34,9 +32,9 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() { for (parameter in it.valueParameters) { val source = parameter.source ?: continue if (!source.hasValOrVar()) { - reporter.report(source, FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER) + reporter.reportOn(source, FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER, context) } else if (source.hasVar()) { - reporter.report(source, FirErrors.VAR_ANNOTATION_PARAMETER) + reporter.reportOn(source, FirErrors.VAR_ANNOTATION_PARAMETER, context) } val typeRef = parameter.returnTypeRef @@ -48,7 +46,7 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() { // TODO: replace with UNRESOLVED_REFERENCE check } coneType.isNullable -> { - reporter.report(typeRef.source, FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER) + reporter.reportOn(typeRef.source, FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER, context) } classId in primitiveTypes -> { // DO NOTHING: primitives are allowed as annotation class parameter @@ -67,13 +65,13 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() { } classId == StandardClassIds.Array -> { if (!isAllowedArray(typeRef, context.session)) - reporter.report(typeRef.source, FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER) + reporter.reportOn(typeRef.source, FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER, context) } isAllowedClassKind(coneType, context.session) -> { // DO NOTHING: annotation or enum classes are allowed } else -> { - reporter.report(typeRef.source, FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER) + reporter.reportOn(typeRef.source, FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER, context) } } } @@ -89,7 +87,7 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() { // TODO: replace with origin check } else -> { - reporter.report(it.source, FirErrors.ANNOTATION_CLASS_MEMBER) + reporter.reportOn(it.source, FirErrors.ANNOTATION_CLASS_MEMBER, context) } } } @@ -134,11 +132,4 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() { return false } - - private inline fun DiagnosticReporter.report( - source: T?, - factory: FirDiagnosticFactory0 - ) { - source?.let { report(factory.on(it)) } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirCommonConstructorDelegationIssuesChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirCommonConstructorDelegationIssuesChecker.kt index f633f78c32c..29196d6b2d5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirCommonConstructorDelegationIssuesChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirCommonConstructorDelegationIssuesChecker.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.fir.FirFakeSourceElementKind -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.references.FirErrorNamedReference @@ -47,9 +47,9 @@ object FirCommonConstructorDelegationIssuesChecker : FirRegularClassChecker() { for (it in otherConstructors) { if (it.delegatedConstructor?.isThis != true) { if (it.delegatedConstructor?.source != null) { - reporter.reportPrimaryConstructorDelegationCallExpected(it.delegatedConstructor?.source) + reporter.reportOn(it.delegatedConstructor?.source, FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED, context) } else { - reporter.reportPrimaryConstructorDelegationCallExpected(it.source) + reporter.reportOn(it.source, FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED, context) } } } @@ -62,13 +62,13 @@ object FirCommonConstructorDelegationIssuesChecker : FirRegularClassChecker() { callee is FirErrorNamedReference && callee.diagnostic is ConeAmbiguityError && it.delegatedConstructor?.source?.kind is FirFakeSourceElementKind ) { - reporter.reportExplicitDelegationCallRequired(it.source) + reporter.reportOn(it.source, FirErrors.EXPLICIT_DELEGATION_CALL_REQUIRED, context) } } } cyclicConstructors.forEach { - reporter.reportCyclicConstructorDelegationCall(it.delegatedConstructor?.source) + reporter.reportOn(it.delegatedConstructor?.source, FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL, context) } } @@ -95,16 +95,4 @@ object FirCommonConstructorDelegationIssuesChecker : FirRegularClassChecker() { ?.calleeReference.safeAs() ?.resolvedSymbol ?.fir.safeAs() - - private fun DiagnosticReporter.reportCyclicConstructorDelegationCall(source: FirSourceElement?) { - source?.let { report(FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL.on(it)) } - } - - private fun DiagnosticReporter.reportPrimaryConstructorDelegationCallExpected(source: FirSourceElement?) { - source?.let { report(FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(it)) } - } - - private fun DiagnosticReporter.reportExplicitDelegationCallRequired(source: FirSourceElement?) { - source?.let { report(FirErrors.EXPLICIT_DELEGATION_CALL_REQUIRED.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt index 39e73764caf..577a93cd63e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.types.* @@ -35,7 +35,7 @@ object FirConflictingProjectionChecker : FirBasicDeclarationChecker() { is FirTypeAlias -> { for (it in declaration.typeParameters) { if (it.variance != Variance.INVARIANT) { - reporter.reportVarianceNotAllowed(it.source) + reporter.reportOn(it.source, FirErrors.VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED, context) } } checkTypeRef(declaration.expandedTypeRef, context, reporter) @@ -70,17 +70,9 @@ object FirConflictingProjectionChecker : FirBasicDeclarationChecker() { actual is ConeKotlinTypeProjectionIn && protoVariance == Variance.OUT_VARIANCE || actual is ConeKotlinTypeProjectionOut && protoVariance == Variance.IN_VARIANCE ) { - reporter.reportConflictingProjections(typeRef.source, typeRef.coneType.toString()) + reporter.reportOn(typeRef.source, FirErrors.CONFLICTING_PROJECTION, typeRef.coneType.toString(), context) return } } } - - private fun DiagnosticReporter.reportConflictingProjections(source: FirSourceElement?, desiredProjection: String) { - source?.let { report(FirErrors.CONFLICTING_PROJECTION.on(it, desiredProjection)) } - } - - private fun DiagnosticReporter.reportVarianceNotAllowed(source: FirSourceElement?) { - source?.let { report(FirErrors.VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt index a235e4583c5..4613251a767 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirRegularClass @@ -25,11 +25,11 @@ object FirConflictsChecker : FirBasicDeclarationChecker() { } inspector.functionDeclarations.forEachNonSingle { it, hint -> - reporter.reportConflictingOverloads(it.source, hint) + reporter.reportOn(it.source, FirErrors.CONFLICTING_OVERLOADS, hint, context) } inspector.otherDeclarations.forEachNonSingle { it, hint -> - reporter.reportConflictingDeclarations(it.source, hint) + reporter.reportOn(it.source, FirErrors.REDECLARATION, hint, context) } } @@ -56,12 +56,4 @@ object FirConflictsChecker : FirBasicDeclarationChecker() { inspector.collect(it) } } - - private fun DiagnosticReporter.reportConflictingOverloads(source: FirSourceElement?, declarations: String) { - source?.let { report(FirErrors.CONFLICTING_OVERLOADS.on(it, declarations)) } - } - - private fun DiagnosticReporter.reportConflictingDeclarations(source: FirSourceElement?, declarations: String) { - source?.let { report(FirErrors.REDECLARATION.on(it, declarations)) } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorAllowedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorAllowedChecker.kt index aa758f87fe6..28532e3cc63 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorAllowedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorAllowedChecker.kt @@ -5,16 +5,14 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0 import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* object FirConstructorAllowedChecker : FirConstructorChecker() { @@ -26,27 +24,20 @@ object FirConstructorAllowedChecker : FirConstructorChecker() { return } when (containingClass.classKind) { - ClassKind.OBJECT -> reporter.report(source, FirErrors.CONSTRUCTOR_IN_OBJECT) - ClassKind.INTERFACE -> reporter.report(source, FirErrors.CONSTRUCTOR_IN_INTERFACE) - ClassKind.ENUM_ENTRY -> reporter.report(source, FirErrors.CONSTRUCTOR_IN_OBJECT) + ClassKind.OBJECT -> reporter.reportOn(source, FirErrors.CONSTRUCTOR_IN_OBJECT, context) + ClassKind.INTERFACE -> reporter.reportOn(source, FirErrors.CONSTRUCTOR_IN_INTERFACE, context) + ClassKind.ENUM_ENTRY -> reporter.reportOn(source, FirErrors.CONSTRUCTOR_IN_OBJECT, context) ClassKind.ENUM_CLASS -> if (declaration.visibility != Visibilities.Private) { - reporter.report(source, FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM) + reporter.reportOn(source, FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM, context) } ClassKind.CLASS -> if (containingClass is FirRegularClass && containingClass.modality == Modality.SEALED && declaration.visibility != Visibilities.Private ) { - reporter.report(source, FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_SEALED) + reporter.reportOn(source, FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_SEALED, context) } ClassKind.ANNOTATION_CLASS -> { // DO NOTHING } } } - - private inline fun DiagnosticReporter.report( - source: T?, - factory: FirDiagnosticFactory0 - ) { - source?.let { report(factory.on(it)) } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorInInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorInInterfaceChecker.kt index 0014a41ff4a..ed2074a9df8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorInInterfaceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorInInterfaceChecker.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.hasPrimaryConstructor +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isInterface @@ -20,11 +20,7 @@ object FirConstructorInInterfaceChecker : FirRegularClassChecker() { } if (declaration.source?.hasPrimaryConstructor() == true) { - reporter.report(declaration.source) + reporter.reportOn(declaration.source, FirErrors.CONSTRUCTOR_IN_INTERFACE, context) } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.CONSTRUCTOR_IN_INTERFACE.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt index 79ca69ecef9..c2da3979e70 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt @@ -8,9 +8,9 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.extended.report import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef @@ -25,14 +25,15 @@ internal fun checkExpectDeclarationVisibilityAndBody( declaration: FirMemberDeclaration, source: FirSourceElement, modifierList: FirModifierList?, - reporter: DiagnosticReporter + reporter: DiagnosticReporter, + context: CheckerContext ) { if (declaration.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true) { if (Visibilities.isPrivate(declaration.visibility)) { - reporter.report(source, FirErrors.EXPECTED_PRIVATE_DECLARATION) + reporter.reportOn(source, FirErrors.EXPECTED_PRIVATE_DECLARATION, context) } if (declaration is FirSimpleFunction && declaration.hasBody) { - reporter.report(source, FirErrors.EXPECTED_DECLARATION_WITH_BODY) + reporter.reportOn(source, FirErrors.EXPECTED_DECLARATION_WITH_BODY, context) } } } @@ -40,7 +41,8 @@ internal fun checkExpectDeclarationVisibilityAndBody( internal fun checkPropertyInitializer( containingClass: FirRegularClass?, property: FirProperty, - reporter: DiagnosticReporter + reporter: DiagnosticReporter, + context: CheckerContext ) { val inInterface = containingClass?.isInterface == true // If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`. @@ -51,7 +53,7 @@ internal fun checkPropertyInitializer( if (isAbstract) { if (property.initializer == null && property.delegate == null && property.returnTypeRef is FirImplicitTypeRef) { property.source?.let { - reporter.report(it, FirErrors.PROPERTY_WITH_NO_TYPE_NO_INITIALIZER) + reporter.reportOn(it, FirErrors.PROPERTY_WITH_NO_TYPE_NO_INITIALIZER, context) } } return @@ -61,7 +63,7 @@ internal fun checkPropertyInitializer( val backingFieldRequired = property.hasBackingField if (inInterface && backingFieldRequired && property.hasAccessorImplementation) { property.source?.let { - // reporter.report(it, FirErrors.BACKING_FIELD_IN_INTERFACE) + // reporter.reportOn(it, FirErrors.BACKING_FIELD_IN_INTERFACE, context) } } @@ -72,16 +74,16 @@ internal fun checkPropertyInitializer( property.initializer?.source?.let { when { inInterface -> { - reporter.report(it, FirErrors.PROPERTY_INITIALIZER_IN_INTERFACE) + reporter.reportOn(it, FirErrors.PROPERTY_INITIALIZER_IN_INTERFACE, context) } isExpect -> { - reporter.report(it, FirErrors.EXPECTED_PROPERTY_INITIALIZER) + reporter.reportOn(it, FirErrors.EXPECTED_PROPERTY_INITIALIZER, context) } !backingFieldRequired -> { - // reporter.report(it, FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD) + // reporter.reportOn(it, FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD, context) } property.receiverTypeRef != null -> { - // reporter.report(it, FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD) + // reporter.reportOn(it, FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD, context) } } } @@ -90,10 +92,10 @@ internal fun checkPropertyInitializer( property.delegate?.source?.let { when { inInterface -> { - reporter.report(it, FirErrors.DELEGATED_PROPERTY_IN_INTERFACE) + reporter.reportOn(it, FirErrors.DELEGATED_PROPERTY_IN_INTERFACE, context) } isExpect -> { - reporter.report(it, FirErrors.EXPECTED_DELEGATED_PROPERTY) + reporter.reportOn(it, FirErrors.EXPECTED_DELEGATED_PROPERTY, context) } } } @@ -105,12 +107,12 @@ internal fun checkPropertyInitializer( if (backingFieldRequired && !inInterface && !property.isLateInit && !isExpect && isUninitialized && !isExternal) { property.source?.let { if (property.receiverTypeRef != null && !property.hasAccessorImplementation) { - // reporter.report(it, FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT) + // reporter.reportOn(it, FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, context) } else { if (containingClass != null || property.hasAccessorImplementation) { - // reporter.report(it, FirErrors.MUST_BE_INITIALIZED) + // reporter.reportOn(it, FirErrors.MUST_BE_INITIALIZED, context) } else { - // reporter.report(it, FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT) + // reporter.reportOn(it, FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT, context) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegationInInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegationInInterfaceChecker.kt index a30619b0675..1c6e5c72da0 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegationInInterfaceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegationInInterfaceChecker.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.KtNodeTypes -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isInterface @@ -22,12 +22,8 @@ object FirDelegationInInterfaceChecker : FirRegularClassChecker() { for (superTypeRef in declaration.superTypeRefs) { val source = superTypeRef.source ?: continue if (source.treeStructure.getParent(source.lighterASTNode)?.tokenType == KtNodeTypes.DELEGATED_SUPER_TYPE_ENTRY) { - reporter.report(source) + reporter.reportOn(source, FirErrors.DELEGATION_IN_INTERFACE, context) } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.DELEGATION_IN_INTERFACE.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegationSuperCallInEnumConstructorChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegationSuperCallInEnumConstructorChecker.kt index c4bab19cbda..d2b0b206061 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegationSuperCallInEnumConstructorChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegationSuperCallInEnumConstructorChecker.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.fir.FirFakeSourceElementKind -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isEnumClass @@ -26,12 +26,8 @@ object FirDelegationSuperCallInEnumConstructorChecker : FirRegularClassChecker() it.delegatedConstructor?.isThis == false && it.delegatedConstructor?.source?.kind !is FirFakeSourceElementKind ) { - reporter.report(it.delegatedConstructor?.source) + reporter.reportOn(it.delegatedConstructor?.source, FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR, context) } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt index 179cd7a2ff4..5dc5e0205eb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt @@ -8,9 +8,9 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.extended.report import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirValueParameter @@ -36,7 +36,7 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() { assert(declaration.name.isSpecial && declaration.name.asString() == "") { "Unexpected name: ${declaration.name.asString()} for destructuring declaration" } - checkInitializer(source, declaration.initializer, reporter) + checkInitializer(source, declaration.initializer, reporter, context) return } @@ -82,7 +82,8 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() { originalDestructuringDeclarationOrInitializerSource, diagnostic.name, originalDestructuringDeclarationType - ) + ), + context ) } is ConeAmbiguityError -> { @@ -91,7 +92,8 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() { originalDestructuringDeclarationOrInitializerSource, diagnostic.name, diagnostic.candidates - ) + ), + context ) } is ConeInapplicableCandidateError -> { @@ -100,7 +102,8 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() { FirErrors.COMPONENT_FUNCTION_ON_NULLABLE.on( originalDestructuringDeclarationOrInitializerSource, (diagnostic.candidateSymbol.fir as FirSimpleFunction).name - ) + ), + context ) } } @@ -108,7 +111,12 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() { } } - private fun checkInitializer(source: FirSourceElement, initializer: FirExpression?, reporter: DiagnosticReporter) { + private fun checkInitializer( + source: FirSourceElement, + initializer: FirExpression?, + reporter: DiagnosticReporter, + context: CheckerContext + ) { val needToReport = when (initializer) { null -> true @@ -116,7 +124,7 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() { else -> false } if (needToReport) { - reporter.report(source, FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION) + reporter.reportOn(source, FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirEnumClassSimpleChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirEnumClassSimpleChecker.kt index 5670b872be6..cec0c77f1c9 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirEnumClassSimpleChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirEnumClassSimpleChecker.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.findNonInterfaceSupertype import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isEnumClass @@ -20,19 +20,11 @@ object FirEnumClassSimpleChecker : FirRegularClassChecker() { } declaration.findNonInterfaceSupertype(context)?.let { - reporter.reportClassInSupertypeForEnum(it.source) + reporter.reportOn(it.source, FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM, context) } if (declaration.typeParameters.isNotEmpty()) { - reporter.reportTypeParametersInEnum(declaration.typeParameters.firstOrNull()?.source) + reporter.reportOn(declaration.typeParameters.firstOrNull()?.source, FirErrors.TYPE_PARAMETERS_IN_ENUM, context) } } - - private fun DiagnosticReporter.reportClassInSupertypeForEnum(source: FirSourceElement?) { - source?.let { report(FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM.on(it)) } - } - - private fun DiagnosticReporter.reportTypeParametersInEnum(source: FirSourceElement?) { - source?.let { report(FirErrors.TYPE_PARAMETERS_IN_ENUM.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExposedVisibilityDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExposedVisibilityDeclarationChecker.kt index f30329addc2..de888202952 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExposedVisibilityDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExposedVisibilityDeclarationChecker.kt @@ -5,15 +5,16 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.FirEffectiveVisibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibilityImpl import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory3 import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.getEffectiveVisibility import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved @@ -51,12 +52,13 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() { } val restricting = supertype.findVisibilityExposure(context, classVisibility) if (restricting != null) { - reporter.reportExposure( + reporter.reportOn( + supertypeRef.source ?: declaration.source, if (isInterface) FirErrors.EXPOSED_SUPER_INTERFACE else FirErrors.EXPOSED_SUPER_CLASS, - restricting, classVisibility, + restricting, restricting.getEffectiveVisibility(context), - supertypeRef.source ?: declaration.source + context ) } } @@ -70,12 +72,13 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() { for (bound in parameter.symbol.fir.bounds) { val restricting = bound.coneType.findVisibilityExposure(context, classVisibility) if (restricting != null) { - reporter.reportExposure( + reporter.reportOn( + bound.source, FirErrors.EXPOSED_TYPE_PARAMETER_BOUND, - restricting, classVisibility, + restricting, restricting.getEffectiveVisibility(context), - bound.source + context ) } } @@ -89,12 +92,13 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() { if (typeAliasVisibility == FirEffectiveVisibilityImpl.Local) return val restricting = expandedType?.findVisibilityExposure(context, typeAliasVisibility) if (restricting != null) { - reporter.reportExposure( + reporter.reportOn( + declaration.source, FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE, - restricting, typeAliasVisibility, + restricting, restricting.getEffectiveVisibility(context), - declaration.source + context ) } } @@ -107,12 +111,13 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() { val restricting = declaration.returnTypeRef.coneTypeSafe() ?.findVisibilityExposure(context, functionVisibility) if (restricting != null) { - reporter.reportExposure( + reporter.reportOn( + declaration.source, FirErrors.EXPOSED_FUNCTION_RETURN_TYPE, - restricting, functionVisibility, + restricting, restricting.getEffectiveVisibility(context), - declaration.source + context ) } } @@ -122,12 +127,13 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() { valueParameter.returnTypeRef.coneTypeSafe() ?.findVisibilityExposure(context, functionVisibility) if (restricting != null) { - reporter.reportExposure( + reporter.reportOn( + valueParameter.source, FirErrors.EXPOSED_PARAMETER_TYPE, - restricting, functionVisibility, + restricting, restricting.getEffectiveVisibility(context), - valueParameter.source + context ) } } @@ -143,12 +149,13 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() { declaration.returnTypeRef.coneTypeSafe() ?.findVisibilityExposure(context, propertyVisibility) if (restricting != null) { - reporter.reportExposure( + reporter.reportOn( + declaration.source, FirErrors.EXPOSED_PROPERTY_TYPE, - restricting, propertyVisibility, + restricting, restricting.getEffectiveVisibility(context), - declaration.source + context ) } checkMemberReceiver(declaration.receiverTypeRef, declaration, reporter, context) @@ -167,12 +174,13 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() { if (memberVisibility == FirEffectiveVisibilityImpl.Local) return val restricting = receiverParameterType.findVisibilityExposure(context, memberVisibility) if (restricting != null) { - reporter.reportExposure( + reporter.reportOn( + typeRef.source, FirErrors.EXPOSED_RECEIVER_TYPE, - restricting, memberVisibility, + restricting, restricting.getEffectiveVisibility(context), - typeRef.source + context ) } } @@ -207,25 +215,6 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() { return null } - private inline fun DiagnosticReporter.reportExposure( - error: FirDiagnosticFactory3, - restrictingDeclaration: FirMemberDeclaration, - elementVisibility: FirEffectiveVisibility, - restrictingVisibility: FirEffectiveVisibility, - source: FirSourceElement? - ) { - source?.let { - report( - error.on( - it as E, - elementVisibility, - restrictingDeclaration, - restrictingVisibility - ) - ) - } - } - private fun FirMemberDeclaration.getEffectiveVisibility(context: CheckerContext) = getEffectiveVisibility(context.session, context.containingDeclarations, context.sessionHolder.scopeSession) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirFunctionNameChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirFunctionNameChecker.kt index 63b7a9d3508..87d756fbd99 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirFunctionNameChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirFunctionNameChecker.kt @@ -7,9 +7,9 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.extended.report import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFunction @@ -23,7 +23,7 @@ object FirFunctionNameChecker : FirFunctionChecker() { val containingDeclaration = context.containingDeclarations.lastOrNull() val isNonLocal = containingDeclaration is FirFile || containingDeclaration is FirClass<*> if (declaration is FirSimpleFunction && declaration.name == SpecialNames.NO_NAME_PROVIDED && isNonLocal) { - reporter.report(source, FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME) + reporter.reportOn(source, FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME, context) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt index 722870933e3..a06ccdc442a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt @@ -10,7 +10,8 @@ import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.isLateInit import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeTypeParameterType import org.jetbrains.kotlin.fir.types.coneType @@ -40,28 +41,28 @@ object FirInapplicableLateinitChecker : FirPropertyChecker() { when { declaration.isVal -> - reporter.report(declaration.source, "is allowed only on mutable properties") + reporter.reportOn(declaration.source, "is allowed only on mutable properties", context) declaration.initializer != null -> if (declaration.isLocal) { - reporter.report(declaration.source, "is not allowed on local variables with initializer") + reporter.reportOn(declaration.source, "is not allowed on local variables with initializer", context) } else { - reporter.report(declaration.source, "is not allowed on properties with initializer") + reporter.reportOn(declaration.source, "is not allowed on properties with initializer", context) } declaration.delegate != null -> - reporter.report(declaration.source, "is not allowed on delegated properties") + reporter.reportOn(declaration.source, "is not allowed on delegated properties", context) declaration.isNullable() -> - reporter.report(declaration.source, "is not allowed on properties of a type with nullable upper bound") + reporter.reportOn(declaration.source, "is not allowed on properties of a type with nullable upper bound", context) declaration.returnTypeRef.coneType in getPrimitiveTypes(context) -> if (declaration.isLocal) { - reporter.report(declaration.source, "is not allowed on local variables of primitive types") + reporter.reportOn(declaration.source, "is not allowed on local variables of primitive types", context) } else { - reporter.report(declaration.source, "is not allowed on properties of primitive types") + reporter.reportOn(declaration.source, "is not allowed on properties of primitive types", context) } declaration.hasGetter() || declaration.hasSetter() -> - reporter.report(declaration.source, "is not allowed on properties with a custom getter or setter") + reporter.reportOn(declaration.source, "is not allowed on properties with a custom getter or setter", context) } } @@ -73,7 +74,7 @@ object FirInapplicableLateinitChecker : FirPropertyChecker() { private fun FirProperty.hasGetter() = getter != null && getter?.source != null && getter?.source?.kind !is FirFakeSourceElementKind private fun FirProperty.hasSetter() = setter != null && setter?.source != null && setter?.source?.kind !is FirFakeSourceElementKind - private fun DiagnosticReporter.report(source: FirSourceElement?, target: String) { - source?.let { report(FirErrors.INAPPLICABLE_LATEINIT_MODIFIER.on(it, target)) } + private fun DiagnosticReporter.reportOn(source: FirSourceElement?, target: String, context: CheckerContext) { + source?.let { report(FirErrors.INAPPLICABLE_LATEINIT_MODIFIER.on(it, target), context) } } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInfixFunctionDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInfixFunctionDeclarationChecker.kt index 4b643cb0ca2..d291b6d1494 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInfixFunctionDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInfixFunctionDeclarationChecker.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction @@ -18,12 +18,12 @@ object FirInfixFunctionDeclarationChecker : FirMemberDeclarationChecker() { override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { if (declaration is FirSimpleFunction && declaration.isInfix) { if (declaration.valueParameters.size != 1 || !hasExtensionOrDispatchReceiver(declaration, context)) { - reporter.report(declaration.source) + reporter.reportOn(declaration.source, FirErrors.INAPPLICABLE_INFIX_MODIFIER, context) } return } if (declaration.isInfix) { - reporter.report(declaration.source) + reporter.reportOn(declaration.source, FirErrors.INAPPLICABLE_INFIX_MODIFIER, context) } } @@ -34,8 +34,4 @@ object FirInfixFunctionDeclarationChecker : FirMemberDeclarationChecker() { if (function.receiverTypeRef != null) return true return context.containingDeclarations.lastOrNull() is FirClass<*> } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.INAPPLICABLE_INFIX_MODIFIER.on(it, "Inapplicable infix modifier")) } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInterfaceWithSuperclassChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInterfaceWithSuperclassChecker.kt index 24e69261a20..a062081d76f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInterfaceWithSuperclassChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInterfaceWithSuperclassChecker.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.findNonInterfaceSupertype import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isInterface @@ -20,11 +20,7 @@ object FirInterfaceWithSuperclassChecker : FirRegularClassChecker() { } declaration.findNonInterfaceSupertype(context)?.let { - reporter.report(it.source) + reporter.reportOn(it.source, FirErrors.INTERFACE_WITH_SUPERCLASS, context) } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.INTERFACE_WITH_SUPERCLASS.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalEntityNotAllowedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalEntityNotAllowedChecker.kt index babb18bdbe3..dffc6a52bcb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalEntityNotAllowedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalEntityNotAllowedChecker.kt @@ -6,15 +6,14 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isCompanion import org.jetbrains.kotlin.fir.declarations.visibility -import org.jetbrains.kotlin.name.Name object FirLocalEntityNotAllowedChecker : FirRegularClassChecker() { override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { @@ -24,19 +23,11 @@ object FirLocalEntityNotAllowedChecker : FirRegularClassChecker() { when { declaration.classKind == ClassKind.OBJECT && !declaration.isCompanion -> - reporter.reportLocalObjectNotAllowed(declaration.source, declaration.name) + reporter.reportOn(declaration.source, FirErrors.LOCAL_OBJECT_NOT_ALLOWED, declaration.name, context) declaration.classKind == ClassKind.INTERFACE -> - reporter.reportLocalInterfaceNotAllowed(declaration.source, declaration.name) + reporter.reportOn(declaration.source, FirErrors.LOCAL_INTERFACE_NOT_ALLOWED, declaration.name, context) else -> { } } } - - private fun DiagnosticReporter.reportLocalObjectNotAllowed(source: FirSourceElement?, name: Name) { - source?.let { report(FirErrors.LOCAL_OBJECT_NOT_ALLOWED.on(it, name)) } - } - - private fun DiagnosticReporter.reportLocalInterfaceNotAllowed(source: FirSourceElement?, name: Name) { - source?.let { report(FirErrors.LOCAL_INTERFACE_NOT_ALLOWED.on(it, name)) } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirManyCompanionObjectsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirManyCompanionObjectsChecker.kt index 4ed2484a370..c68305b3d11 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirManyCompanionObjectsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirManyCompanionObjectsChecker.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isCompanion @@ -19,14 +19,10 @@ object FirManyCompanionObjectsChecker : FirRegularClassChecker() { for (it in declaration.declarations) { if (it is FirRegularClass && it.isCompanion) { if (hasCompanion) { - reporter.report(it.source) + reporter.reportOn(it.source, FirErrors.MANY_COMPANION_OBJECTS, context) } hasCompanion = true } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.MANY_COMPANION_OBJECTS.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberFunctionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberFunctionChecker.kt index abf01537ef5..901f4f9ce3c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberFunctionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberFunctionChecker.kt @@ -8,9 +8,9 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.extended.report import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.lexer.KtTokens @@ -39,10 +39,13 @@ object FirMemberFunctionChecker : FirRegularClassChecker() { val isAbstract = function.isAbstract || hasAbstractModifier if (isAbstract) { if (!containingDeclaration.canHaveAbstractDeclaration) { - reporter.report(FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(source, function, containingDeclaration)) + reporter.report( + FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(source, function, containingDeclaration), + context + ) } if (function.hasBody) { - reporter.report(FirErrors.ABSTRACT_FUNCTION_WITH_BODY.on(source, function)) + reporter.report(FirErrors.ABSTRACT_FUNCTION_WITH_BODY.on(source, function), context) } } val isInsideExpectClass = isInsideExpectClass(containingDeclaration, context) @@ -51,17 +54,16 @@ object FirMemberFunctionChecker : FirRegularClassChecker() { if (!function.hasBody) { if (containingDeclaration.isInterface) { if (Visibilities.isPrivate(function.visibility)) { - reporter.report(FirErrors.PRIVATE_FUNCTION_WITH_NO_BODY.on(source, function)) + reporter.reportOn(source, FirErrors.PRIVATE_FUNCTION_WITH_NO_BODY, function, context) } if (!isInsideExpectClass && !hasAbstractModifier && hasOpenModifier) { - reporter.report(source, FirErrors.REDUNDANT_OPEN_IN_INTERFACE) + reporter.reportOn(source, FirErrors.REDUNDANT_OPEN_IN_INTERFACE, context) } } else if (!isInsideExpectClass && !hasAbstractModifier && !isExternal) { - reporter.report(FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(source, function)) + reporter.reportOn(source, FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, function, context) } } - checkExpectDeclarationVisibilityAndBody(function, source, modifierList, reporter) + checkExpectDeclarationVisibilityAndBody(function, source, modifierList, reporter, context) } - } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertyChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertyChecker.kt index bf3db33af6c..33bfa76a7c3 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertyChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertyChecker.kt @@ -9,9 +9,9 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.extended.report import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.expressions.FirExpression @@ -47,37 +47,43 @@ object FirMemberPropertyChecker : FirRegularClassChecker() { (property.getter == null || property.getter is FirDefaultPropertyAccessor) ) { property.source?.let { - reporter.report(it, FirErrors.PRIVATE_PROPERTY_IN_INTERFACE) + reporter.reportOn(it, FirErrors.PRIVATE_PROPERTY_IN_INTERFACE, context) } } if (isAbstract) { if (!containingDeclaration.canHaveAbstractDeclaration) { property.source?.let { - reporter.report(FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(it, property, containingDeclaration)) + reporter.reportOn( + it, + FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, + property, + containingDeclaration, + context + ) return } } property.initializer?.source?.let { - reporter.report(it, FirErrors.ABSTRACT_PROPERTY_WITH_INITIALIZER) + reporter.reportOn(it, FirErrors.ABSTRACT_PROPERTY_WITH_INITIALIZER, context) } property.delegate?.source?.let { - reporter.report(it, FirErrors.ABSTRACT_DELEGATED_PROPERTY) + reporter.reportOn(it, FirErrors.ABSTRACT_DELEGATED_PROPERTY, context) } checkAccessor(property.getter, property.delegate) { src, _ -> - reporter.report(src, FirErrors.ABSTRACT_PROPERTY_WITH_GETTER) + reporter.reportOn(src, FirErrors.ABSTRACT_PROPERTY_WITH_GETTER, context) } checkAccessor(property.setter, property.delegate) { src, symbol -> if (symbol.fir.visibility == Visibilities.Private && property.visibility != Visibilities.Private) { - reporter.report(src, FirErrors.PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY) + reporter.reportOn(src, FirErrors.PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY, context) } else { - reporter.report(src, FirErrors.ABSTRACT_PROPERTY_WITH_SETTER) + reporter.reportOn(src, FirErrors.ABSTRACT_PROPERTY_WITH_SETTER, context) } } } - checkPropertyInitializer(containingDeclaration, property, reporter) + checkPropertyInitializer(containingDeclaration, property, reporter, context) val hasOpenModifier = modifierList?.modifiers?.any { it.token == KtTokens.OPEN_KEYWORD } == true if (hasOpenModifier && @@ -87,19 +93,19 @@ object FirMemberPropertyChecker : FirRegularClassChecker() { !isInsideExpectClass(containingDeclaration, context) ) { property.source?.let { - reporter.report(it, FirErrors.REDUNDANT_OPEN_IN_INTERFACE) + reporter.reportOn(it, FirErrors.REDUNDANT_OPEN_IN_INTERFACE, context) } } val isOpen = property.isOpen || hasOpenModifier if (isOpen) { checkAccessor(property.setter, property.delegate) { src, symbol -> if (symbol.fir.visibility == Visibilities.Private && property.visibility != Visibilities.Private) { - reporter.report(src, FirErrors.PRIVATE_SETTER_FOR_OPEN_PROPERTY) + reporter.reportOn(src, FirErrors.PRIVATE_SETTER_FOR_OPEN_PROPERTY, context) } } } - checkExpectDeclarationVisibilityAndBody(property, source, modifierList, reporter) + checkExpectDeclarationVisibilityAndBody(property, source, modifierList, reporter, context) } private fun checkAccessor( diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMethodOfAnyImplementedInInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMethodOfAnyImplementedInInterfaceChecker.kt index fcc41268fb6..e36393679ea 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMethodOfAnyImplementedInInterfaceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMethodOfAnyImplementedInInterfaceChecker.kt @@ -5,12 +5,12 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -64,12 +64,8 @@ object FirMethodOfAnyImplementedInInterfaceChecker : FirRegularClassChecker(), F val inspector = getInspector(context) if (it is FirSimpleFunction && inspector.contains(it) && it.body != null && it.isOverride) { - reporter.report(it.source) + reporter.reportOn(it.source, FirErrors.ANY_METHOD_IMPLEMENTED_IN_INTERFACE, context) } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.ANY_METHOD_IMPLEMENTED_IN_INTERFACE.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierChecker.kt index 9612745ddc6..95140abcea0 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirModifierChecker.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.KtNodeTypes -import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors @@ -103,7 +103,8 @@ object FirModifierChecker : FirBasicDeclarationChecker() { secondModifier: FirModifier<*>, reporter: DiagnosticReporter, reportedNodes: MutableSet>, - owner: FirDeclaration? + owner: FirDeclaration?, + context: CheckerContext ) { val firstToken = firstModifier.token val secondToken = secondModifier.token @@ -111,21 +112,21 @@ object FirModifierChecker : FirBasicDeclarationChecker() { CompatibilityType.COMPATIBLE -> { } CompatibilityType.REPEATED -> - if (reportedNodes.add(secondModifier)) reporter.reportRepeatedModifier(secondModifier, secondToken) + if (reportedNodes.add(secondModifier)) reporter.reportRepeatedModifier(secondModifier, secondToken, context) CompatibilityType.REDUNDANT_2_TO_1 -> - reporter.reportRedundantModifier(secondModifier, secondToken, firstToken) + reporter.reportRedundantModifier(secondModifier, secondToken, firstToken, context) CompatibilityType.REDUNDANT_1_TO_2 -> - reporter.reportRedundantModifier(firstModifier, firstToken, secondToken) + reporter.reportRedundantModifier(firstModifier, firstToken, secondToken, context) CompatibilityType.DEPRECATED -> { - reporter.reportDeprecatedModifierPair(firstModifier, firstToken, secondToken) - reporter.reportDeprecatedModifierPair(secondModifier, secondToken, firstToken) + reporter.reportDeprecatedModifierPair(firstModifier, firstToken, secondToken, context) + reporter.reportDeprecatedModifierPair(secondModifier, secondToken, firstToken, context) } CompatibilityType.INCOMPATIBLE, CompatibilityType.COMPATIBLE_FOR_CLASSES -> { if (compatibilityType == CompatibilityType.COMPATIBLE_FOR_CLASSES && owner is FirClass<*>) { return } - if (reportedNodes.add(firstModifier)) reporter.reportIncompatibleModifiers(firstModifier, firstToken, secondToken) - if (reportedNodes.add(secondModifier)) reporter.reportIncompatibleModifiers(secondModifier, secondToken, firstToken) + if (reportedNodes.add(firstModifier)) reporter.reportIncompatibleModifiers(firstModifier, firstToken, secondToken, context) + if (reportedNodes.add(secondModifier)) reporter.reportIncompatibleModifiers(secondModifier, secondToken, firstToken, context) } } } @@ -133,7 +134,8 @@ object FirModifierChecker : FirBasicDeclarationChecker() { private fun checkModifiers( list: FirModifierList, owner: FirDeclaration, - reporter: DiagnosticReporter + reporter: DiagnosticReporter, + context: CheckerContext ) { // general strategy: report no more than one error and any number of warnings // therefore, a track of nodes with already reported errors should be kept @@ -145,7 +147,7 @@ object FirModifierChecker : FirBasicDeclarationChecker() { if (firstModifier == secondModifier) { break } - checkCompatibilityType(firstModifier, secondModifier, reporter, reportedNodes, owner) + checkCompatibilityType(firstModifier, secondModifier, reporter, reportedNodes, owner, context) } } } @@ -168,30 +170,30 @@ object FirModifierChecker : FirBasicDeclarationChecker() { if (context.containingDeclarations.last() is FirDefaultPropertyAccessor) return val modifierList = with(FirModifierList) { source.getModifierList() } - modifierList?.let { checkModifiers(it, declaration, reporter) } + modifierList?.let { checkModifiers(it, declaration, reporter, context) } } private fun DiagnosticReporter.reportRepeatedModifier( - modifier: FirModifier<*>, keyword: KtModifierKeywordToken + modifier: FirModifier<*>, keyword: KtModifierKeywordToken, context: CheckerContext ) { - report(FirErrors.REPEATED_MODIFIER.on(modifier.source, keyword)) + report(FirErrors.REPEATED_MODIFIER.on(modifier.source, keyword), context) } private fun DiagnosticReporter.reportRedundantModifier( - modifier: FirModifier<*>, firstKeyword: KtModifierKeywordToken, secondKeyword: KtModifierKeywordToken + modifier: FirModifier<*>, firstKeyword: KtModifierKeywordToken, secondKeyword: KtModifierKeywordToken, context: CheckerContext ) { - report(FirErrors.REDUNDANT_MODIFIER.on(modifier.source, firstKeyword, secondKeyword)) + report(FirErrors.REDUNDANT_MODIFIER.on(modifier.source, firstKeyword, secondKeyword), context) } private fun DiagnosticReporter.reportDeprecatedModifierPair( - modifier: FirModifier<*>, firstKeyword: KtModifierKeywordToken, secondKeyword: KtModifierKeywordToken + modifier: FirModifier<*>, firstKeyword: KtModifierKeywordToken, secondKeyword: KtModifierKeywordToken, context: CheckerContext ) { - report(FirErrors.DEPRECATED_MODIFIER_PAIR.on(modifier.source, firstKeyword, secondKeyword)) + report(FirErrors.DEPRECATED_MODIFIER_PAIR.on(modifier.source, firstKeyword, secondKeyword), context) } private fun DiagnosticReporter.reportIncompatibleModifiers( - modifier: FirModifier<*>, firstKeyword: KtModifierKeywordToken, secondKeyword: KtModifierKeywordToken + modifier: FirModifier<*>, firstKeyword: KtModifierKeywordToken, secondKeyword: KtModifierKeywordToken, context: CheckerContext ) { - report(FirErrors.INCOMPATIBLE_MODIFIERS.on(modifier.source, firstKeyword, secondKeyword)) + report(FirErrors.INCOMPATIBLE_MODIFIERS.on(modifier.source, firstKeyword, secondKeyword), context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt index bd020bdebd7..c059eb565ec 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.containingClass import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap @@ -106,6 +107,7 @@ object FirOverrideChecker : FirRegularClassChecker() { private fun FirCallableMemberDeclaration<*>.checkVisibility( reporter: DiagnosticReporter, overriddenSymbols: List>, + context: CheckerContext ) { val visibilities = overriddenSymbols.mapNotNull { if (it.fir !is FirMemberDeclaration) return@mapNotNull null @@ -122,7 +124,7 @@ object FirOverrideChecker : FirRegularClassChecker() { // reporter.reportCannotChangeAccessPrivilege(this, overridden.fir) return } else if (compare < 0) { - reporter.reportCannotWeakenAccessPrivilege(this, overridden.fir) + reporter.reportCannotWeakenAccessPrivilege(this, overridden.fir, context) return } } @@ -169,15 +171,15 @@ object FirOverrideChecker : FirRegularClassChecker() { val overriddenFunctionSymbols = firTypeScope.retrieveDirectOverriddenOf(function) if (overriddenFunctionSymbols.isEmpty()) { - reporter.reportNothingToOverride(function) + reporter.reportNothingToOverride(function, context) return } checkModality(overriddenFunctionSymbols)?.let { - reporter.reportOverridingFinalMember(function, it) + reporter.reportOverridingFinalMember(function, it, context) } - function.checkVisibility(reporter, overriddenFunctionSymbols) + function.checkVisibility(reporter, overriddenFunctionSymbols, context) val restriction = function.checkReturnType( overriddenSymbols = overriddenFunctionSymbols, @@ -186,7 +188,7 @@ object FirOverrideChecker : FirRegularClassChecker() { ) restriction?.let { - reporter.reportReturnTypeMismatchOnFunction(function, it) + reporter.reportReturnTypeMismatchOnFunction(function, it, context) } } @@ -204,19 +206,19 @@ object FirOverrideChecker : FirRegularClassChecker() { val overriddenPropertySymbols = firTypeScope.retrieveDirectOverriddenOf(property) if (overriddenPropertySymbols.isEmpty()) { - reporter.reportNothingToOverride(property) + reporter.reportNothingToOverride(property, context) return } checkModality(overriddenPropertySymbols)?.let { - reporter.reportOverridingFinalMember(property, it) + reporter.reportOverridingFinalMember(property, it, context) } property.checkMutability(overriddenPropertySymbols)?.let { - reporter.reportVarOverriddenByVal(property, it) + reporter.reportVarOverriddenByVal(property, it, context) } - property.checkVisibility(reporter, overriddenPropertySymbols) + property.checkVisibility(reporter, overriddenPropertySymbols, context) val restriction = property.checkReturnType( overriddenSymbols = overriddenPropertySymbols, @@ -226,76 +228,91 @@ object FirOverrideChecker : FirRegularClassChecker() { restriction?.let { if (property.isVar) { - reporter.reportTypeMismatchOnVariable(property, it) + reporter.reportTypeMismatchOnVariable(property, it, context) } else { - reporter.reportTypeMismatchOnProperty(property, it) + reporter.reportTypeMismatchOnProperty(property, it, context) } } } - private fun DiagnosticReporter.reportNothingToOverride(declaration: FirMemberDeclaration) { + private fun DiagnosticReporter.reportNothingToOverride(declaration: FirMemberDeclaration, context: CheckerContext) { // TODO: not ready yet, e.g., Collections - // declaration.source?.let { report(FirErrors.NOTHING_TO_OVERRIDE.on(it, declaration)) } + // reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context) } private fun DiagnosticReporter.reportOverridingFinalMember( overriding: FirMemberDeclaration, overridden: FirCallableDeclaration<*>, + context: CheckerContext ) { overriding.source?.let { source -> overridden.containingClass()?.let { containingClass -> - report(FirErrors.OVERRIDING_FINAL_MEMBER.on(source, overridden, containingClass.name)) + report(FirErrors.OVERRIDING_FINAL_MEMBER.on(source, overridden, containingClass.name), context) } } } private fun DiagnosticReporter.reportVarOverriddenByVal( overriding: FirMemberDeclaration, - overridden: FirMemberDeclaration + overridden: FirMemberDeclaration, + context: CheckerContext ) { - overriding.source?.let { report(FirErrors.VAR_OVERRIDDEN_BY_VAL.on(it, overriding, overridden)) } + overriding.source?.let { report(FirErrors.VAR_OVERRIDDEN_BY_VAL.on(it, overriding, overridden), context) } } private fun DiagnosticReporter.reportCannotWeakenAccessPrivilege( overriding: FirMemberDeclaration, overridden: FirCallableDeclaration<*>, + context: CheckerContext ) { - overriding.source?.let { source -> - overridden.containingClass()?.let { containingClass -> - report(FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(source, overriding.visibility, overridden, containingClass.name)) - } - } + val containingClass = overridden.containingClass() ?: return + reportOn( + overriding.source, + FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE, + overriding.visibility, + overridden, + containingClass.name, + context + ) } private fun DiagnosticReporter.reportCannotChangeAccessPrivilege( overriding: FirMemberDeclaration, overridden: FirCallableDeclaration<*>, + context: CheckerContext ) { - overriding.source?.let { source -> - overridden.containingClass()?.let { containingClass -> - report(FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE.on(source, overriding.visibility, overridden, containingClass.name)) - } - } + val containingClass = overridden.containingClass() ?: return + reportOn( + overriding.source, + FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE, + overriding.visibility, + overridden, + containingClass.name, + context + ) } private fun DiagnosticReporter.reportReturnTypeMismatchOnFunction( overriding: FirMemberDeclaration, - overridden: FirMemberDeclaration + overridden: FirMemberDeclaration, + context: CheckerContext ) { - overriding.source?.let { report(FirErrors.RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(it, overriding, overridden)) } + reportOn(overriding.source, FirErrors.RETURN_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context) } private fun DiagnosticReporter.reportTypeMismatchOnProperty( overriding: FirMemberDeclaration, - overridden: FirMemberDeclaration + overridden: FirMemberDeclaration, + context: CheckerContext ) { - overriding.source?.let { report(FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(it, overriding, overridden)) } + reportOn(overriding.source, FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context) } private fun DiagnosticReporter.reportTypeMismatchOnVariable( overriding: FirMemberDeclaration, - overridden: FirMemberDeclaration + overridden: FirMemberDeclaration, + context: CheckerContext ) { - overriding.source?.let { report(FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE.on(it, overriding, overridden)) } + reportOn(overriding.source, FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorRequiredForDataClassChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorRequiredForDataClassChecker.kt index 13a6f08b72b..df961f6f436 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorRequiredForDataClassChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorRequiredForDataClassChecker.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isData @@ -23,11 +23,7 @@ object FirPrimaryConstructorRequiredForDataClassChecker : FirRegularClassChecker val hasPrimaryConstructor = declaration.declarations.any { it is FirConstructor && it.isPrimary } if (!hasPrimaryConstructor) { - reporter.report(declaration.source) + reporter.reportOn(declaration.source, FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, context) } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt index 426eb1c460b..73151cf1fc2 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.types.ConeClassLikeType @@ -55,7 +55,7 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() { ?: continue if (fir.status.modality == Modality.SEALED && classId.outerClassId != null) { - reporter.report(it.source) + reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context) return } } @@ -77,7 +77,7 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() { ?: continue if (fir.status.modality == Modality.SEALED) { - reporter.reportInLocal(it.source) + reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE_IN_LOCAL_CLASS, context) return } } @@ -99,17 +99,9 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() { ?: continue if (fir.status.modality == Modality.SEALED && !context.containingDeclarations.contains(fir)) { - reporter.report(it.source) + reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context) return } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.SEALED_SUPERTYPE.on(it)) } - } - - private fun DiagnosticReporter.reportInLocal(source: FirSourceElement?) { - source?.let { report(FirErrors.SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypeInitializedInInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypeInitializedInInterfaceChecker.kt index 3e4c655da9e..a09f7132e4a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypeInitializedInInterfaceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypeInitializedInInterfaceChecker.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.KtNodeTypes -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isInterface @@ -22,12 +22,8 @@ object FirSupertypeInitializedInInterfaceChecker : FirRegularClassChecker() { for (superTypeRef in declaration.superTypeRefs) { val source = superTypeRef.source ?: continue if (source.treeStructure.getParent(source.lighterASTNode)?.tokenType == KtNodeTypes.CONSTRUCTOR_CALLEE) { - reporter.report(source) + reporter.reportOn(source, FirErrors.SUPERTYPE_INITIALIZED_IN_INTERFACE, context) } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.SUPERTYPE_INITIALIZED_IN_INTERFACE.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypeInitializedWithoutPrimaryConstructor.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypeInitializedWithoutPrimaryConstructor.kt index fa9782af05e..f350c6d450c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypeInitializedWithoutPrimaryConstructor.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypeInitializedWithoutPrimaryConstructor.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.KtNodeTypes -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.isInterface @@ -27,12 +27,8 @@ object FirSupertypeInitializedWithoutPrimaryConstructor : FirRegularClassChecker for (superTypeRef in declaration.superTypeRefs) { val source = superTypeRef.source ?: continue if (source.treeStructure.getParent(source.lighterASTNode)?.tokenType == KtNodeTypes.CONSTRUCTOR_CALLEE) { - reporter.report(declaration.source) + reporter.reportOn(declaration.source, FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR, context) } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR.on(it)) } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionChecker.kt index 67be9cc6bed..f2645db7b6a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionChecker.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.lexer.KtTokens @@ -17,12 +18,12 @@ object FirTopLevelFunctionChecker : FirFileChecker() { override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) { for (topLevelDeclaration in declaration.declarations) { if (topLevelDeclaration is FirSimpleFunction) { - checkFunction(topLevelDeclaration, reporter) + checkFunction(topLevelDeclaration, reporter, context) } } } - private fun checkFunction(function: FirSimpleFunction, reporter: DiagnosticReporter) { + private fun checkFunction(function: FirSimpleFunction, reporter: DiagnosticReporter, context: CheckerContext) { val source = function.source ?: return if (source.kind is FirFakeSourceElementKind) return // If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`. @@ -32,9 +33,9 @@ object FirTopLevelFunctionChecker : FirFileChecker() { if (function.isExternal || modifierList?.modifiers?.any { it.token == KtTokens.EXTERNAL_KEYWORD } == true) return val isExpect = function.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true if (!function.hasBody && !isExpect) { - reporter.report(FirErrors.NON_MEMBER_FUNCTION_NO_BODY.on(source, function)) + reporter.reportOn(source, FirErrors.NON_MEMBER_FUNCTION_NO_BODY, function, context) } - checkExpectDeclarationVisibilityAndBody(function, source, modifierList, reporter) + checkExpectDeclarationVisibilityAndBody(function, source, modifierList, reporter, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertyChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertyChecker.kt index 1e3d5d99ee1..5457d3ea13f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertyChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertyChecker.kt @@ -16,17 +16,17 @@ object FirTopLevelPropertyChecker : FirFileChecker() { override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) { for (topLevelDeclaration in declaration.declarations) { if (topLevelDeclaration is FirProperty) { - checkProperty(topLevelDeclaration, reporter) + checkProperty(topLevelDeclaration, reporter, context) } } } - private fun checkProperty(property: FirProperty, reporter: DiagnosticReporter) { + private fun checkProperty(property: FirProperty, reporter: DiagnosticReporter, context: CheckerContext) { val source = property.source ?: return if (source.kind is FirFakeSourceElementKind) return val modifierList = with(FirModifierList) { source.getModifierList() } - checkPropertyInitializer(null, property, reporter) - checkExpectDeclarationVisibilityAndBody(property, source, modifierList, reporter) + checkPropertyInitializer(null, property, reporter, context) + checkExpectDeclarationVisibilityAndBody(property, source, modifierList, reporter, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTypeParametersInObjectChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTypeParametersInObjectChecker.kt index 33404a70708..a0fa3fe7bb4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTypeParametersInObjectChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTypeParametersInObjectChecker.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass object FirTypeParametersInObjectChecker : FirRegularClassChecker() { @@ -19,11 +19,7 @@ object FirTypeParametersInObjectChecker : FirRegularClassChecker() { } if (declaration.typeParameters.isNotEmpty()) { - reporter.report(declaration.source) + reporter.reportOn(declaration.source, FirErrors.TYPE_PARAMETERS_IN_OBJECT, context) } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.TYPE_PARAMETERS_IN_OBJECT.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAbstractSuperCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAbstractSuperCallChecker.kt index 1b028fc90b7..c92c6c9ff00 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAbstractSuperCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAbstractSuperCallChecker.kt @@ -7,12 +7,12 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass import org.jetbrains.kotlin.fir.analysis.checkers.getDeclaration import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.modality @@ -42,14 +42,8 @@ object FirAbstractSuperCallChecker : FirQualifiedAccessChecker() { declaration.modality == Modality.ABSTRACT && item.modality == Modality.ABSTRACT ) { - reporter.report(expression.calleeReference.source) + reporter.reportOn(expression.calleeReference.source, FirErrors.ABSTRACT_SUPER_CALL, context) } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { - report(FirErrors.ABSTRACT_SUPER_CALL.on(it)) - } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAnonymousFunctionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAnonymousFunctionChecker.kt index 6b78f913121..e054e461d9e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAnonymousFunctionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAnonymousFunctionChecker.kt @@ -6,9 +6,9 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.extended.report import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.expressions.FirStatement @@ -20,10 +20,10 @@ object FirAnonymousFunctionChecker : FirExpressionChecker() { for (valueParameter in expression.valueParameters) { val source = valueParameter.source ?: continue if (valueParameter.defaultValue != null) { - reporter.report(source, FirErrors.ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE) + reporter.reportOn(source, FirErrors.ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE, context) } if (valueParameter.isVararg) { - reporter.report(source, FirErrors.USELESS_VARARG_ON_PARAMETER) + reporter.reportOn(source, FirErrors.USELESS_VARARG_ON_PARAMETER, context) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt index 5a58000782c..3a5bff25b17 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt @@ -28,7 +28,7 @@ object FirCatchParameterChecker : FirTryExpressionChecker() { val catchParameter = catchEntry.parameter if (catchParameter.defaultValue != null) - catchParameter.source?.let { reporter.report(FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE.on(it)) } + catchParameter.source?.let { reporter.report(FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE.on(it), context) } val typeRef = catchParameter.returnTypeRef if (typeRef !is FirResolvedTypeRef) return @@ -38,17 +38,17 @@ object FirCatchParameterChecker : FirTryExpressionChecker() { val isReified = coneType.lookupTag.typeParameterSymbol.fir.isReified if (isReified) { - catchParameter.source?.let { reporter.report(FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE.on(it)) } + catchParameter.source?.let { reporter.report(FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE.on(it), context) } } else { - catchParameter.source?.let { reporter.report(FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE.on(it)) } + catchParameter.source?.let { reporter.report(FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE.on(it), context) } } } if (!coneType.isThrowable(context.session)) - catchParameter.source?.let { reporter.report(FirErrors.TYPE_MISMATCH.on(it, throwable, coneType)) } + catchParameter.source?.let { reporter.report(FirErrors.TYPE_MISMATCH.on(it, throwable, coneType), context) } } } private fun ConeKotlinType.isThrowable(session: FirSession) = throwable.isSupertypeOf(session.typeCheckerContext, this.fullyExpandedType(session)) -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirNotASupertypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirNotASupertypeChecker.kt index 9a06d7e999a..32a239cbcd2 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirNotASupertypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirNotASupertypeChecker.kt @@ -5,12 +5,12 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass @@ -29,7 +29,7 @@ object FirNotASupertypeChecker : FirQualifiedAccessChecker() { val surrounding = context.findClosestClass(superReference.labelName) ?: return if (!targetClass.isSupertypeOf(surrounding)) { - reporter.report(expression.source) + reporter.reportOn(expression.source, FirErrors.NOT_A_SUPERTYPE, context) } } @@ -51,10 +51,4 @@ object FirNotASupertypeChecker : FirQualifiedAccessChecker() { return null } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { - report(FirErrors.NOT_A_SUPERTYPE.on(it)) - } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirProjectionsOnNonClassTypeArgumentChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirProjectionsOnNonClassTypeArgumentChecker.kt index 3c227fc60dd..4ece80f39e1 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirProjectionsOnNonClassTypeArgumentChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirProjectionsOnNonClassTypeArgumentChecker.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.types.FirStarProjection import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance @@ -18,19 +18,13 @@ object FirProjectionsOnNonClassTypeArgumentChecker : FirQualifiedAccessChecker() override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { for (it in expression.typeArguments) { when (it) { - is FirStarProjection -> reporter.report(it.source) + is FirStarProjection -> reporter.reportOn(it.source, FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, context) is FirTypeProjectionWithVariance -> { if (it.variance != Variance.INVARIANT) { - reporter.report(it.source) + reporter.reportOn(it.source, FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, context) } } } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { - report(FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(it)) - } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt index 13c2a5110ec..6dd050ad8d1 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt @@ -5,13 +5,13 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject import org.jetbrains.kotlin.fir.analysis.checkers.followAllAlias import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.references.FirSuperReference @@ -61,13 +61,12 @@ object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccess } if (count >= 2 && candidate != null) { - reporter.report(superReference.superTypeRef.source, candidate) - } - } - - private fun DiagnosticReporter.report(source: FirSourceElement?, candidate: FirClass<*>) { - source?.let { - report(FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE.on(it, candidate)) + reporter.reportOn( + superReference.superTypeRef.source, + FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE, + candidate, + context + ) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt index f05dcfc06b5..3eaf87d9cd9 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression @@ -33,11 +33,7 @@ object FirSealedClassConstructorCallChecker : FirQualifiedAccessChecker() { ?: return if (typeFir.status.modality == Modality.SEALED) { - reporter.report(expression.calleeReference.source) + reporter.reportOn(expression.calleeReference.source, FirErrors.SEALED_CLASS_CONSTRUCTOR_CALL, context) } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { report(FirErrors.SEALED_CLASS_CONSTRUCTOR_CALL.on(it)) } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperNotAvailableChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperNotAvailableChecker.kt index e73be836a31..f75b0b73426 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperNotAvailableChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperNotAvailableChecker.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.references.FirSuperReference @@ -23,13 +23,7 @@ object FirSuperNotAvailableChecker : FirQualifiedAccessChecker() { } if (!isInsideClass) { - reporter.report(expression.source) - } - } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { - report(FirErrors.SUPER_NOT_AVAILABLE.on(it)) + reporter.reportOn(expression.source, FirErrors.SUPER_NOT_AVAILABLE, context) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperclassNotAccessibleFromInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperclassNotAccessibleFromInterfaceChecker.kt index 5cbdc7c00a5..0bab6e13a60 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperclassNotAccessibleFromInterfaceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperclassNotAccessibleFromInterfaceChecker.kt @@ -6,11 +6,11 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression @@ -34,7 +34,7 @@ object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessChecke ?: return if (origin.source != null && origin.classKind == ClassKind.CLASS) { - reporter.report(expression.explicitReceiver?.source) + reporter.reportOn(expression.explicitReceiver?.source, FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE, context) } } } @@ -46,10 +46,4 @@ object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessChecke private fun getClassLikeDeclaration(functionCall: FirQualifiedAccessExpression, context: CheckerContext): FirClassLikeDeclaration<*>? { return functionCall.calleeReference.safeAs()?.resolvedSymbol?.fir?.getContainingClass(context) } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { - report(FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE.on(it)) - } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeArgumentsNotAllowedExpressionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeArgumentsNotAllowedExpressionChecker.kt index 2f8762e32d4..23a80d4f8f4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeArgumentsNotAllowedExpressionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeArgumentsNotAllowedExpressionChecker.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression -import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier @@ -20,15 +20,9 @@ object FirTypeArgumentsNotAllowedExpressionChecker : FirQualifiedAccessChecker() if (explicitReceiver is FirResolvedQualifier && explicitReceiver.symbol == null) { if (explicitReceiver.typeArguments.isNotEmpty()) { - reporter.report(explicitReceiver.source) + reporter.reportOn(explicitReceiver.source, FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED, context) return } } } - - private fun DiagnosticReporter.report(source: FirSourceElement?) { - source?.let { - report(FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.on(it)) - } - } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt index 341ef0dff58..1b326fa99da 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.originalForSubstitutionOverride @@ -74,7 +75,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { } if (!satisfiesBounds(proto, actual.type, substitutor, typeCheckerContext)) { - reporter.report(actual.source, proto, actual.type) + reporter.reportOn(actual.source, proto, actual.type, context) return } @@ -98,7 +99,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { // typealias A = B> // val a = A() when (calleeFir) { - is FirConstructor -> analyzeConstructorCall(expression, substitutor, typeCheckerContext, reporter) + is FirConstructor -> analyzeConstructorCall(expression, substitutor, typeCheckerContext, reporter, context) } } @@ -106,7 +107,8 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { functionCall: FirQualifiedAccessExpression, callSiteSubstitutor: ConeSubstitutor, typeCheckerContext: AbstractTypeCheckerContext, - reporter: DiagnosticReporter + reporter: DiagnosticReporter, + context: CheckerContext ) { // holds Collection bound. // note that if B used another type parameter here, @@ -168,7 +170,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { val satisfiesBounds = AbstractTypeChecker.isSubtypeOf(typeCheckerContext, target, intersection) if (!satisfiesBounds) { - reporter.report(functionCall.source, proto, actual) + reporter.reportOn(functionCall.source, proto, actual, context) return } } @@ -218,7 +220,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { parameterPairs.forEach { (proto, actual) -> if (!satisfiesBounds(proto, actual.type, substitutor, typeCheckerContext)) { // should report on the parameter instead! - reporter.report(reportTarget, proto, actual) + reporter.reportOn(reportTarget, proto, actual, context) return true } @@ -250,9 +252,12 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { return AbstractTypeChecker.isSubtypeOf(typeCheckerContext, target, intersection) } - private fun DiagnosticReporter.report(source: FirSourceElement?, proto: FirTypeParameterSymbol, actual: ConeKotlinType) { - source?.let { - report(FirErrors.UPPER_BOUND_VIOLATED.on(it, proto, actual)) - } + private fun DiagnosticReporter.reportOn( + source: FirSourceElement?, + proto: FirTypeParameterSymbol, + actual: ConeKotlinType, + context: CheckerContext + ) { + reportOn(source, FirErrors.UPPER_BOUND_VIOLATED, proto, actual, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/ArrayEqualityCanBeReplacedWithEquals.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/ArrayEqualityCanBeReplacedWithEquals.kt index b42e7616fc2..5e38795e233 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/ArrayEqualityCanBeReplacedWithEquals.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/ArrayEqualityCanBeReplacedWithEquals.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall import org.jetbrains.kotlin.fir.expressions.FirOperation import org.jetbrains.kotlin.fir.expressions.FirStatement @@ -27,6 +28,6 @@ object ArrayEqualityCanBeReplacedWithEquals : FirBasicExpressionChecker() { if (left.typeRef.coneType.classId != StandardClassIds.Array) return if (right.typeRef.coneType.classId != StandardClassIds.Array) return - reporter.report(expression.source, ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS) + reporter.reportOn(expression.source, ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeReplacedWithOperatorAssignmentChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeReplacedWithOperatorAssignmentChecker.kt index cdea09b2fe8..acc76ba1185 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeReplacedWithOperatorAssignmentChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeReplacedWithOperatorAssignmentChecker.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirVariableAssignme import org.jetbrains.kotlin.fir.analysis.checkers.getChildren import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol @@ -58,7 +59,7 @@ object CanBeReplacedWithOperatorAssignmentChecker : FirVariableAssignmentChecker } if (needToReport) { - reporter.report(expression.source, FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT) + reporter.reportOn(expression.source, FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeValChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeValChecker.kt index 389c6fd59d3..4edc9b8d3ec 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeValChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/CanBeValChecker.kt @@ -7,11 +7,17 @@ package org.jetbrains.kotlin.fir.analysis.checkers.extended import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange -import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.analysis.cfa.* +import org.jetbrains.kotlin.fir.FirFakeSourceElement +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker +import org.jetbrains.kotlin.fir.analysis.cfa.PathAwarePropertyInitializationInfo +import org.jetbrains.kotlin.fir.analysis.cfa.TraverseDirection +import org.jetbrains.kotlin.fir.analysis.cfa.traverse +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.getChildren import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.dfa.cfg.* import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol @@ -21,7 +27,8 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() { graph: ControlFlowGraph, reporter: DiagnosticReporter, data: Map, PathAwarePropertyInitializationInfo>, - properties: Set + properties: Set, + context: CheckerContext ) { val unprocessedProperties = mutableSetOf() val propertiesCharacteristics = mutableMapOf() @@ -51,14 +58,14 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() { if (lastDestructuringSource != null) { // if this is the last variable in destructuring declaration and destructuringCanBeVal == true and it can be val if (lastDestructuredVariables == 1 && destructuringCanBeVal && canBeVal(symbol, value)) { - reporter.report(lastDestructuringSource, FirErrors.CAN_BE_VAL) + reporter.reportOn(lastDestructuringSource, FirErrors.CAN_BE_VAL, context) lastDestructuringSource = null } else if (!canBeVal(symbol, value)) { destructuringCanBeVal = false } lastDestructuredVariables-- } else if (canBeVal(symbol, value) && symbol.fir.delegate == null) { - reporter.report(source, FirErrors.CAN_BE_VAL) + reporter.reportOn(source, FirErrors.CAN_BE_VAL, context) } } } @@ -110,4 +117,4 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() { EventOccurrencesRange.AT_MOST_ONCE, EventOccurrencesRange.ZERO ) -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/EmptyRangeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/EmptyRangeChecker.kt index 5b91cad921a..16b2894d716 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/EmptyRangeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/EmptyRangeChecker.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirStatement @@ -36,8 +37,7 @@ object EmptyRangeChecker : FirBasicExpressionChecker() { } if (needReport) { - reporter.report(expression.source, FirErrors.EMPTY_RANGE) - + reporter.reportOn(expression.source, FirErrors.EMPTY_RANGE, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantCallOfConversionMethod.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantCallOfConversionMethod.kt index e67cc357168..87555e52263 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantCallOfConversionMethod.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantCallOfConversionMethod.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessChecker import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirFunctionCall @@ -31,7 +32,7 @@ object RedundantCallOfConversionMethod : FirQualifiedAccessChecker() { val qualifiedType = targetClassMap[functionName] ?: return if (expression.explicitReceiver?.isRedundant(qualifiedType) == true) { - reporter.report(expression.source, FirErrors.REDUNDANT_CALL_OF_CONVERSION_METHOD) + reporter.reportOn(expression.source, FirErrors.REDUNDANT_CALL_OF_CONVERSION_METHOD, context) } } @@ -64,4 +65,4 @@ object RedundantCallOfConversionMethod : FirQualifiedAccessChecker() { "toUShort" to StandardClassIds.UShort, "toUByte" to StandardClassIds.UByte ) -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantExplicitTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantExplicitTypeChecker.kt index 924e5e7095c..fbae9f885a3 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantExplicitTypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantExplicitTypeChecker.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirMemberDeclarationChecker import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirTypeAlias @@ -84,7 +85,7 @@ object RedundantExplicitTypeChecker : FirMemberDeclarationChecker() { else -> return } - reporter.report(declaration.returnTypeRef.source, FirErrors.REDUNDANT_EXPLICIT_TYPE) + reporter.reportOn(declaration.returnTypeRef.source, FirErrors.REDUNDANT_EXPLICIT_TYPE, context) } private fun ConeKotlinType.isSame(other: ClassId?): Boolean { @@ -95,4 +96,4 @@ object RedundantExplicitTypeChecker : FirMemberDeclarationChecker() { private fun ConeKotlinType.hasSameNameWithoutModifiers(name: Name): Boolean = this is ConeClassLikeType && lookupTag.name == name && typeArguments.isEmpty() && !isMarkedNullable -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierChecker.kt index deaaf10ead8..57b8c51196b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantModalityModifierChecker.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.implicitModality import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.modalityModifier +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.modality @@ -33,6 +34,6 @@ object RedundantModalityModifierChecker : FirMemberDeclarationChecker() { val implicitModality = declaration.implicitModality(context) if (modality != implicitModality) return - reporter.report(source, REDUNDANT_MODALITY_MODIFIER) + reporter.reportOn(source, REDUNDANT_MODALITY_MODIFIER, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantReturnUnitTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantReturnUnitTypeChecker.kt index c1207f16dd4..3590da3ef4c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantReturnUnitTypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantReturnUnitTypeChecker.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock @@ -25,8 +26,8 @@ object RedundantReturnUnitType : FirBasicDeclarationChecker() { if (returnType.annotations.isNotEmpty()) return if (returnType.isUnit) { - reporter.report(declaration.returnTypeRef.source, FirErrors.REDUNDANT_RETURN_UNIT_TYPE) + reporter.reportOn(declaration.returnTypeRef.source, FirErrors.REDUNDANT_RETURN_UNIT_TYPE, context) } } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantSetterParameterTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantSetterParameterTypeChecker.kt index 90d49246675..deacaeaec26 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantSetterParameterTypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantSetterParameterTypeChecker.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirMemberDeclarationChecker import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SETTER_PARAMETER_TYPE +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor @@ -23,7 +24,7 @@ object RedundantSetterParameterTypeChecker : FirMemberDeclarationChecker() { val setterParameterTypeSource = valueParameter.returnTypeRef.source ?: return if (setterParameterTypeSource != propertyTypeSource) { - reporter.report(setterParameterTypeSource, REDUNDANT_SETTER_PARAMETER_TYPE) + reporter.reportOn(setterParameterTypeSource, REDUNDANT_SETTER_PARAMETER_TYPE, context) } } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantSingleExpressionStringTemplateChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantSingleExpressionStringTemplateChecker.kt index a2282d4b3e9..7ac980a7445 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantSingleExpressionStringTemplateChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantSingleExpressionStringTemplateChecker.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionC import org.jetbrains.kotlin.fir.analysis.checkers.getChildren import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.symbols.StandardClassIds @@ -32,7 +33,7 @@ object RedundantSingleExpressionStringTemplateChecker : FirBasicExpressionChecke expression.explicitReceiver?.typeRef?.coneType?.classId == StandardClassIds.String && expression.stringParentChildrenCount() == 1 // there is no more children in original string template ) { - reporter.report(expression.source, REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE) + reporter.reportOn(expression.source, REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantVisibilityModifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantVisibilityModifierChecker.kt index 94030703087..8318c2101d6 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantVisibilityModifierChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantVisibilityModifierChecker.kt @@ -7,17 +7,14 @@ package org.jetbrains.kotlin.fir.analysis.checkers.extended import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.fir.FirFakeSourceElement -import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirFakeSourceElement +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker -import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.fir.analysis.diagnostics.overrideModifier -import org.jetbrains.kotlin.fir.analysis.diagnostics.visibilityModifier +import org.jetbrains.kotlin.fir.analysis.diagnostics.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.lexer.KtModifierKeywordToken @@ -53,7 +50,7 @@ object RedundantVisibilityModifierChecker : FirBasicDeclarationChecker() { && declaration.setter?.visibility == Visibilities.Public ) return - reporter.report(source, FirErrors.REDUNDANT_VISIBILITY_MODIFIER) + reporter.reportOn(source, FirErrors.REDUNDANT_VISIBILITY_MODIFIER, context) } private fun FirDeclaration.implicitVisibility(context: CheckerContext): Visibility { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/ReportHelper.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/ReportHelper.kt deleted file mode 100644 index c5d248cd440..00000000000 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/ReportHelper.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.fir.analysis.checkers.extended - -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0 - -inline fun DiagnosticReporter.report( - source: T?, - factory: FirDiagnosticFactory0 -) { - source?.let { report(factory.on(it)) } -} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UnusedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UnusedChecker.kt index 75c004f1f87..03b5fb9b7ca 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UnusedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UnusedChecker.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass import org.jetbrains.kotlin.fir.analysis.checkers.isIterator import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess @@ -30,21 +31,22 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.types.coneType object UnusedChecker : FirControlFlowChecker() { - override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, checkerContext: CheckerContext) { - if ((graph.declaration as? FirSymbolOwner<*>)?.getContainingClass(checkerContext)?.takeIf { + override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) { + if ((graph.declaration as? FirSymbolOwner<*>)?.getContainingClass(context)?.takeIf { !it.symbol.classId.isLocal } != null ) return val properties = LocalPropertyCollector.collect(graph) if (properties.isEmpty()) return - val data = ValueWritesWithoutReading(checkerContext.session, properties).getData(graph) - graph.traverse(TraverseDirection.Backward, CfaVisitor(data, reporter)) + val data = ValueWritesWithoutReading(context.session, properties).getData(graph) + graph.traverse(TraverseDirection.Backward, CfaVisitor(data, reporter, context)) } class CfaVisitor( val data: Map, PathAwareVariableStatusInfo>, - val reporter: DiagnosticReporter + val reporter: DiagnosticReporter, + val context: CheckerContext ) : ControlFlowGraphVisitorVoid() { override fun visitNode(node: CFGNode<*>) {} @@ -56,7 +58,7 @@ object UnusedChecker : FirControlFlowChecker() { if (data == VariableStatus.ONLY_WRITTEN_NEVER_READ) { // todo: report case like "a += 1" where `a` `doesn't writes` different way (special for Idea) val source = node.fir.lValue.source - reporter.report(source, FirErrors.ASSIGNED_VALUE_IS_NEVER_READ) + reporter.reportOn(source, FirErrors.ASSIGNED_VALUE_IS_NEVER_READ, context) // To avoid duplicate reports, stop investigating remaining paths once reported. break } @@ -74,17 +76,17 @@ object UnusedChecker : FirControlFlowChecker() { when { data == VariableStatus.UNUSED -> { if ((node.fir.initializer as? FirFunctionCall)?.isIterator != true) { - reporter.report(variableSource, FirErrors.UNUSED_VARIABLE) + reporter.reportOn(variableSource, FirErrors.UNUSED_VARIABLE, context) break } } data.isRedundantInit -> { val source = variableSymbol.fir.initializer?.source - reporter.report(source, FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT) + reporter.reportOn(source, FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT, context) break } data == VariableStatus.ONLY_WRITTEN_NEVER_READ -> { - reporter.report(variableSource, FirErrors.VARIABLE_NEVER_READ) + reporter.reportOn(variableSource, FirErrors.VARIABLE_NEVER_READ, context) break } else -> { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt index 826de86a6ba..8faa654deff 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessChecker import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference @@ -28,7 +29,7 @@ object UselessCallOnNotNullChecker : FirQualifiedAccessChecker() { if ("$calleePackageName.$calleeName" !in triggerOn) return if (calleeOn.getNullability() == ConeNullability.NOT_NULL) { - reporter.report(expression.source, FirErrors.USELESS_CALL_ON_NOT_NULL) + reporter.reportOn(expression.source, FirErrors.USELESS_CALL_ON_NOT_NULL, context) } } @@ -53,4 +54,4 @@ object UselessCallOnNotNullChecker : FirQualifiedAccessChecker() { "kotlin.orEmpty" ) -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt index 6a2e10ea473..67af299d2ff 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt @@ -10,7 +10,10 @@ import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector -import org.jetbrains.kotlin.fir.analysis.diagnostics.* +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0 +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind.* @@ -27,37 +30,42 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) { override fun visitErrorLoop(errorLoop: FirErrorLoop, data: CheckerContext) { val source = errorLoop.source ?: return - reportFirDiagnostic(errorLoop.diagnostic, source, reporter) + reportFirDiagnostic(errorLoop.diagnostic, source, reporter, data) } override fun visitErrorTypeRef(errorTypeRef: FirErrorTypeRef, data: CheckerContext) { val source = errorTypeRef.source ?: return - reportFirDiagnostic(errorTypeRef.diagnostic, source, reporter) + reportFirDiagnostic(errorTypeRef.diagnostic, source, reporter, data) } override fun visitErrorNamedReference(errorNamedReference: FirErrorNamedReference, data: CheckerContext) { val source = errorNamedReference.source ?: return // Don't report duplicated unresolved reference on annotation entry (already reported on its type) if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && errorNamedReference.diagnostic is ConeUnresolvedNameError) return - reportFirDiagnostic(errorNamedReference.diagnostic, source, reporter) + reportFirDiagnostic(errorNamedReference.diagnostic, source, reporter, data) } override fun visitErrorExpression(errorExpression: FirErrorExpression, data: CheckerContext) { val source = errorExpression.source ?: return - reportFirDiagnostic(errorExpression.diagnostic, source, reporter) + reportFirDiagnostic(errorExpression.diagnostic, source, reporter, data) } override fun visitErrorFunction(errorFunction: FirErrorFunction, data: CheckerContext) { val source = errorFunction.source ?: return - reportFirDiagnostic(errorFunction.diagnostic, source, reporter) + reportFirDiagnostic(errorFunction.diagnostic, source, reporter, data) } override fun visitErrorResolvedQualifier(errorResolvedQualifier: FirErrorResolvedQualifier, data: CheckerContext) { val source = errorResolvedQualifier.source ?: return - reportFirDiagnostic(errorResolvedQualifier.diagnostic, source, reporter) + reportFirDiagnostic(errorResolvedQualifier.diagnostic, source, reporter, data) } - private fun reportFirDiagnostic(diagnostic: ConeDiagnostic, source: FirSourceElement, reporter: DiagnosticReporter) { + private fun reportFirDiagnostic( + diagnostic: ConeDiagnostic, + source: FirSourceElement, + reporter: DiagnosticReporter, + context: CheckerContext + ) { // Will be handled by [FirDestructuringDeclarationChecker] if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY) { // TODO: if all diagnostics are supported, we don't need the following check, and will bail out based on element type. @@ -97,7 +105,7 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect is ConeIntermediateDiagnostic -> null else -> throw IllegalArgumentException("Unsupported diagnostic type: ${diagnostic.javaClass}") } - reporter.report(coneDiagnostic) + reporter.report(coneDiagnostic, context) } private fun ConeKotlinType.isEffectivelyNotNull(): Boolean { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/DiagnosticReporter.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/DiagnosticReporter.kt index 1fd260cf5f0..de84018cfd2 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/DiagnosticReporter.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/DiagnosticReporter.kt @@ -5,15 +5,57 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext + abstract class DiagnosticReporter { - abstract fun report(diagnostic: FirDiagnostic<*>?) + abstract fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) +} + +inline fun DiagnosticReporter.reportOn( + source: T?, + factory: FirDiagnosticFactory0, + context: CheckerContext +) { + source?.let { report(factory.on(it), context) } +} + +inline fun DiagnosticReporter.reportOn( + source: T?, + factory: FirDiagnosticFactory1, + a: A, + context: CheckerContext +) { + source?.let { report(factory.on(it, a), context) } +} + +inline fun DiagnosticReporter.reportOn( + source: T?, + factory: FirDiagnosticFactory2, + a: A, + b: B, + context: CheckerContext +) { + source?.let { report(factory.on(it, a, b), context) } +} + +inline fun DiagnosticReporter.reportOn( + source: T?, + factory: FirDiagnosticFactory3, + a: A, + b: B, + c: C, + context: CheckerContext +) { + source?.let { report(factory.on(it, a, b, c), context) } } class SimpleDiagnosticReporter : DiagnosticReporter() { val diagnostics: MutableList> = mutableListOf() - override fun report(diagnostic: FirDiagnostic<*>?) { + override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) { if (diagnostic == null) return diagnostics += diagnostic } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index f17fdc08ea8..961d15010b7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -288,7 +288,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { ) // Modifiers - map.put(INAPPLICABLE_INFIX_MODIFIER, "''infix'' modifier is inapplicable on this function: {0}", TO_STRING) + map.put(INAPPLICABLE_INFIX_MODIFIER, "''infix'' modifier is inapplicable on this function") map.put(REPEATED_MODIFIER, "Repeated ''{0}''", TO_STRING) map.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING) map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", TO_STRING, TO_STRING) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 6b848a85fbb..b6cc52927cd 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -15,7 +15,9 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.name.Name @@ -104,7 +106,7 @@ object FirErrors { val EXPOSED_TYPE_PARAMETER_BOUND by error3() // Modifiers - val INAPPLICABLE_INFIX_MODIFIER by existing1() + val INAPPLICABLE_INFIX_MODIFIER by error0() val REPEATED_MODIFIER by error1() val REDUNDANT_MODIFIER by error2() val DEPRECATED_MODIFIER_PAIR by error2() diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostics/AbstractFirIdeDiagnosticsCollector.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostics/AbstractFirIdeDiagnosticsCollector.kt index f05922086ee..4a4f927c2aa 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostics/AbstractFirIdeDiagnosticsCollector.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostics/AbstractFirIdeDiagnosticsCollector.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics import com.intellij.openapi.diagnostic.Logger import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector import org.jetbrains.kotlin.fir.analysis.collectors.registerAllComponents import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter @@ -39,7 +40,7 @@ internal abstract class AbstractFirIdeDiagnosticsCollector( private inner class Reporter : DiagnosticReporter() { - override fun report(diagnostic: FirDiagnostic<*>?) { + override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) { if (diagnostic !is FirPsiDiagnostic<*>) return if (diagnostic.element.psi !is KtElement) return onDiagnostic(diagnostic) diff --git a/plugins/fir/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/checkers/DummyNameChecker.kt b/plugins/fir/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/checkers/DummyNameChecker.kt index 652871e080d..0c207ed8a4e 100644 --- a/plugins/fir/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/checkers/DummyNameChecker.kt +++ b/plugins/fir/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/checkers/DummyNameChecker.kt @@ -7,8 +7,7 @@ package org.jetbrains.kotlin.fir.plugin.checkers import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirMemberDeclarationChecker -import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.* import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction @@ -16,7 +15,7 @@ object DummyNameChecker : FirMemberDeclarationChecker() { override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { if (declaration !is FirSimpleFunction) return if (declaration.name.asString() == "dummy") { - declaration.source?.let { reporter.report(FirErrors.SYNTAX.on(it)) } + reporter.reportOn(declaration.source, FirErrors.SYNTAX, context) } } }