FIR: Refactor JvmMappedScope to fix container-related tests with new builtins
This commit is contained in:
committed by
TeamCityServer
parent
80a710a5c5
commit
5b677c068f
@@ -10,15 +10,14 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.wrapSubstitutionScopeIfNeed
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||
import org.jetbrains.kotlin.fir.scopes.jvm.JvmMappedScope
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
|
||||
|
||||
fun wrapScopeWithJvmMapped(
|
||||
@@ -50,10 +49,7 @@ fun wrapScopeWithJvmMapped(
|
||||
} else {
|
||||
// We should substitute Java type parameters with base Kotlin type parameters to match overrides properly
|
||||
// It's necessary for MutableMap, which has *two* JavaMappedScope inside (one for itself and another for base Map)
|
||||
(klass.symbol.constructType(
|
||||
klass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
|
||||
false
|
||||
) as ConeClassLikeType).wrapSubstitutionScopeIfNeed(
|
||||
wrapSubstitutionScopeIfNeed(
|
||||
useSiteSession, jvmMappedScope, klass, scopeSession,
|
||||
derivedClass = klass,
|
||||
)
|
||||
@@ -63,3 +59,30 @@ fun wrapScopeWithJvmMapped(
|
||||
declaredMemberScope
|
||||
}
|
||||
}
|
||||
|
||||
private fun wrapSubstitutionScopeIfNeed(
|
||||
session: FirSession,
|
||||
useSiteMemberScope: FirTypeScope,
|
||||
declaration: FirClass,
|
||||
builder: ScopeSession,
|
||||
derivedClass: FirRegularClass
|
||||
): FirTypeScope {
|
||||
if (declaration.typeParameters.isEmpty()) return useSiteMemberScope
|
||||
return builder.getOrBuild(declaration.symbol, PLATFORM_TYPE_PARAMETERS_SUBSTITUTION_SCOPE_KEY) {
|
||||
val platformClass = session.platformClassMapper.getCorrespondingPlatformClass(declaration) ?: return@getOrBuild useSiteMemberScope
|
||||
// This kind of substitution is necessary when method which is mapped from Java (e.g. Java Map.forEach)
|
||||
// is called on an external type, like MyMap<String, String>,
|
||||
// to determine parameter types properly (e.g. String, String instead of K, V)
|
||||
val platformTypeParameters = platformClass.typeParameters
|
||||
val platformSubstitution = createSubstitution(platformTypeParameters, declaration.defaultType(), session)
|
||||
val substitutor = substitutorByMap(platformSubstitution, session)
|
||||
FirClassSubstitutionScope(
|
||||
session, useSiteMemberScope, substitutor,
|
||||
dispatchReceiverTypeForSubstitutedMembers = derivedClass.defaultType(),
|
||||
skipPrivateMembers = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val PLATFORM_TYPE_PARAMETERS_SUBSTITUTION_SCOPE_KEY = scopeSessionKey<FirClassSymbol<*>, FirTypeScope>()
|
||||
|
||||
|
||||
@@ -11,16 +11,13 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.createSubstitutionForSupertype
|
||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
@@ -109,12 +106,6 @@ inline fun <reified ID : Any, reified FS : FirScope> scopeSessionKey(): ScopeSes
|
||||
|
||||
val USE_SITE = scopeSessionKey<FirClassSymbol<*>, FirTypeScope>()
|
||||
|
||||
data class SubstitutionScopeKey(
|
||||
val type: ConeClassLikeType,
|
||||
// This property is necessary. Otherwise we may have accidental matching when two classes have the same supertype
|
||||
val derivedClassId: ClassId
|
||||
) : ScopeSessionKey<FirClassLikeSymbol<*>, FirClassSubstitutionScope>()
|
||||
|
||||
/* TODO REMOVE */
|
||||
fun createSubstitution(
|
||||
typeParameters: List<FirTypeParameterRef>, // TODO: or really declared?
|
||||
@@ -139,36 +130,6 @@ fun createSubstitution(
|
||||
}.toMap()
|
||||
}
|
||||
|
||||
fun ConeClassLikeType.wrapSubstitutionScopeIfNeed(
|
||||
session: FirSession,
|
||||
useSiteMemberScope: FirTypeScope,
|
||||
declaration: FirClassLikeDeclaration,
|
||||
builder: ScopeSession,
|
||||
derivedClass: FirRegularClass
|
||||
): FirTypeScope {
|
||||
if (this.typeArguments.isEmpty()) return useSiteMemberScope
|
||||
return builder.getOrBuild(declaration.symbol, SubstitutionScopeKey(this, derivedClass.symbol.classId)) {
|
||||
val typeParameters = (declaration as? FirTypeParameterRefsOwner)?.typeParameters.orEmpty()
|
||||
val originalSubstitution = createSubstitution(typeParameters, this, session)
|
||||
val platformClass = session.platformClassMapper.getCorrespondingPlatformClass(declaration)
|
||||
val substitutor = if (platformClass != null) {
|
||||
// This kind of substitution is necessary when method which is mapped from Java (e.g. Java Map.forEach)
|
||||
// is called on an external type, like MyMap<String, String>,
|
||||
// to determine parameter types properly (e.g. String, String instead of K, V)
|
||||
val platformTypeParameters = platformClass.typeParameters
|
||||
val platformSubstitution = createSubstitution(platformTypeParameters, this, session)
|
||||
substitutorByMap(originalSubstitution + platformSubstitution, session)
|
||||
} else {
|
||||
substitutorByMap(originalSubstitution, session)
|
||||
}
|
||||
FirClassSubstitutionScope(
|
||||
session, useSiteMemberScope, substitutor,
|
||||
dispatchReceiverTypeForSubstitutedMembers = derivedClass.defaultType(),
|
||||
skipPrivateMembers = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.computePartialExpansion(
|
||||
useSiteSession: FirSession,
|
||||
supertypeSupplier: SupertypeSupplier
|
||||
|
||||
Reference in New Issue
Block a user