[FIR] Part 1. Group checkers by the MPP kind

This commit introduces MppChecker kind, which represents the new property
  of checkers
- `MppCheckerKind.Common` means that this checker should run from the same
  session to which corresponding declaration belongs
- `MppCheckerKind.Platform` means that in case of MPP compilation this
  checker should run with session of leaf platform module for sources
  of all modules

An example of a platform checker is a checker that checks class scopes
  and reports ABSTRACT_NOT_IMPLEMENTED and similar diagnostics. If some
  regular class in the common module contains expect supertypes, the
  checker should consider the actualization of those supertypes to get
  a complete type scope

^KT-58881
This commit is contained in:
Dmitriy Novozhilov
2024-01-08 14:37:30 +02:00
committed by Nikolay Lunyak
parent ff063f553e
commit 727d2f46f8
338 changed files with 1216 additions and 728 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.parcelize.fir.diagnostics
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirAnnotationCallChecker
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
@@ -27,7 +28,8 @@ import org.jetbrains.kotlin.parcelize.ParcelizeNames.RAW_VALUE_ANNOTATION_CLASS_
import org.jetbrains.kotlin.parcelize.ParcelizeNames.TYPE_PARCELER_CLASS_IDS
import org.jetbrains.kotlin.parcelize.ParcelizeNames.WRITE_WITH_CLASS_IDS
object FirParcelizeAnnotationChecker : FirAnnotationCallChecker() {
// TODO: extract common checker for expect interfaces
object FirParcelizeAnnotationChecker : FirAnnotationCallChecker(MppCheckerKind.Platform) {
override fun check(expression: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
val annotationType = expression.annotationTypeRef.coneType.fullyExpandedType(context.session) as? ConeClassLikeType ?: return
val resolvedAnnotationSymbol = annotationType.lookupTag.toFirRegularClassSymbol(context.session) ?: return
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirClassChecker
import org.jetbrains.kotlin.fir.declarations.*
@@ -29,7 +30,7 @@ import org.jetbrains.kotlin.parcelize.ParcelizeNames.PARCELIZE_CLASS_CLASS_IDS
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
object FirParcelizeClassChecker : FirClassChecker() {
object FirParcelizeClassChecker : FirClassChecker(MppCheckerKind.Common) {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
checkParcelableClass(declaration, context, reporter)
checkParcelerClass(declaration, context, reporter)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.hasValOrVar
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirConstructorChecker
import org.jetbrains.kotlin.fir.correspondingProperty
@@ -17,7 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
import org.jetbrains.kotlin.parcelize.ParcelizeNames
object FirParcelizeConstructorChecker : FirConstructorChecker() {
object FirParcelizeConstructorChecker : FirConstructorChecker(MppCheckerKind.Common) {
override fun check(declaration: FirConstructor, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.isPrimary) return
val source = declaration.source ?: return
@@ -7,17 +7,18 @@ package org.jetbrains.kotlin.parcelize.fir.diagnostics
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirSimpleFunctionChecker
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isInt
import org.jetbrains.kotlin.fir.types.isUnit
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
object FirParcelizeFunctionChecker : FirSimpleFunctionChecker() {
object FirParcelizeFunctionChecker : FirSimpleFunctionChecker(MppCheckerKind.Common) {
override fun check(declaration: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) {
val containingClassSymbol = declaration.dispatchReceiverType?.toRegularClassSymbol(context.session)
if (!containingClassSymbol.isParcelize(context.session)) return
@@ -11,15 +11,16 @@ import org.jetbrains.kotlin.descriptors.isEnumClass
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirPropertyChecker
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation
import org.jetbrains.kotlin.fir.declarations.utils.fromPrimaryConstructor
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation
import org.jetbrains.kotlin.fir.resolve.fqName
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
@@ -31,7 +32,7 @@ import org.jetbrains.kotlin.parcelize.ParcelizeNames.CREATOR_NAME
import org.jetbrains.kotlin.parcelize.ParcelizeNames.IGNORED_ON_PARCEL_CLASS_IDS
import org.jetbrains.kotlin.parcelize.ParcelizeNames.PARCELER_ID
object FirParcelizePropertyChecker : FirPropertyChecker() {
object FirParcelizePropertyChecker : FirPropertyChecker(MppCheckerKind.Common) {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
val session = context.session
val containingClassSymbol = declaration.dispatchReceiverType?.toRegularClassSymbol(session) ?: return