diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsExternalChecker.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsExternalChecker.kt index 4c69947c37c..9bab5fc85a6 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsExternalChecker.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsExternalChecker.kt @@ -72,7 +72,11 @@ object FirJsExternalChecker : FirBasicDeclarationChecker() { if (declaration is FirPropertyAccessor && declaration.isDirectlyExternal(context.session)) { reporter.reportOn(declaration.source, FirJsErrors.WRONG_EXTERNAL_DECLARATION, "property accessor", context) - } else if (declaration !is FirPrimaryConstructor && declaration.isPrivateMemberOfExternalClass(context.session)) { + } else if ( + declaration !is FirPrimaryConstructor && + declaration !is FirField && + declaration.isPrivateMemberOfExternalClass(context.session) + ) { reporter.reportOn(declaration.source, FirJsErrors.WRONG_EXTERNAL_DECLARATION, "private member of class", context) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt index bc43712b2e7..b3cdb294732 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt @@ -42,6 +42,10 @@ object FirAnnotationChecker : FirBasicDeclarationChecker() { context: CheckerContext, reporter: DiagnosticReporter ) { + if (declaration is FirDanglingModifierList) { + return + } + checkAnnotationContainer(declaration, context, reporter) if (declaration is FirCallableDeclaration) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionAnnotationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionAnnotationChecker.kt index 6fb09be1d87..3cd8bef6deb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionAnnotationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionAnnotationChecker.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.expressions.FirBlock +import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.types.ConeKotlinType @@ -29,6 +30,7 @@ object FirExpressionAnnotationChecker : FirBasicExpressionChecker() { // See KT-33658 about annotations on non-expression statements if (expression is FirDeclaration || expression !is FirExpression || + expression is FirErrorExpression || expression is FirBlock && (expression.source?.kind == KtRealSourceElementKind || expression.source?.kind == KtFakeSourceElementKind.DesugaredForLoop) ) return diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirRecursiveProblemChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirRecursiveProblemChecker.kt index 914b09fd7a4..fef9aab0a2e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirRecursiveProblemChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirRecursiveProblemChecker.kt @@ -14,11 +14,18 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.types.* object FirRecursiveProblemChecker : FirBasicExpressionChecker() { override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) { - if (expression !is FirExpression || expression.source?.kind is KtFakeSourceElementKind) return + if ( + expression !is FirExpression || + expression.source?.kind is KtFakeSourceElementKind || + expression.isExpressionWithAlwaysImplicitTypeRef + ) { + return + } fun checkConeType(coneType: ConeKotlinType?) { if (coneType is ConeErrorType && (coneType.diagnostic as? ConeSimpleDiagnostic)?.kind == DiagnosticKind.RecursionInImplicitTypes) { @@ -32,4 +39,6 @@ object FirRecursiveProblemChecker : FirBasicExpressionChecker() { checkConeType(expression.typeRef.coneType) } + + private val FirStatement.isExpressionWithAlwaysImplicitTypeRef get() = this is FirNoReceiverExpression } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/DeclarationCheckersDiagnosticComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/DeclarationCheckersDiagnosticComponent.kt index 514b8d50f0c..dc802e09cc7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/DeclarationCheckersDiagnosticComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/DeclarationCheckersDiagnosticComponent.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationChecker import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirDeclarationChecker import org.jetbrains.kotlin.fir.analysis.checkersComponent import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.* @OptIn(CheckersComponentInternal::class) @@ -20,6 +21,15 @@ class DeclarationCheckersDiagnosticComponent( reporter: DiagnosticReporter, private val checkers: DeclarationCheckers = session.checkersComponent.declarationCheckers, ) : AbstractDiagnosticCollectorComponent(session, reporter) { + override fun visitElement(element: FirElement, data: CheckerContext) { + if (element is FirDeclaration) { + error("${element::class.simpleName} should call parent checkers inside ${this::class.simpleName}") + } + } + + override fun visitDeclaration(declaration: FirDeclaration, data: CheckerContext) { + checkers.allBasicDeclarationCheckers.check(declaration, data) + } override fun visitFile(file: FirFile, data: CheckerContext) { checkers.allFileCheckers.check(file, data) @@ -81,6 +91,22 @@ class DeclarationCheckersDiagnosticComponent( checkers.allAnonymousInitializerCheckers.check(anonymousInitializer, data) } + override fun visitField(field: FirField, data: CheckerContext) { + checkers.allCallableDeclarationCheckers.check(field, data) + } + + override fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: CheckerContext) { + checkers.allBasicDeclarationCheckers.check(danglingModifierList, data) + } + + override fun visitErrorProperty(errorProperty: FirErrorProperty, data: CheckerContext) { + checkers.allCallableDeclarationCheckers.check(errorProperty, data) + } + + override fun visitScript(script: FirScript, data: CheckerContext) { + checkers.allBasicDeclarationCheckers.check(script, data) + } + private fun Collection>.check( declaration: D, context: CheckerContext diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt index 610bd7f8704..456e5facae1 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirExpressionChecker import org.jetbrains.kotlin.fir.analysis.checkersComponent import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.expressions.* @OptIn(CheckersComponentInternal::class) @@ -20,6 +21,16 @@ class ExpressionCheckersDiagnosticComponent( reporter: DiagnosticReporter, private val checkers: ExpressionCheckers = session.checkersComponent.expressionCheckers, ) : AbstractDiagnosticCollectorComponent(session, reporter) { + override fun visitElement(element: FirElement, data: CheckerContext) { + if (element is FirExpression) { + error("${element::class.simpleName} should call parent checkers inside ${this::class.simpleName}") + } + } + + override fun visitExpression(expression: FirExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(expression, data) + } + override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: CheckerContext) { checkers.allTypeOperatorCallCheckers.check(typeOperatorCall, data) } @@ -36,6 +47,10 @@ class ExpressionCheckersDiagnosticComponent( checkers.allAnnotationCallCheckers.check(annotationCall, data) } + override fun visitErrorAnnotationCall(errorAnnotationCall: FirErrorAnnotationCall, data: CheckerContext) { + checkers.allAnnotationCallCheckers.check(errorAnnotationCall, data) + } + override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: CheckerContext) { checkers.allQualifiedAccessExpressionCheckers.check(qualifiedAccessExpression, data) } @@ -48,6 +63,10 @@ class ExpressionCheckersDiagnosticComponent( checkers.allFunctionCallCheckers.check(functionCall, data) } + override fun visitComponentCall(componentCall: FirComponentCall, data: CheckerContext) { + checkers.allFunctionCallCheckers.check(componentCall, data) + } + override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: CheckerContext) { checkers.allIntegerLiteralOperatorCallCheckers.check(integerLiteralOperatorCall, data) } @@ -156,6 +175,71 @@ class ExpressionCheckersDiagnosticComponent( checkers.allThrowExpressionCheckers.check(throwExpression, data) } + override fun visitVarargArgumentsExpression(varargArgumentsExpression: FirVarargArgumentsExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(varargArgumentsExpression, data) + } + + override fun visitWrappedExpression(wrappedExpression: FirWrappedExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(wrappedExpression, data) + } + + override fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(wrappedArgumentExpression, data) + } + + override fun visitSpreadArgumentExpression(spreadArgumentExpression: FirSpreadArgumentExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(spreadArgumentExpression, data) + } + + override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(namedArgumentExpression, data) + } + + override fun visitLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(lambdaArgumentExpression, data) + } + + override fun visitSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(smartCastExpression, data) + } + + override fun visitWhenSubjectExpression(whenSubjectExpression: FirWhenSubjectExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(whenSubjectExpression, data) + } + + override fun visitResolvedReifiedParameterReference( + resolvedReifiedParameterReference: FirResolvedReifiedParameterReference, + data: CheckerContext + ) { + checkers.allBasicExpressionCheckers.check(resolvedReifiedParameterReference, data) + } + + override fun visitComparisonExpression(comparisonExpression: FirComparisonExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(comparisonExpression, data) + } + + override fun visitDesugaredAssignmentValueReferenceExpression( + desugaredAssignmentValueReferenceExpression: FirDesugaredAssignmentValueReferenceExpression, + data: CheckerContext + ) { + checkers.allBasicExpressionCheckers.check(desugaredAssignmentValueReferenceExpression, data) + } + + override fun visitCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(checkedSafeCallSubject, data) + } + + override fun visitErrorExpression(errorExpression: FirErrorExpression, data: CheckerContext) { + checkers.allBasicExpressionCheckers.check(errorExpression, data) + } + + override fun visitQualifiedErrorAccessExpression( + qualifiedErrorAccessExpression: FirQualifiedErrorAccessExpression, + data: CheckerContext + ) { + checkers.allBasicExpressionCheckers.check(qualifiedErrorAccessExpression, data) + } + private fun Collection>.check( expression: E, context: CheckerContext diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/TypeCheckersDiagnosticComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/TypeCheckersDiagnosticComponent.kt index d11952c1ff1..c01c44f0d62 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/TypeCheckersDiagnosticComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/TypeCheckersDiagnosticComponent.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.type.FirTypeChecker import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers import org.jetbrains.kotlin.fir.analysis.checkersComponent import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.types.* @OptIn(CheckersComponentInternal::class) @@ -20,6 +21,11 @@ class TypeCheckersDiagnosticComponent( reporter: DiagnosticReporter, private val checkers: TypeCheckers = session.checkersComponent.typeCheckers, ) : AbstractDiagnosticCollectorComponent(session, reporter) { + override fun visitElement(element: FirElement, data: CheckerContext) { + if (element is FirTypeRef) { + error("${element::class.simpleName} should call parent checkers inside ${this::class.simpleName}") + } + } override fun visitDynamicTypeRef(dynamicTypeRef: FirDynamicTypeRef, data: CheckerContext) { checkers.allTypeRefCheckers.check(dynamicTypeRef, data) @@ -45,6 +51,10 @@ class TypeCheckersDiagnosticComponent( checkers.allTypeRefCheckers.check(typeRefWithNullability, data) } + override fun visitIntersectionTypeRef(intersectionTypeRef: FirIntersectionTypeRef, data: CheckerContext) { + checkers.allTypeRefCheckers.check(intersectionTypeRef, data) + } + override fun visitImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: CheckerContext) { checkers.allTypeRefCheckers.check(implicitTypeRef, data) }