[FIR] Cleanup FIR modules. Part 1 (calls package)

This commit is contained in:
Dmitriy Novozhilov
2020-06-29 10:39:58 +03:00
parent 1ac0e8449b
commit 604c68b3a0
12 changed files with 155 additions and 190 deletions
@@ -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 -> {}
}
}
@@ -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,
@@ -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,
@@ -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
@@ -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()
@@ -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"
}
}
@@ -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")