[FIR JS] Implement FirJsInheritanceChecker
This commit is contained in:
committed by
Space Team
parent
9e1c6f2f61
commit
4cf8d9ffb9
+19
@@ -4648,6 +4648,25 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE) { firDiagnostic ->
|
||||||
|
ImplementingFunctionInterfaceImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS) { firDiagnostic ->
|
||||||
|
OverridingExternalFunWithOptionalParamsImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE) { firDiagnostic ->
|
||||||
|
OverridingExternalFunWithOptionalParamsWithFakeImpl(
|
||||||
|
firSymbolBuilder.functionLikeBuilder.buildFunctionSymbol(firDiagnostic.a),
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirJsErrors.DELEGATION_BY_DYNAMIC) { firDiagnostic ->
|
add(FirJsErrors.DELEGATION_BY_DYNAMIC) { firDiagnostic ->
|
||||||
DelegationByDynamicImpl(
|
DelegationByDynamicImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+13
@@ -3233,6 +3233,19 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = JavaSamInterfaceConstructorReference::class
|
override val diagnosticClass get() = JavaSamInterfaceConstructorReference::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ImplementingFunctionInterface : KtFirDiagnostic<KtClassOrObject>() {
|
||||||
|
override val diagnosticClass get() = ImplementingFunctionInterface::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class OverridingExternalFunWithOptionalParams : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = OverridingExternalFunWithOptionalParams::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class OverridingExternalFunWithOptionalParamsWithFake : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = OverridingExternalFunWithOptionalParamsWithFake::class
|
||||||
|
abstract val function: KtFunctionLikeSymbol
|
||||||
|
}
|
||||||
|
|
||||||
abstract class DelegationByDynamic : KtFirDiagnostic<KtElement>() {
|
abstract class DelegationByDynamic : KtFirDiagnostic<KtElement>() {
|
||||||
override val diagnosticClass get() = DelegationByDynamic::class
|
override val diagnosticClass get() = DelegationByDynamic::class
|
||||||
}
|
}
|
||||||
|
|||||||
+16
@@ -3911,6 +3911,22 @@ internal class JavaSamInterfaceConstructorReferenceImpl(
|
|||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
) : KtFirDiagnostic.JavaSamInterfaceConstructorReference(), KtAbstractFirDiagnostic<PsiElement>
|
) : KtFirDiagnostic.JavaSamInterfaceConstructorReference(), KtAbstractFirDiagnostic<PsiElement>
|
||||||
|
|
||||||
|
internal class ImplementingFunctionInterfaceImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.ImplementingFunctionInterface(), KtAbstractFirDiagnostic<KtClassOrObject>
|
||||||
|
|
||||||
|
internal class OverridingExternalFunWithOptionalParamsImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.OverridingExternalFunWithOptionalParams(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class OverridingExternalFunWithOptionalParamsWithFakeImpl(
|
||||||
|
override val function: KtFunctionLikeSymbol,
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.OverridingExternalFunWithOptionalParamsWithFake(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
internal class DelegationByDynamicImpl(
|
internal class DelegationByDynamicImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
|
|||||||
+13
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.fir.PrivateForInline
|
|||||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
|
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
|
||||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
|
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
|
||||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused")
|
@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused")
|
||||||
@@ -27,6 +29,17 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val FUN_INTERFACES by object : DiagnosticGroup("Fun Interfaces") {
|
||||||
|
val IMPLEMENTING_FUNCTION_INTERFACE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
}
|
||||||
|
|
||||||
|
val EXTERNAL by object : DiagnosticGroup("External") {
|
||||||
|
val OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
val OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
|
parameter<FirNamedFunctionSymbol>("function")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
||||||
val DELEGATION_BY_DYNAMIC by error<KtElement>()
|
val DELEGATION_BY_DYNAMIC by error<KtElement>()
|
||||||
}
|
}
|
||||||
|
|||||||
+9
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
|
|||||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -27,6 +29,13 @@ object FirJsErrors {
|
|||||||
// Supertypes
|
// Supertypes
|
||||||
val WRONG_MULTIPLE_INHERITANCE by error1<KtElement, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val WRONG_MULTIPLE_INHERITANCE by error1<KtElement, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|
||||||
|
// Fun Interfaces
|
||||||
|
val IMPLEMENTING_FUNCTION_INTERFACE by error0<KtClassOrObject>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|
||||||
|
// External
|
||||||
|
val OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
val OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE by error1<KtElement, FirNamedFunctionSymbol>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|
||||||
// Dynamics
|
// Dynamics
|
||||||
val DELEGATION_BY_DYNAMIC by error0<KtElement>()
|
val DELEGATION_BY_DYNAMIC by error0<KtElement>()
|
||||||
|
|
||||||
|
|||||||
+10
@@ -10,9 +10,12 @@ import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.checkMissingMessages
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.checkMissingMessages
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.DELEGATION_BY_DYNAMIC
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.DELEGATION_BY_DYNAMIC
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_MODULE_PROHIBITED_ON_NON_NATIVE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_MODULE_PROHIBITED_ON_NON_NATIVE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_MODULE_PROHIBITED_ON_VAR
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_MODULE_PROHIBITED_ON_VAR
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_JS_MODULE_PROHIBITED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_JS_MODULE_PROHIBITED
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_JS_QUALIFIER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_JS_QUALIFIER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_MULTIPLE_INHERITANCE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_MULTIPLE_INHERITANCE
|
||||||
|
|
||||||
@@ -32,6 +35,13 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
FirDiagnosticRenderers.SYMBOL
|
FirDiagnosticRenderers.SYMBOL
|
||||||
)
|
)
|
||||||
map.put(DELEGATION_BY_DYNAMIC, "Can't delegate to dynamic value")
|
map.put(DELEGATION_BY_DYNAMIC, "Can't delegate to dynamic value")
|
||||||
|
map.put(IMPLEMENTING_FUNCTION_INTERFACE, "Implementing function interface is prohibited in JavaScript")
|
||||||
|
map.put(OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS, "Overriding `external` function with optional parameters")
|
||||||
|
map.put(
|
||||||
|
OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE,
|
||||||
|
"Overriding `external` function with optional parameters by declaration from superclass: {0}",
|
||||||
|
FirDiagnosticRenderers.SYMBOL
|
||||||
|
)
|
||||||
|
|
||||||
map.checkMissingMessages(FirJsErrors)
|
map.checkMissingMessages(FirJsErrors)
|
||||||
}
|
}
|
||||||
|
|||||||
+18
@@ -7,12 +7,16 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.js.checkers
|
package org.jetbrains.kotlin.fir.analysis.js.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.directOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.hasAnnotationOrInsideAnnotatedClass
|
import org.jetbrains.kotlin.fir.analysis.checkers.hasAnnotationOrInsideAnnotatedClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||||
|
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
@@ -42,6 +46,20 @@ fun FirBasedSymbol<*>.isEffectivelyExternal(session: FirSession): Boolean {
|
|||||||
return getContainingClassSymbol(session)?.isEffectivelyExternal(session) == true
|
return getContainingClassSymbol(session)?.isEffectivelyExternal(session) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirBasedSymbol<*>.isEffectivelyExternal(context: CheckerContext) = isEffectivelyExternal(context.session)
|
||||||
|
|
||||||
|
fun FirFunctionSymbol<*>.isOverridingExternalWithOptionalParams(context: CheckerContext): Boolean {
|
||||||
|
if (!isSubstitutionOrIntersectionOverride && modality == Modality.ABSTRACT) return false
|
||||||
|
|
||||||
|
val overridden = (this as? FirNamedFunctionSymbol)?.directOverriddenFunctions(context) ?: return false
|
||||||
|
|
||||||
|
for (overriddenFunction in overridden.filter { it.isEffectivelyExternal(context) }) {
|
||||||
|
if (overriddenFunction.valueParameterSymbols.any { it.hasDefaultValue }) return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
fun FirBasedSymbol<*>.isNativeObject(session: FirSession): Boolean {
|
fun FirBasedSymbol<*>.isNativeObject(session: FirSession): Boolean {
|
||||||
if (hasAnnotationOrInsideAnnotatedClass(JsStandardClassIds.Annotations.JsNative, session) || isEffectivelyExternal(session)) {
|
if (hasAnnotationOrInsideAnnotatedClass(JsStandardClassIds.Annotations.JsNative, session) || isEffectivelyExternal(session)) {
|
||||||
return true
|
return true
|
||||||
|
|||||||
+2
@@ -12,6 +12,7 @@ object JsDeclarationCheckers : DeclarationCheckers() {
|
|||||||
override val functionCheckers: Set<FirFunctionChecker>
|
override val functionCheckers: Set<FirFunctionChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirJsInlineDeclarationChecker,
|
FirJsInlineDeclarationChecker,
|
||||||
|
FirJsInheritanceFunctionChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val propertyCheckers: Set<FirPropertyChecker>
|
override val propertyCheckers: Set<FirPropertyChecker>
|
||||||
@@ -28,5 +29,6 @@ object JsDeclarationCheckers : DeclarationCheckers() {
|
|||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirJsMultipleInheritanceChecker,
|
FirJsMultipleInheritanceChecker,
|
||||||
FirJsDynamicDeclarationChecker,
|
FirJsDynamicDeclarationChecker,
|
||||||
|
FirJsInheritanceClassChecker,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.js.checkers.declaration
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
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.context.CheckerContext
|
||||||
|
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.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.typeContext
|
||||||
|
|
||||||
|
object FirJsInheritanceClassChecker : FirClassChecker() {
|
||||||
|
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (!declaration.symbol.isEffectivelyExternal(context)) {
|
||||||
|
val fakeOverriddenMethod = declaration.findFakeMethodOverridingExternalWithOptionalParams(context)
|
||||||
|
|
||||||
|
if (fakeOverriddenMethod != null) {
|
||||||
|
reporter.reportOn(
|
||||||
|
declaration.source, FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE,
|
||||||
|
fakeOverriddenMethod, context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!context.languageVersionSettings.supportsFeature(LanguageFeature.JsAllowImplementingFunctionInterface) &&
|
||||||
|
declaration.superConeTypes.any {
|
||||||
|
it.isBuiltinFunctionalTypeOrSubtype(context.session) && !it.isSuspendFunctionTypeOrSubtype(context.session)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
reporter.reportOn(declaration.source, FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeClassLikeType.isBuiltinFunctionalTypeOrSubtype(session: FirSession): Boolean {
|
||||||
|
return with(session.typeContext) { isBuiltinFunctionalTypeOrSubtype() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeClassLikeType.isSuspendFunctionTypeOrSubtype(session: FirSession): Boolean {
|
||||||
|
return with(session.typeContext) { isSuspendFunctionTypeOrSubtype() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirClass.findFakeMethodOverridingExternalWithOptionalParams(context: CheckerContext): FirNamedFunctionSymbol? {
|
||||||
|
val scope = symbol.unsubstitutedScope(context)
|
||||||
|
|
||||||
|
val members = scope.collectAllFunctions()
|
||||||
|
.filterIsInstance<FirIntersectionOverrideFunctionSymbol>()
|
||||||
|
.filter {
|
||||||
|
val container = it.getContainingClassSymbol(context.session)
|
||||||
|
container == symbol && it.intersections.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
return members.firstOrNull {
|
||||||
|
it.isOverridingExternalWithOptionalParams(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.js.checkers.declaration
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirFunctionChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.isOverridingExternalWithOptionalParams
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
|
|
||||||
|
object FirJsInheritanceFunctionChecker : FirFunctionChecker() {
|
||||||
|
override fun check(declaration: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (declaration.isNotEffectivelyExternalFunctionButOverridesExternal(context)) {
|
||||||
|
reporter.reportOn(declaration.source, FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirDeclaration.isNotEffectivelyExternalFunctionButOverridesExternal(context: CheckerContext): Boolean {
|
||||||
|
if (this !is FirFunction || symbol.isEffectivelyExternal(context)) return false
|
||||||
|
return symbol.isOverridingExternalWithOptionalParams(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
-16
@@ -14,34 +14,26 @@ import org.jetbrains.kotlin.descriptors.Modality
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.diagnostics.*
|
import org.jetbrains.kotlin.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.primaryConstructorSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.primaryConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.getChild
|
import org.jetbrains.kotlin.fir.analysis.getChild
|
||||||
import org.jetbrains.kotlin.fir.containingClassForLocalAttr
|
|
||||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.SessionHolder
|
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.scopes.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature
|
import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature
|
||||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
@@ -138,11 +130,13 @@ fun FirTypeRef.toRegularClassSymbol(session: FirSession): FirRegularClassSymbol?
|
|||||||
* Returns the ClassLikeDeclaration where the Fir object has been defined
|
* Returns the ClassLikeDeclaration where the Fir object has been defined
|
||||||
* or null if no proper declaration has been found.
|
* or null if no proper declaration has been found.
|
||||||
*/
|
*/
|
||||||
fun FirDeclaration.getContainingClassSymbol(session: FirSession): FirClassLikeSymbol<*>? =
|
fun FirBasedSymbol<*>.getContainingClassSymbol(session: FirSession): FirClassLikeSymbol<*>? = when (this) {
|
||||||
(this as? FirCallableDeclaration)?.containingClassLookupTag()?.toSymbol(session)
|
is FirCallableSymbol<*> -> containingClassLookupTag()?.toSymbol(session)
|
||||||
|
is FirClassLikeSymbol<*> -> getContainingClassLookupTag()?.toSymbol(session)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(SymbolInternals::class)
|
fun FirDeclaration.getContainingClassSymbol(session: FirSession) = symbol.getContainingClassSymbol(session)
|
||||||
fun FirBasedSymbol<*>.getContainingClassSymbol(session: FirSession): FirClassLikeSymbol<*>? = fir.getContainingClassSymbol(session)
|
|
||||||
|
|
||||||
fun FirClassLikeSymbol<*>.outerClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? {
|
fun FirClassLikeSymbol<*>.outerClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? {
|
||||||
if (this !is FirClassSymbol<*>) return null
|
if (this !is FirClassSymbol<*>) return null
|
||||||
@@ -708,6 +702,17 @@ fun ConeKotlinType.getInlineClassUnderlyingType(session: FirSession): ConeKotlin
|
|||||||
return toRegularClassSymbol(session)!!.primaryConstructorSymbol()!!.valueParameterSymbols[0].resolvedReturnTypeRef.coneType
|
return toRegularClassSymbol(session)!!.primaryConstructorSymbol()!!.valueParameterSymbols[0].resolvedReturnTypeRef.coneType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirNamedFunctionSymbol.directOverriddenFunctions(session: FirSession, scopeSession: ScopeSession): List<FirNamedFunctionSymbol> {
|
||||||
|
val classSymbol = getContainingClassSymbol(session) as? FirClassSymbol ?: return emptyList()
|
||||||
|
val scope = classSymbol.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
|
||||||
|
|
||||||
|
scope.processFunctionsByName(name) { }
|
||||||
|
return scope.getDirectOverriddenFunctions(this, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirNamedFunctionSymbol.directOverriddenFunctions(context: CheckerContext) =
|
||||||
|
directOverriddenFunctions(context.session, context.sessionHolder.scopeSession)
|
||||||
|
|
||||||
fun CheckerContext.closestNonLocalWith(declaration: FirDeclaration) =
|
fun CheckerContext.closestNonLocalWith(declaration: FirDeclaration) =
|
||||||
(containingDeclarations + declaration).takeWhile { it.isNonLocal }.lastOrNull()
|
(containingDeclarations + declaration).takeWhile { it.isNonLocal }.lastOrNull()
|
||||||
|
|
||||||
|
|||||||
@@ -32,3 +32,9 @@ fun FirContainingNamesAwareScope.collectAllProperties(): Collection<FirVariableS
|
|||||||
processAllProperties(this::add)
|
processAllProperties(this::add)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirContainingNamesAwareScope.collectAllFunctions(): Collection<FirNamedFunctionSymbol> {
|
||||||
|
return mutableListOf<FirNamedFunctionSymbol>().apply {
|
||||||
|
processAllFunctions(this::add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// IGNORE_BACKEND_K1: JS, JS_IR
|
// IGNORE_BACKEND_K1: JS, JS_IR
|
||||||
|
// IGNORE_BACKEND_K2: JS_IR
|
||||||
|
|
||||||
fun interface Foo : () -> Int
|
fun interface Foo : () -> Int
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// IGNORE_BACKEND_K1: JS_IR
|
// IGNORE_BACKEND_K1: JS_IR
|
||||||
|
// IGNORE_BACKEND_K2: JS_IR
|
||||||
// IGNORE_BACKEND: JS_IR_ES6
|
// IGNORE_BACKEND: JS_IR_ES6
|
||||||
//KT-3822 Compiler crashes when use invoke convention with `this` in class which extends Function0<T>
|
//KT-3822 Compiler crashes when use invoke convention with `this` in class which extends Function0<T>
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
abstract class A : () -> Unit
|
|
||||||
|
|
||||||
object B : (String, Int) -> Long {
|
|
||||||
override fun invoke(a: String, B: Int) = 23L
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class C : kotlin.Function1<Any, Int>
|
|
||||||
|
|
||||||
abstract class D : C()
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
abstract class <!IMPLEMENTING_FUNCTION_INTERFACE!>A<!> : () -> Unit
|
abstract class <!IMPLEMENTING_FUNCTION_INTERFACE!>A<!> : () -> Unit
|
||||||
|
|
||||||
<!IMPLEMENTING_FUNCTION_INTERFACE!>object B<!> : (String, Int) -> Long {
|
<!IMPLEMENTING_FUNCTION_INTERFACE!>object B<!> : (String, Int) -> Long {
|
||||||
|
|||||||
+4
-4
@@ -3,7 +3,7 @@ open external class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class B : A() {
|
class B : A() {
|
||||||
override fun f(x: Int) {}
|
<!OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS!>override fun f(x: Int)<!> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BB : A()
|
class BB : A()
|
||||||
@@ -36,7 +36,7 @@ class E : D() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class F : D(), I {
|
class F : D(), I {
|
||||||
override fun f(x: Int) {}
|
<!OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS!>override fun f(x: Int)<!> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
external class G : D, I {
|
external class G : D, I {
|
||||||
@@ -51,9 +51,9 @@ open external class XE {
|
|||||||
fun f(x: Int)
|
fun f(x: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Y : X(), I
|
class <!OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE!>Y<!> : X(), I
|
||||||
|
|
||||||
class YY : A(), II
|
class <!OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE!>YY<!> : A(), II
|
||||||
|
|
||||||
external class YE: XE, I
|
external class YE: XE, I
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user