From 604c68b3a01fcc97c645fbcd68a14719e7f92438 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 29 Jun 2020 10:39:58 +0300 Subject: [PATCH] [FIR] Cleanup FIR modules. Part 1 (`calls` package) --- .../calls/AbstractConeCallConflictResolver.kt | 25 ++- .../kotlin/fir/resolve/calls/Arguments.kt | 1 - .../fir/resolve/calls/CandidateFactory.kt | 13 +- ...CreateFreshTypeVariableSubstitutorStage.kt | 6 +- .../calls/FirArgumentsToParametersMapper.kt | 1 - .../kotlin/fir/resolve/calls/FirReceivers.kt | 39 ++--- .../fir/resolve/calls/QualifierReceiver.kt | 13 +- .../fir/resolve/calls/ResolutionDiagnostic.kt | 3 +- .../fir/resolve/calls/ResolutionStages.kt | 160 +++++++++--------- .../kotlin/fir/resolve/calls/Synthetics.kt | 77 +++++---- .../fir/resolve/calls/TypeArgumentMapping.kt | 6 +- .../fir/resolve/calls/tower/TowerGroup.kt | 1 + 12 files changed, 155 insertions(+), 190 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt index aaaef2706f3..4bc7374623f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt @@ -20,12 +20,6 @@ abstract class AbstractConeCallConflictResolver( private val specificityComparator: TypeSpecificityComparator, protected val inferenceComponents: InferenceComponents ) : ConeCallConflictResolver() { - protected fun Collection.setIfOneOrEmpty(): Set? = 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(variable.receiverTypeRef?.coneTypeUnsafe()), + listOfNotNull(variable.receiverTypeRef?.coneTypeUnsafe()), variable.receiverTypeRef != null, false, 0, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index 354b60add00..3b29b813a77 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -291,7 +291,6 @@ internal fun Candidate.resolveArgument( argument: FirExpression, parameter: FirValueParameter?, isReceiver: Boolean, - isSafeCall: Boolean, sink: CheckerSink ) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt index e541ddd0818..a27f2b2a361 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt @@ -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 -> {} } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt index 404e6d14482..5625d4061b4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt @@ -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, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt index 4a17982c036..316a260271b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt @@ -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) {} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt index 22072333832..45defe91119 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt @@ -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 : Receiver { abstract val explicitReceiver: FirExpression @@ -85,8 +61,7 @@ sealed class ImplicitReceiverValue>( 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>( } } +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, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/QualifierReceiver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/QualifierReceiver.kt index a6a8c7b4220..a9831550213 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/QualifierReceiver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/QualifierReceiver.kt @@ -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() { - 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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt index 87ace7de7b9..aa9c336324b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt @@ -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() \ No newline at end of file +) : InapplicableArgumentDiagnostic() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index d2035e96438..cc731ad131c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -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() 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()) { - 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, 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, - 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, + 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()?.lookupTag ?: return@any false lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt index eb73a895323..66f24316b67 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt @@ -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 { + 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 { - 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" - } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TypeArgumentMapping.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TypeArgumentMapping.kt index 7a25d2eced7..ef66400cfb1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TypeArgumentMapping.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TypeArgumentMapping.kt @@ -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 } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerGroup.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerGroup.kt index 8c59716d40d..8020acc1431 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerGroup.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerGroup.kt @@ -37,6 +37,7 @@ sealed class TowerGroupKind(private val index: Int) : Comparable return 0 } + @Suppress("FunctionName") companion object { // These two groups intentionally have the same priority fun Implicit(depth: Int): TowerGroupKind = ImplicitOrNonLocal(depth, "Implicit")