[FIR] Part 5. Introduce paired common checkers for expect classes

There are some cases when we want to run some platform checker not from
  platform session but from common session. All such cases appear when
  we check some `expect` class

```kotlin
// MODULE: common
expect interface A
expect class B : A

class C : A

// MODULE: platform()()(common)
actual interface A {
    fun foo()
}

actual class B : A {
    override fun foo() {}
}
```

In this example we want to report "abstract foo not implemented" on
  class `C`, but we don't want to report it on `expect class B` (as
  its supertype is always `expect A`, never `actual A`)

So to cover such cases some platform checkers were split into two parts:
- `Regular`, which is platform checkers and runs for everything except
  expect declaration
- `ForExpectClass`, which is common checkers and runs only for expect
  declarations

^KT-58881 Fixed
^KT-58881 Fixed
^KT-64187 Fixed
This commit is contained in:
Dmitriy Novozhilov
2024-01-09 15:12:05 +02:00
committed by Nikolay Lunyak
parent f5d8113de3
commit 990da9fa1a
27 changed files with 495 additions and 156 deletions
@@ -5,14 +5,17 @@
package org.jetbrains.kotlin.fir.analysis.wasm.checkers
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.*
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirClassChecker
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.declaration.*
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.declaration.FirJsExportAnnotationChecker
object WasmBaseDeclarationCheckers : DeclarationCheckers() {
override val classCheckers: Set<FirClassChecker>
get() = setOf(
FirWasmExternalInheritanceChecker,
FirWasmExternalInheritanceChecker.Regular,
FirWasmExternalInheritanceChecker.ForExpectClass,
)
override val basicDeclarationCheckers: Set<FirBasicDeclarationChecker>
@@ -39,4 +42,4 @@ object WasmWasiDeclarationCheckers : DeclarationCheckers() {
get() = setOf(
FirWasmWasiExternalDeclarationChecker,
)
}
}
@@ -15,11 +15,25 @@ import org.jetbrains.kotlin.fir.analysis.checkers.toClassLikeSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.utils.isEffectivelyExternal
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.StandardClassIds
// TODO: extract common checker for expect interfaces
object FirWasmExternalInheritanceChecker : FirClassChecker(MppCheckerKind.Platform) {
sealed class FirWasmExternalInheritanceChecker(mppKind: MppCheckerKind) : FirClassChecker(mppKind) {
object Regular : FirWasmExternalInheritanceChecker(MppCheckerKind.Platform) {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration.isExpect) return
super.check(declaration, context, reporter)
}
}
object ForExpectClass : FirWasmExternalInheritanceChecker(MppCheckerKind.Common) {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.isExpect) return
super.check(declaration, context, reporter)
}
}
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
val session = context.session
val isCurrentClassExternal = declaration.symbol.isEffectivelyExternal(session)