FIR: create new ConeTypeCheckerContext on every supertypes calculation

It can be recursively used while calculating supertypes via IDE lazy resolve,
which is forbidden
This commit is contained in:
Ilya Kirillov
2021-01-12 17:57:30 +01:00
parent 1c80c5610d
commit 1b68f35f7c
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker
@ThreadSafeMutableState @ThreadSafeMutableState
class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSessionComponent { class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSessionComponent {
private val context = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session = session)
private val cache = HashMap<ConeClassLikeLookupTag, Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>?>(1000, 0.5f) private val cache = HashMap<ConeClassLikeLookupTag, Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>?>(1000, 0.5f)
fun getCorrespondingSupertypes( fun getCorrespondingSupertypes(
@@ -29,27 +28,30 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
): List<ConeClassLikeType>? { ): List<ConeClassLikeType>? {
if (type !is ConeClassLikeType || supertypeConstructor !is ConeClassLikeLookupTag) return null if (type !is ConeClassLikeType || supertypeConstructor !is ConeClassLikeLookupTag) return null
val context = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session = session)
val lookupTag = type.lookupTag val lookupTag = type.lookupTag
if (lookupTag == supertypeConstructor) return listOf(captureType(type)) if (lookupTag == supertypeConstructor) return listOf(captureType(type, context))
if (lookupTag !in cache) { if (lookupTag !in cache) {
cache[lookupTag] = computeSupertypesMap(lookupTag) cache[lookupTag] = computeSupertypesMap(lookupTag, context)
} }
val resultTypes = cache[lookupTag]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null val resultTypes = cache[lookupTag]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null
if (type.typeArguments.isEmpty()) return resultTypes if (type.typeArguments.isEmpty()) return resultTypes
val capturedType = captureType(type) val capturedType = captureType(type, context)
val substitutionSupertypePolicy = context.substitutionSupertypePolicy(capturedType) val substitutionSupertypePolicy = context.substitutionSupertypePolicy(capturedType)
return resultTypes.map { return resultTypes.map {
substitutionSupertypePolicy.transformType(context, it) as ConeClassLikeType substitutionSupertypePolicy.transformType(context, it) as ConeClassLikeType
} }
} }
private fun captureType(type: ConeClassLikeType): ConeClassLikeType = private fun captureType(type: ConeClassLikeType, context: ConeTypeCheckerContext): ConeClassLikeType =
(context.captureFromArguments(type, CaptureStatus.FOR_SUBTYPING) ?: type) as ConeClassLikeType (context.captureFromArguments(type, CaptureStatus.FOR_SUBTYPING) ?: type) as ConeClassLikeType
private fun computeSupertypesMap(subtypeLookupTag: ConeClassLikeLookupTag): Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>? { private fun computeSupertypesMap(
subtypeLookupTag: ConeClassLikeLookupTag,
context: ConeTypeCheckerContext
): Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>? {
val resultingMap = HashMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>() val resultingMap = HashMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>()
val subtypeFirClass: FirClassLikeDeclaration<*> = subtypeLookupTag.toSymbol(session)?.fir ?: return null val subtypeFirClass: FirClassLikeDeclaration<*> = subtypeLookupTag.toSymbol(session)?.fir ?: return null
@@ -64,7 +66,7 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
if (context.anySupertype( if (context.anySupertype(
defaultType, defaultType,
{ it !is ConeClassLikeType || it.lookupTag.toSymbol(session) !is FirClassLikeSymbol<*> } { it !is ConeClassLikeType || it.lookupTag.toSymbol(session) !is FirClassLikeSymbol<*> }
) { supertype -> computeSupertypePolicyAndPutInMap(supertype, resultingMap) } ) { supertype -> computeSupertypePolicyAndPutInMap(supertype, resultingMap, context) }
) { ) {
return null return null
} }
@@ -76,7 +78,8 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
private fun computeSupertypePolicyAndPutInMap( private fun computeSupertypePolicyAndPutInMap(
supertype: SimpleTypeMarker, supertype: SimpleTypeMarker,
resultingMap: MutableMap<ConeClassLikeLookupTag, List<ConeClassLikeType>> resultingMap: MutableMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>,
context: ConeTypeCheckerContext
): AbstractTypeCheckerContext.SupertypesPolicy { ): AbstractTypeCheckerContext.SupertypesPolicy {
val supertypeLookupTag = (supertype as ConeClassLikeType).lookupTag val supertypeLookupTag = (supertype as ConeClassLikeType).lookupTag
val captured = context.captureFromArguments(supertype, CaptureStatus.FOR_SUBTYPING) as ConeClassLikeType? ?: supertype val captured = context.captureFromArguments(supertype, CaptureStatus.FOR_SUBTYPING) as ConeClassLikeType? ?: supertype