[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,
|
||||
)
|
||||
}
|
||||
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 ->
|
||||
DelegationByDynamicImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
|
||||
+13
@@ -3233,6 +3233,19 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
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>() {
|
||||
override val diagnosticClass get() = DelegationByDynamic::class
|
||||
}
|
||||
|
||||
+16
@@ -3911,6 +3911,22 @@ internal class JavaSamInterfaceConstructorReferenceImpl(
|
||||
override val token: KtLifetimeToken,
|
||||
) : 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(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
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.PositioningStrategy
|
||||
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
|
||||
|
||||
@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 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.fir.analysis.diagnostics.*
|
||||
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
|
||||
|
||||
/*
|
||||
@@ -27,6 +29,13 @@ object FirJsErrors {
|
||||
// Supertypes
|
||||
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
|
||||
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.checkMissingMessages
|
||||
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_VAR
|
||||
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_MULTIPLE_INHERITANCE
|
||||
|
||||
@@ -32,6 +35,13 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
FirDiagnosticRenderers.SYMBOL
|
||||
)
|
||||
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)
|
||||
}
|
||||
|
||||
+18
@@ -7,12 +7,16 @@
|
||||
|
||||
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.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.hasAnnotationOrInsideAnnotatedClass
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
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.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
@@ -42,6 +46,20 @@ fun FirBasedSymbol<*>.isEffectivelyExternal(session: FirSession): Boolean {
|
||||
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 {
|
||||
if (hasAnnotationOrInsideAnnotatedClass(JsStandardClassIds.Annotations.JsNative, session) || isEffectivelyExternal(session)) {
|
||||
return true
|
||||
|
||||
+2
@@ -12,6 +12,7 @@ object JsDeclarationCheckers : DeclarationCheckers() {
|
||||
override val functionCheckers: Set<FirFunctionChecker>
|
||||
get() = setOf(
|
||||
FirJsInlineDeclarationChecker,
|
||||
FirJsInheritanceFunctionChecker,
|
||||
)
|
||||
|
||||
override val propertyCheckers: Set<FirPropertyChecker>
|
||||
@@ -28,5 +29,6 @@ object JsDeclarationCheckers : DeclarationCheckers() {
|
||||
get() = setOf(
|
||||
FirJsMultipleInheritanceChecker,
|
||||
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.annotations.KotlinTarget
|
||||
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.declaration.primaryConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
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.utils.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.SessionHolder
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||
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.*
|
||||
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.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.*
|
||||
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
|
||||
* or null if no proper declaration has been found.
|
||||
*/
|
||||
fun FirDeclaration.getContainingClassSymbol(session: FirSession): FirClassLikeSymbol<*>? =
|
||||
(this as? FirCallableDeclaration)?.containingClassLookupTag()?.toSymbol(session)
|
||||
fun FirBasedSymbol<*>.getContainingClassSymbol(session: FirSession): FirClassLikeSymbol<*>? = when (this) {
|
||||
is FirCallableSymbol<*> -> containingClassLookupTag()?.toSymbol(session)
|
||||
is FirClassLikeSymbol<*> -> getContainingClassLookupTag()?.toSymbol(session)
|
||||
else -> null
|
||||
}
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
fun FirBasedSymbol<*>.getContainingClassSymbol(session: FirSession): FirClassLikeSymbol<*>? = fir.getContainingClassSymbol(session)
|
||||
fun FirDeclaration.getContainingClassSymbol(session: FirSession) = symbol.getContainingClassSymbol(session)
|
||||
|
||||
fun FirClassLikeSymbol<*>.outerClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? {
|
||||
if (this !is FirClassSymbol<*>) return null
|
||||
@@ -708,6 +702,17 @@ fun ConeKotlinType.getInlineClassUnderlyingType(session: FirSession): ConeKotlin
|
||||
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) =
|
||||
(containingDeclarations + declaration).takeWhile { it.isNonLocal }.lastOrNull()
|
||||
|
||||
|
||||
@@ -32,3 +32,9 @@ fun FirContainingNamesAwareScope.collectAllProperties(): Collection<FirVariableS
|
||||
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_K2: JS_IR
|
||||
|
||||
fun interface Foo : () -> Int
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// IGNORE_BACKEND_K1: JS_IR
|
||||
// IGNORE_BACKEND_K2: JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
//KT-3822 Compiler crashes when use invoke convention with `this` in class which extends Function0<T>
|
||||
// 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
|
||||
|
||||
<!IMPLEMENTING_FUNCTION_INTERFACE!>object B<!> : (String, Int) -> Long {
|
||||
|
||||
+4
-4
@@ -3,7 +3,7 @@ open external class A {
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
override fun f(x: Int) {}
|
||||
<!OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS!>override fun f(x: Int)<!> {}
|
||||
}
|
||||
|
||||
class BB : A()
|
||||
@@ -36,7 +36,7 @@ class E : D() {
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -51,9 +51,9 @@ open external class XE {
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user