[FIR][K/N] Don't use FIR internals in FirNativeObjCOverrideInitChecker
^KT-61564
This commit is contained in:
committed by
Space Team
parent
ad9f7bf90e
commit
55a41961d3
+18
-11
@@ -18,28 +18,35 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.getSuperClassSymbolOrAny
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.NativeStandardInteropNames.objCOverrideInitClassId
|
||||
|
||||
object FirNativeObjCOverrideInitChecker : FirClassChecker() {
|
||||
@OptIn(SymbolInternals::class)
|
||||
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val session = context.session
|
||||
|
||||
fun FirConstructor.overridesConstructor(other: FirConstructor): Boolean {
|
||||
if (valueParameters.size != other.valueParameters.size)
|
||||
fun FirClassSymbol<*>.constructors(session: FirSession): List<FirConstructorSymbol> {
|
||||
val result = mutableListOf<FirConstructorSymbol>()
|
||||
session.declaredMemberScope(this, memberRequiredPhase = null).processDeclaredConstructors { result += it }
|
||||
return result
|
||||
}
|
||||
|
||||
fun FirConstructorSymbol.overridesConstructor(other: FirConstructorSymbol): Boolean {
|
||||
val aParams = this.valueParameterSymbols
|
||||
val bParams = other.valueParameterSymbols
|
||||
if (aParams.size != bParams.size)
|
||||
return false
|
||||
return valueParameters.zip(other.valueParameters).all { (thisParameter, otherParameter) ->
|
||||
thisParameter.name == otherParameter.name && thisParameter.returnTypeRef.coneType == otherParameter.returnTypeRef.coneType
|
||||
return aParams.zip(bParams).all { (thisParameter, otherParameter) ->
|
||||
thisParameter.name == otherParameter.name && thisParameter.resolvedReturnType == otherParameter.resolvedReturnType
|
||||
}
|
||||
}
|
||||
|
||||
fun checkCanGenerateOverrideInit(firClass: FirClass, constructor: FirConstructor) {
|
||||
val superClass = (firClass as FirRegularClass).symbol.getSuperClassSymbolOrAny(session)
|
||||
val superConstructors = superClass.fir.constructors(session).filter {
|
||||
constructor.overridesConstructor(it.fir)
|
||||
val superConstructors = superClass.constructors(session).filter {
|
||||
constructor.symbol.overridesConstructor(it)
|
||||
}.toList()
|
||||
|
||||
val superConstructor: FirConstructorSymbol = superConstructors.singleOrNull() ?: run {
|
||||
@@ -60,11 +67,11 @@ object FirNativeObjCOverrideInitChecker : FirClassChecker() {
|
||||
return
|
||||
}
|
||||
|
||||
val initMethod = superConstructor.fir.getObjCInitMethod(session, ScopeSession())!!
|
||||
val initMethod = superConstructor.getObjCInitMethod(session, ScopeSession())!!
|
||||
|
||||
// Remove fake overrides of this init method, also check for explicit overriding:
|
||||
firClass.declarations.forEach {
|
||||
if (it is FirSimpleFunction && initMethod.symbol in it.getOverriddenSymbols(context) && !it.isSubstitutionOrIntersectionOverride) {
|
||||
if (it is FirSimpleFunction && initMethod in it.getOverriddenSymbols(context) && !it.isSubstitutionOrIntersectionOverride) {
|
||||
reporter.reportOn(
|
||||
constructor.source,
|
||||
FirNativeErrors.CONSTRUCTOR_OVERRIDES_ALREADY_OVERRIDDEN_OBJC_INITIALIZER,
|
||||
|
||||
+33
-8
@@ -13,12 +13,15 @@ import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.processAllFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.scopeForClass
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -69,18 +72,40 @@ fun FirConstructor.getObjCInitMethod(session: FirSession, scopeSession: ScopeSes
|
||||
return null
|
||||
}
|
||||
|
||||
fun FirConstructorSymbol.getObjCInitMethod(session: FirSession, scopeSession: ScopeSession): FirFunctionSymbol<*>? {
|
||||
this.annotations.getAnnotationByClassId(NativeStandardInteropNames.objCConstructorClassId, session)?.let { annotation ->
|
||||
val initSelector: String = annotation.constStringArgument("initSelector")
|
||||
val classSymbol = containingClassLookupTag()?.toSymbol(session) as FirClassSymbol<*>
|
||||
val initSelectors = mutableListOf<FirFunctionSymbol<*>>()
|
||||
session.declaredMemberScope(classSymbol, memberRequiredPhase = null)
|
||||
.processAllFunctions {
|
||||
if (it.decodeObjCMethodAnnotation(session)?.selector == initSelector)
|
||||
initSelectors.add(it)
|
||||
}
|
||||
return initSelectors.singleOrNull()
|
||||
?: error("expected one init method for $classSymbol $initSelector, got ${initSelectors.size}")
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* mimics FunctionDescriptor.decodeObjCMethodAnnotation()
|
||||
*/
|
||||
internal fun List<FirAnnotation>.decodeObjCMethodAnnotation(session: FirSession): ObjCMethodInfo? =
|
||||
getAnnotationByClassId(NativeStandardInteropNames.objCMethodClassId, session)?.let {
|
||||
ObjCMethodInfo(
|
||||
selector = it.constStringArgument("selector"),
|
||||
encoding = it.constStringArgument("encoding"),
|
||||
isStret = it.constBooleanArgumentOrNull("isStret") ?: false,
|
||||
directSymbol = getAnnotationByClassId(NativeStandardInteropNames.objCDirectClassId, session)?.constStringArgument("symbol"),
|
||||
)
|
||||
}
|
||||
|
||||
internal fun FirFunction.decodeObjCMethodAnnotation(session: FirSession): ObjCMethodInfo? =
|
||||
annotations.getAnnotationByClassId(NativeStandardInteropNames.objCMethodClassId, session)?.let {
|
||||
ObjCMethodInfo(
|
||||
selector = it.constStringArgument("selector"),
|
||||
encoding = it.constStringArgument("encoding"),
|
||||
isStret = it.constBooleanArgumentOrNull("isStret") ?: false,
|
||||
directSymbol = annotations.getAnnotationByClassId(NativeStandardInteropNames.objCDirectClassId, session)?.constStringArgument("symbol"),
|
||||
)
|
||||
}
|
||||
annotations.decodeObjCMethodAnnotation(session)
|
||||
|
||||
internal fun FirFunctionSymbol<*>.decodeObjCMethodAnnotation(session: FirSession): ObjCMethodInfo? =
|
||||
annotations.decodeObjCMethodAnnotation(session)
|
||||
|
||||
|
||||
private fun FirAnnotation.constStringArgument(argumentName: String): String =
|
||||
|
||||
Reference in New Issue
Block a user