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.FirClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.wrapSubstitutionScopeIfNeed
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
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.jvm.JvmMappedScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
|
||||||
|
|
||||||
|
|
||||||
fun wrapScopeWithJvmMapped(
|
fun wrapScopeWithJvmMapped(
|
||||||
@@ -50,10 +49,7 @@ fun wrapScopeWithJvmMapped(
|
|||||||
} else {
|
} else {
|
||||||
// We should substitute Java type parameters with base Kotlin type parameters to match overrides properly
|
// 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)
|
// It's necessary for MutableMap, which has *two* JavaMappedScope inside (one for itself and another for base Map)
|
||||||
(klass.symbol.constructType(
|
wrapSubstitutionScopeIfNeed(
|
||||||
klass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
|
|
||||||
false
|
|
||||||
) as ConeClassLikeType).wrapSubstitutionScopeIfNeed(
|
|
||||||
useSiteSession, jvmMappedScope, klass, scopeSession,
|
useSiteSession, jvmMappedScope, klass, scopeSession,
|
||||||
derivedClass = klass,
|
derivedClass = klass,
|
||||||
)
|
)
|
||||||
@@ -63,3 +59,30 @@ fun wrapScopeWithJvmMapped(
|
|||||||
declaredMemberScope
|
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.expandedConeType
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
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.resolve.transformers.createSubstitutionForSupertype
|
||||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
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.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import org.jetbrains.kotlin.utils.SmartSet
|
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>()
|
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 */
|
/* TODO REMOVE */
|
||||||
fun createSubstitution(
|
fun createSubstitution(
|
||||||
typeParameters: List<FirTypeParameterRef>, // TODO: or really declared?
|
typeParameters: List<FirTypeParameterRef>, // TODO: or really declared?
|
||||||
@@ -139,36 +130,6 @@ fun createSubstitution(
|
|||||||
}.toMap()
|
}.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(
|
private fun ConeClassLikeType.computePartialExpansion(
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
supertypeSupplier: SupertypeSupplier
|
supertypeSupplier: SupertypeSupplier
|
||||||
|
|||||||
Reference in New Issue
Block a user