[FIR][checkers][JS] Move reporting of FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE to FirJsInheritanceClassChecker

#KT-66474 Fixed
This commit is contained in:
Stanislav Ruban
2024-03-11 04:04:58 +02:00
committed by Space Team
parent 0549c6c75b
commit 478c1a6d50
4 changed files with 32 additions and 27 deletions
@@ -41,20 +41,6 @@ object FirJsExternalChecker : FirWebCommonExternalChecker(allowCompanionInInterf
}
override fun additionalCheck(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration is FirClass && declaration.classKind != ClassKind.ANNOTATION_CLASS) {
val superClasses = declaration.superInterfaces(context.session).toMutableList()
declaration.superClassNotAny(context.session)?.let {
superClasses.add(it)
}
if (declaration.classKind == ClassKind.ENUM_CLASS || declaration.classKind == ClassKind.ENUM_ENTRY) {
superClasses.removeAll { it.classId?.asSingleFqName()?.toUnsafe() == StandardNames.FqNames._enum }
}
val superDeclarations = superClasses.mapNotNull { it.toSymbol(context.session) }
if (superDeclarations.any { !it.isNativeObject(context) && it.classId.asSingleFqName() != StandardNames.FqNames.throwable }) {
reporter.reportOn(declaration.source, FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE, context)
}
}
if (declaration is FirFunction && declaration.isInline) {
reporter.reportOn(declaration.source, FirWebCommonErrors.INLINE_EXTERNAL_DECLARATION, context)
}
@@ -136,10 +122,6 @@ object FirJsExternalChecker : FirWebCommonExternalChecker(allowCompanionInInterf
else -> returnTypeRef.coneType.typeArguments.firstOrNull()?.type
}
private fun FirClass.superInterfaces(session: FirSession) = superConeTypes
.filterNot { it.isAny || it.isNullableAny }
.filter { it.toSymbol(session)?.classKind == ClassKind.INTERFACE }
private fun FirDeclaration.checkEnumEntry(context: CheckerContext, reporter: DiagnosticReporter) {
if (this !is FirEnumEntry) return
initializer?.let {
@@ -147,5 +129,3 @@ object FirJsExternalChecker : FirWebCommonExternalChecker(allowCompanionInInterf
}
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.js.checkers.declaration
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirSession
@@ -15,17 +16,15 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirClassChecker
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.analysis.js.checkers.isEffectivelyExternal
import org.jetbrains.kotlin.fir.analysis.js.checkers.isOverridingExternalWithOptionalParams
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.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.scopes.collectAllFunctions
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverrideFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.isSuspendOrKSuspendFunctionType
import org.jetbrains.kotlin.fir.types.typeContext
import org.jetbrains.kotlin.fir.types.*
sealed class FirJsInheritanceClassChecker(mppKind: MppCheckerKind) : FirClassChecker(mppKind) {
object Regular : FirJsInheritanceClassChecker(MppCheckerKind.Platform) {
@@ -43,7 +42,20 @@ sealed class FirJsInheritanceClassChecker(mppKind: MppCheckerKind) : FirClassChe
}
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.symbol.isEffectivelyExternal(context)) {
val session = context.session
val isEffectivelyExternal = declaration.symbol.isEffectivelyExternal(session)
if (isEffectivelyExternal && declaration.classKind != ClassKind.ANNOTATION_CLASS) {
val superTypes = declaration.superConeTypes
.filterNot { it.isAnyOrNullableAny || it.isThrowableOrNullableThrowable || it.isEnum }
.mapNotNull { it.toSymbol(session) }
if (superTypes.any { !it.isEffectivelyExternal(session) }) {
reporter.reportOn(declaration.source, FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE, context)
}
}
if (!isEffectivelyExternal) {
val fakeOverriddenMethod = declaration.findFakeMethodOverridingExternalWithOptionalParams(context)
if (fakeOverriddenMethod != null) {
@@ -57,7 +69,7 @@ sealed class FirJsInheritanceClassChecker(mppKind: MppCheckerKind) : FirClassChe
if (
!context.languageVersionSettings.supportsFeature(LanguageFeature.JsAllowImplementingFunctionInterface) &&
declaration.superConeTypes.any {
it.isBuiltinFunctionalTypeOrSubtype(context.session) && !it.isSuspendFunctionTypeOrSubtype(context.session)
it.isBuiltinFunctionalTypeOrSubtype(session) && !it.isSuspendFunctionTypeOrSubtype(session)
}
) {
reporter.reportOn(declaration.source, FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE, context)
@@ -4,7 +4,7 @@
expect interface ExternalInterface
external class <!EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE!>ExternalClass<!>: ExternalInterface
external class ExternalClass: ExternalInterface
// MODULE: js()()(commonjs)
// TARGET_PLATFORM: JS
@@ -0,0 +1,13 @@
// MODULE: commonjs
// TARGET_PLATFORM: JS
// FILE: commonjs.kt
expect interface ExternalInterface
external class <!EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE!>ExternalClass<!>: ExternalInterface
// MODULE: js()()(commonjs)
// TARGET_PLATFORM: JS
// FILE: js.kt
actual external interface ExternalInterface