[FIR] Cleanup FIR modules. Part 1 (calls package)
This commit is contained in:
+10
-15
@@ -20,12 +20,6 @@ abstract class AbstractConeCallConflictResolver(
|
||||
private val specificityComparator: TypeSpecificityComparator,
|
||||
protected val inferenceComponents: InferenceComponents
|
||||
) : ConeCallConflictResolver() {
|
||||
protected fun Collection<Candidate>.setIfOneOrEmpty(): Set<Candidate>? = when (size) {
|
||||
0 -> emptySet()
|
||||
1 -> setOf(single())
|
||||
else -> null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if [call1] is definitely more or equally specific [call2],
|
||||
* `false` otherwise.
|
||||
@@ -56,6 +50,7 @@ abstract class AbstractConeCallConflictResolver(
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("PrivatePropertyName")
|
||||
private val SpecificityComparisonWithNumerics = object : SpecificityComparisonCallbacks {
|
||||
override fun isNonSubtypeNotLessSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean {
|
||||
requireOrDescribe(specific is ConeKotlinType, specific)
|
||||
@@ -83,18 +78,18 @@ abstract class AbstractConeCallConflictResolver(
|
||||
when {
|
||||
//TypeUtils.equalTypes(specific, _double) && TypeUtils.equalTypes(general, _float) -> return true
|
||||
specificClassId == int -> {
|
||||
when {
|
||||
generalClassId == long -> return true
|
||||
generalClassId == byte -> return true
|
||||
generalClassId == short -> return true
|
||||
when (generalClassId) {
|
||||
long -> return true
|
||||
byte -> return true
|
||||
short -> return true
|
||||
}
|
||||
}
|
||||
specificClassId == short && generalClassId == byte -> return true
|
||||
specificClassId == uInt -> {
|
||||
when {
|
||||
generalClassId == uLong -> return true
|
||||
generalClassId == uByte -> return true
|
||||
generalClassId == uShort -> return true
|
||||
when (generalClassId) {
|
||||
uLong -> return true
|
||||
uByte -> return true
|
||||
uShort -> return true
|
||||
}
|
||||
}
|
||||
specificClassId == uShort && generalClassId == uByte -> return true
|
||||
@@ -117,7 +112,7 @@ abstract class AbstractConeCallConflictResolver(
|
||||
return FlatSignature(
|
||||
call,
|
||||
(variable as? FirProperty)?.typeParameters?.map { it.symbol }.orEmpty(),
|
||||
listOfNotNull<ConeKotlinType>(variable.receiverTypeRef?.coneTypeUnsafe()),
|
||||
listOfNotNull(variable.receiverTypeRef?.coneTypeUnsafe()),
|
||||
variable.receiverTypeRef != null,
|
||||
false,
|
||||
0,
|
||||
|
||||
@@ -291,7 +291,6 @@ internal fun Candidate.resolveArgument(
|
||||
argument: FirExpression,
|
||||
parameter: FirValueParameter?,
|
||||
isReceiver: Boolean,
|
||||
isSafeCall: Boolean,
|
||||
sink: CheckerSink
|
||||
) {
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ import org.jetbrains.kotlin.fir.returnExpressions
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
@@ -113,12 +111,17 @@ class CandidateFactory private constructor(
|
||||
|
||||
fun PostponedArgumentsAnalyzer.Context.addSubsystemFromExpression(statement: FirStatement) {
|
||||
when (statement) {
|
||||
is FirFunctionCall, is FirQualifiedAccessExpression, is FirWhenExpression, is FirTryExpression, is FirCheckNotNullCall, is FirCallableReferenceAccess ->
|
||||
(statement as FirResolvable).candidate()?.let { addOtherSystem(it.system.asReadOnlyStorage()) }
|
||||
is FirFunctionCall,
|
||||
is FirQualifiedAccessExpression,
|
||||
is FirWhenExpression,
|
||||
is FirTryExpression,
|
||||
is FirCheckNotNullCall,
|
||||
is FirCallableReferenceAccess
|
||||
-> (statement as FirResolvable).candidate()?.let { addOtherSystem(it.system.asReadOnlyStorage()) }
|
||||
|
||||
is FirSafeCallExpression -> addSubsystemFromExpression(statement.regularQualifiedAccess)
|
||||
is FirWrappedArgumentExpression -> addSubsystemFromExpression(statement.expression)
|
||||
is FirBlock -> statement.returnExpressions().forEach { addSubsystemFromExpression(it) }
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.FirDeclaredUpperBoundConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||
|
||||
|
||||
internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val declaration = candidate.symbol.fir
|
||||
@@ -41,7 +40,6 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// optimization
|
||||
if (candidate.typeArgumentMapping == TypeArgumentMapping.NoExplicitArguments /*&& knownTypeParametersResultingSubstitutor == null*/) {
|
||||
return
|
||||
@@ -62,8 +60,6 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
||||
// continue
|
||||
// }
|
||||
|
||||
|
||||
//
|
||||
when (val typeArgument = candidate.typeArgumentMapping[index]) {
|
||||
is FirTypeProjectionWithVariance -> csBuilder.addEqualityConstraint(
|
||||
freshVariable.defaultType,
|
||||
@@ -111,7 +107,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
||||
|
||||
}
|
||||
|
||||
fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||
private fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||
declaration: FirTypeParameterRefsOwner,
|
||||
candidate: Candidate,
|
||||
csBuilder: ConstraintSystemOperation,
|
||||
|
||||
-1
@@ -18,7 +18,6 @@ import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
|
||||
|
||||
data class ArgumentMapping(
|
||||
// This map should be ordered by arguments as written, e.g.:
|
||||
// fun foo(a: Int, b: Int) {}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionWithSmartcast
|
||||
@@ -23,11 +22,8 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
|
||||
interface Receiver {
|
||||
|
||||
}
|
||||
interface Receiver
|
||||
|
||||
interface ReceiverValue : Receiver {
|
||||
val type: ConeKotlinType
|
||||
@@ -38,26 +34,6 @@ interface ReceiverValue : Receiver {
|
||||
type.scope(useSiteSession, scopeSession)
|
||||
}
|
||||
|
||||
private fun receiverExpression(symbol: AbstractFirBasedSymbol<*>, type: ConeKotlinType): FirThisReceiverExpression =
|
||||
buildThisReceiverExpression {
|
||||
calleeReference = buildImplicitThisReference {
|
||||
boundSymbol = symbol
|
||||
}
|
||||
typeRef = buildResolvedTypeRef {
|
||||
this.type = type
|
||||
}
|
||||
}
|
||||
|
||||
class ClassDispatchReceiverValue(klassSymbol: FirClassSymbol<*>) : ReceiverValue {
|
||||
override val type: ConeKotlinType = ConeClassLikeTypeImpl(
|
||||
klassSymbol.toLookupTag(),
|
||||
(klassSymbol.fir as? FirTypeParameterRefsOwner)?.typeParameters?.map { ConeStarProjection }?.toTypedArray().orEmpty(),
|
||||
isNullable = false
|
||||
)
|
||||
|
||||
override val receiverExpression: FirExpression = receiverExpression(klassSymbol, type)
|
||||
}
|
||||
|
||||
// TODO: should inherit just Receiver, not ReceiverValue
|
||||
abstract class AbstractExplicitReceiver<E : FirExpression> : Receiver {
|
||||
abstract val explicitReceiver: FirExpression
|
||||
@@ -85,8 +61,7 @@ sealed class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
||||
final override var type: ConeKotlinType = type
|
||||
private set
|
||||
|
||||
var implicitScope: FirTypeScope? = type.scope(useSiteSession, scopeSession)
|
||||
private set
|
||||
private var implicitScope: FirTypeScope? = type.scope(useSiteSession, scopeSession)
|
||||
|
||||
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? = implicitScope
|
||||
|
||||
@@ -113,6 +88,16 @@ sealed class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
||||
}
|
||||
}
|
||||
|
||||
private fun receiverExpression(symbol: AbstractFirBasedSymbol<*>, type: ConeKotlinType): FirThisReceiverExpression =
|
||||
buildThisReceiverExpression {
|
||||
calleeReference = buildImplicitThisReference {
|
||||
boundSymbol = symbol
|
||||
}
|
||||
typeRef = buildResolvedTypeRef {
|
||||
this.type = type
|
||||
}
|
||||
}
|
||||
|
||||
class ImplicitDispatchReceiverValue internal constructor(
|
||||
boundSymbol: FirClassSymbol<*>,
|
||||
type: ConeKotlinType,
|
||||
|
||||
+3
-10
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
|
||||
|
||||
fun FirClassLikeDeclaration<*>.fullyExpandedClass(useSiteSession: FirSession): FirRegularClass? {
|
||||
if (this is FirTypeAlias) return this.expandedConeType?.lookupTag?.toSymbol(useSiteSession)?.fir?.fullyExpandedClass(useSiteSession)
|
||||
if (this is FirRegularClass) return this
|
||||
@@ -33,21 +32,17 @@ fun createQualifierReceiver(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
): QualifierReceiver? {
|
||||
|
||||
val classLikeSymbol = explicitReceiver.symbol
|
||||
when {
|
||||
return when {
|
||||
classLikeSymbol != null -> {
|
||||
val classSymbol = classLikeSymbol.fir.fullyExpandedClass(useSiteSession)?.symbol ?: return null
|
||||
return ClassQualifierReceiver(explicitReceiver, classSymbol, classLikeSymbol, useSiteSession, scopeSession)
|
||||
}
|
||||
else -> {
|
||||
return PackageQualifierReceiver(explicitReceiver, useSiteSession)
|
||||
ClassQualifierReceiver(explicitReceiver, classSymbol, classLikeSymbol, useSiteSession, scopeSession)
|
||||
}
|
||||
else -> PackageQualifierReceiver(explicitReceiver, useSiteSession)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class QualifierReceiver(final override val explicitReceiver: FirExpression) : AbstractExplicitReceiver<FirResolvedQualifier>() {
|
||||
|
||||
abstract fun classifierScope(): FirScope?
|
||||
abstract fun callableScope(): FirScope?
|
||||
}
|
||||
@@ -70,10 +65,8 @@ class ClassQualifierReceiver(
|
||||
val klass = classSymbol.fir
|
||||
return klass.scopeProvider.getNestedClassifierScope(klass, useSiteSession, scopeSession)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class PackageQualifierReceiver(
|
||||
explicitReceiver: FirResolvedQualifier,
|
||||
useSiteSession: FirSession
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@ abstract class InapplicableArgumentDiagnostic : ResolutionDiagnostic(CandidateAp
|
||||
}
|
||||
|
||||
class MixingNamedAndPositionArguments(override val argument: FirExpression) : InapplicableArgumentDiagnostic()
|
||||
|
||||
class TooManyArguments(
|
||||
val argument: FirExpression,
|
||||
val function: FirFunction<*>
|
||||
@@ -48,4 +49,4 @@ class NoValueForParameter(
|
||||
class NameNotFound(
|
||||
override val argument: FirExpression,
|
||||
val function: FirFunction<*>
|
||||
) : InapplicableArgumentDiagnostic()
|
||||
) : InapplicableArgumentDiagnostic()
|
||||
|
||||
+79
-81
@@ -41,13 +41,6 @@ abstract class ResolutionStage {
|
||||
|
||||
abstract class CheckerStage : ResolutionStage()
|
||||
|
||||
internal fun FirExpression.isSuperReferenceExpression(): Boolean {
|
||||
return if (this is FirQualifiedAccessExpression) {
|
||||
val calleeReference = calleeReference
|
||||
calleeReference is FirSuperReference
|
||||
} else false
|
||||
}
|
||||
|
||||
internal object CheckExplicitReceiverConsistency : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val receiverKind = candidate.explicitReceiverKind
|
||||
@@ -101,7 +94,7 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
override fun Candidate.getReceiverType(): ConeKotlinType? {
|
||||
val callableSymbol = symbol as? FirCallableSymbol<*> ?: return null
|
||||
val callable = callableSymbol.fir
|
||||
val receiverType = (callable.receiverTypeRef as FirResolvedTypeRef?)?.type
|
||||
val receiverType = callable.receiverTypeRef?.coneTypeUnsafe<ConeKotlinType>()
|
||||
if (receiverType != null) return receiverType
|
||||
val returnTypeRef = callable.returnTypeRef as? FirResolvedTypeRef ?: return null
|
||||
if (!returnTypeRef.isExtensionFunctionType(bodyResolveComponents.session)) return null
|
||||
@@ -153,6 +146,13 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirExpression.isSuperReferenceExpression(): Boolean {
|
||||
return if (this is FirQualifiedAccessExpression) {
|
||||
val calleeReference = calleeReference
|
||||
calleeReference is FirSuperReference
|
||||
} else false
|
||||
}
|
||||
|
||||
internal object MapArguments : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val symbol = candidate.symbol as? FirFunctionSymbol<*> ?: return sink.reportApplicability(CandidateApplicability.HIDDEN)
|
||||
@@ -184,14 +184,13 @@ internal object MapArguments : ResolutionStage() {
|
||||
internal object CheckArguments : CheckerStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val argumentMapping =
|
||||
candidate.argumentMapping ?: throw IllegalStateException("Argument should be already mapped while checking arguments!")
|
||||
candidate.argumentMapping ?: error("Argument should be already mapped while checking arguments!")
|
||||
for (argument in callInfo.arguments) {
|
||||
val parameter = argumentMapping[argument]
|
||||
candidate.resolveArgument(
|
||||
argument,
|
||||
parameter,
|
||||
isReceiver = false,
|
||||
isSafeCall = false,
|
||||
sink = sink
|
||||
)
|
||||
if (candidate.system.hasContradiction) {
|
||||
@@ -205,9 +204,11 @@ internal object CheckArguments : CheckerStage() {
|
||||
internal object EagerResolveOfCallableReferences : CheckerStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
if (candidate.postponedAtoms.isEmpty()) return
|
||||
for (atom in candidate.postponedAtoms.filterIsInstance<ResolvedCallableReferenceAtom>()) {
|
||||
if (!candidate.bodyResolveComponents.callResolver.resolveCallableReference(candidate.csBuilder, atom)) {
|
||||
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE)
|
||||
for (atom in candidate.postponedAtoms) {
|
||||
if (atom is ResolvedCallableReferenceAtom) {
|
||||
if (!candidate.bodyResolveComponents.callResolver.resolveCallableReference(candidate.csBuilder, atom)) {
|
||||
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,7 +225,7 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
||||
else -> null
|
||||
}
|
||||
|
||||
val fir = with(candidate.bodyResolveComponents) {
|
||||
val fir: FirCallableDeclaration<*> = with(candidate.bodyResolveComponents) {
|
||||
candidateSymbol.phasedFir
|
||||
}
|
||||
|
||||
@@ -332,18 +333,29 @@ internal object DiscriminateSynthetics : CheckerStage() {
|
||||
}
|
||||
|
||||
internal object CheckVisibility : CheckerStage() {
|
||||
private fun AbstractFirBasedSymbol<*>.packageFqName(): FqName {
|
||||
return when (this) {
|
||||
is FirClassLikeSymbol<*> -> classId.packageFqName
|
||||
is FirCallableSymbol<*> -> callableId.packageName
|
||||
else -> error("No package fq name for $this")
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val symbol = candidate.symbol
|
||||
val declaration = symbol.fir
|
||||
if (declaration is FirMemberDeclaration) {
|
||||
if (!checkVisibility(declaration, symbol, sink, candidate)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration is FirConstructor) {
|
||||
val ownerClassId = declaration.symbol.callableId.classId!!
|
||||
val provider = declaration.session.firSymbolProvider
|
||||
val classSymbol = provider.getClassLikeSymbolByFqName(ownerClassId)
|
||||
|
||||
if (classSymbol is FirRegularClassSymbol) {
|
||||
if (classSymbol.fir.classKind.isSingleton) {
|
||||
sink.yieldApplicability(CandidateApplicability.HIDDEN)
|
||||
}
|
||||
checkVisibility(classSymbol.fir, classSymbol, sink, candidate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 'local' isn't taken into account here
|
||||
private fun ClassId.isSame(other: ClassId): Boolean =
|
||||
packageFqName == other.packageFqName && relativeClassName == other.relativeClassName
|
||||
|
||||
private fun canSeePrivateMemberOf(
|
||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||
ownerId: ClassId,
|
||||
@@ -364,6 +376,10 @@ internal object CheckVisibility : CheckerStage() {
|
||||
return false
|
||||
}
|
||||
|
||||
// 'local' isn't taken into account here
|
||||
private fun ClassId.isSame(other: ClassId): Boolean =
|
||||
packageFqName == other.packageFqName && relativeClassName == other.relativeClassName
|
||||
|
||||
private fun ClassId.ownerIfCompanion(session: FirSession): ClassId? {
|
||||
if (outerClassId == null || isLocal) return null
|
||||
val ownerSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(this) as? FirRegularClassSymbol
|
||||
@@ -371,14 +387,6 @@ internal object CheckVisibility : CheckerStage() {
|
||||
return outerClassId.takeIf { ownerSymbol?.fir?.isCompanion == true }
|
||||
}
|
||||
|
||||
private fun FirClass<*>.isSubClass(ownerId: ClassId, session: FirSession): Boolean {
|
||||
if (classId.isSame(ownerId)) return true
|
||||
|
||||
return lookupSuperTypes(this, lookupInterfaces = true, deep = true, session).any { superType ->
|
||||
(superType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag?.classId?.isSame(ownerId) == true
|
||||
}
|
||||
}
|
||||
|
||||
private fun canSeeProtectedMemberOf(
|
||||
containingUseSiteClass: FirClass<*>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
@@ -392,46 +400,17 @@ internal object CheckVisibility : CheckerStage() {
|
||||
return containingUseSiteClass.isSubClass(ownerId, session)
|
||||
}
|
||||
|
||||
private fun canSeeProtectedMemberOf(
|
||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
ownerId: ClassId, session: FirSession
|
||||
): Boolean {
|
||||
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerId, session)) return true
|
||||
private fun FirClass<*>.isSubClass(ownerId: ClassId, session: FirSession): Boolean {
|
||||
if (classId.isSame(ownerId)) return true
|
||||
|
||||
for (containingDeclaration in containingDeclarationOfUseSite) {
|
||||
if (containingDeclaration !is FirClass<*>) continue
|
||||
val boundSymbol = containingDeclaration.symbol
|
||||
if (canSeeProtectedMemberOf(boundSymbol.fir, dispatchReceiver, ownerId, session)) return true
|
||||
return lookupSuperTypes(this, lookupInterfaces = true, deep = true, session).any { superType ->
|
||||
(superType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag?.classId?.isSame(ownerId) == true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun ReceiverValue?.ownerIfCompanion(session: FirSession): ClassId? =
|
||||
(this?.type as? ConeClassLikeType)?.lookupTag?.classId?.ownerIfCompanion(session)
|
||||
|
||||
private fun AbstractFirBasedSymbol<*>.getOwnerId(): ClassId? {
|
||||
return when (this) {
|
||||
is FirClassLikeSymbol<*> -> {
|
||||
val ownerId = classId.outerClassId
|
||||
if (classId.isLocal) {
|
||||
ownerId?.asLocal() ?: classId
|
||||
} else {
|
||||
ownerId
|
||||
}
|
||||
}
|
||||
is FirCallableSymbol<*> -> {
|
||||
callableId.classId
|
||||
}
|
||||
else -> {
|
||||
throw AssertionError("Unsupported owner search for ${fir.javaClass}: ${fir.render()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassId.asLocal(): ClassId = ClassId(packageFqName, relativeClassName, true)
|
||||
|
||||
private suspend fun checkVisibility(
|
||||
declaration: FirMemberDeclaration,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
@@ -489,26 +468,44 @@ internal object CheckVisibility : CheckerStage() {
|
||||
return true
|
||||
}
|
||||
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val symbol = candidate.symbol
|
||||
val declaration = symbol.fir
|
||||
if (declaration is FirMemberDeclaration) {
|
||||
if (!checkVisibility(declaration, symbol, sink, candidate)) {
|
||||
return
|
||||
private fun AbstractFirBasedSymbol<*>.getOwnerId(): ClassId? {
|
||||
return when (this) {
|
||||
is FirClassLikeSymbol<*> -> {
|
||||
val ownerId = classId.outerClassId
|
||||
if (classId.isLocal) {
|
||||
ownerId?.asLocal() ?: classId
|
||||
} else {
|
||||
ownerId
|
||||
}
|
||||
}
|
||||
is FirCallableSymbol<*> -> callableId.classId
|
||||
else -> error("Unsupported owner search for ${fir.javaClass}: ${fir.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassId.asLocal(): ClassId = ClassId(packageFqName, relativeClassName, true)
|
||||
|
||||
private fun canSeeProtectedMemberOf(
|
||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
ownerId: ClassId, session: FirSession
|
||||
): Boolean {
|
||||
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerId, session)) return true
|
||||
|
||||
for (containingDeclaration in containingDeclarationOfUseSite) {
|
||||
if (containingDeclaration !is FirClass<*>) continue
|
||||
val boundSymbol = containingDeclaration.symbol
|
||||
if (canSeeProtectedMemberOf(boundSymbol.fir, dispatchReceiver, ownerId, session)) return true
|
||||
}
|
||||
|
||||
if (declaration is FirConstructor) {
|
||||
val ownerClassId = declaration.symbol.callableId.classId!!
|
||||
val provider = declaration.session.firSymbolProvider
|
||||
val classSymbol = provider.getClassLikeSymbolByFqName(ownerClassId)
|
||||
return false
|
||||
}
|
||||
|
||||
if (classSymbol is FirRegularClassSymbol) {
|
||||
if (classSymbol.fir.classKind.isSingleton) {
|
||||
sink.yieldApplicability(CandidateApplicability.HIDDEN)
|
||||
}
|
||||
checkVisibility(classSymbol.fir, classSymbol, sink, candidate)
|
||||
}
|
||||
private fun AbstractFirBasedSymbol<*>.packageFqName(): FqName {
|
||||
return when (this) {
|
||||
is FirClassLikeSymbol<*> -> classId.packageFqName
|
||||
is FirCallableSymbol<*> -> callableId.packageName
|
||||
else -> error("No package fq name for $this")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,8 +520,9 @@ internal object CheckLowPriorityInOverloadResolution : CheckerStage() {
|
||||
is FirProperty -> fir.annotations
|
||||
else -> return
|
||||
}
|
||||
|
||||
val hasLowPriorityAnnotation = annotations.any {
|
||||
val lookupTag = ((it.annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeClassLikeType)?.lookupTag ?: return@any false
|
||||
val lookupTag = it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag ?: return@any false
|
||||
lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,44 @@ class FirSyntheticPropertiesScope(
|
||||
private val baseScope: FirTypeScope
|
||||
) : FirScope() {
|
||||
|
||||
companion object {
|
||||
private const val GETTER_PREFIX = "get"
|
||||
private const val IS_PREFIX = "is"
|
||||
|
||||
fun possibleGetterNamesByPropertyName(name: Name): List<Name> {
|
||||
if (name.isSpecial) return emptyList()
|
||||
val identifier = name.identifier
|
||||
val capitalizedAsciiName = identifier.capitalizeAsciiOnly()
|
||||
val capitalizedFirstWordName = identifier.capitalizeFirstWord(asciiOnly = true)
|
||||
return listOfNotNull(
|
||||
Name.identifier(GETTER_PREFIX + capitalizedAsciiName),
|
||||
if (capitalizedFirstWordName == capitalizedAsciiName) null else Name.identifier(GETTER_PREFIX + capitalizedFirstWordName),
|
||||
name.takeIf { identifier.startsWith(IS_PREFIX) }
|
||||
).filter {
|
||||
propertyNameByGetMethodName(it) == name
|
||||
}
|
||||
}
|
||||
|
||||
fun setterNameByGetterName(name: Name): Name {
|
||||
val identifier = name.identifier
|
||||
val prefix = when {
|
||||
identifier.startsWith("get") -> "get"
|
||||
identifier.startsWith("is") -> "is"
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
return Name.identifier("set" + identifier.removePrefix(prefix))
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
val getterNames = possibleGetterNamesByPropertyName(name)
|
||||
for (getterName in getterNames) {
|
||||
baseScope.processFunctionsByName(getterName) {
|
||||
checkGetAndCreateSynthetic(name, getterName, it, processor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkGetAndCreateSynthetic(
|
||||
propertyName: Name,
|
||||
getterName: Name,
|
||||
@@ -95,43 +133,4 @@ class FirSyntheticPropertiesScope(
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
val getterNames = possibleGetterNamesByPropertyName(name)
|
||||
for (getterName in getterNames) {
|
||||
baseScope.processFunctionsByName(getterName) {
|
||||
checkGetAndCreateSynthetic(name, getterName, it, processor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun possibleGetterNamesByPropertyName(name: Name): List<Name> {
|
||||
if (name.isSpecial) return emptyList()
|
||||
val identifier = name.identifier
|
||||
val capitalizedAsciiName = identifier.capitalizeAsciiOnly()
|
||||
val capitalizedFirstWordName = identifier.capitalizeFirstWord(asciiOnly = true)
|
||||
return listOfNotNull(
|
||||
Name.identifier(GETTER_PREFIX + capitalizedAsciiName),
|
||||
if (capitalizedFirstWordName == capitalizedAsciiName) null else Name.identifier(GETTER_PREFIX + capitalizedFirstWordName),
|
||||
name.takeIf { identifier.startsWith(IS_PREFIX) }
|
||||
).filter {
|
||||
propertyNameByGetMethodName(it) == name
|
||||
}
|
||||
}
|
||||
|
||||
fun setterNameByGetterName(name: Name): Name {
|
||||
val identifier = name.identifier
|
||||
val prefix = when {
|
||||
identifier.startsWith("get") -> "get"
|
||||
identifier.startsWith("is") -> "is"
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
return Name.identifier("set" + identifier.removePrefix(prefix))
|
||||
}
|
||||
|
||||
private const val GETTER_PREFIX = "get"
|
||||
|
||||
private const val IS_PREFIX = "is"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-5
@@ -6,12 +6,10 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
|
||||
|
||||
sealed class TypeArgumentMapping {
|
||||
|
||||
abstract operator fun get(typeParameterIndex: Int): FirTypeProjection
|
||||
|
||||
object NoExplicitArguments : TypeArgumentMapping() {
|
||||
@@ -25,7 +23,6 @@ sealed class TypeArgumentMapping {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal object MapTypeArguments : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val typeArguments = callInfo.typeArguments
|
||||
@@ -47,10 +44,9 @@ internal object MapTypeArguments : ResolutionStage() {
|
||||
|
||||
internal object NoTypeArguments : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
|
||||
if (callInfo.typeArguments.isNotEmpty()) {
|
||||
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE)
|
||||
}
|
||||
candidate.typeArgumentMapping = TypeArgumentMapping.NoExplicitArguments
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ sealed class TowerGroupKind(private val index: Int) : Comparable<TowerGroupKind>
|
||||
return 0
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
companion object {
|
||||
// These two groups intentionally have the same priority
|
||||
fun Implicit(depth: Int): TowerGroupKind = ImplicitOrNonLocal(depth, "Implicit")
|
||||
|
||||
Reference in New Issue
Block a user