FIR: Support special scope for raw types
^KT-46369 Fixed ^KT-41794 Fixed ^KT-49351 Fixed
This commit is contained in:
committed by
Space Team
parent
1215ae0fe7
commit
5cc31114cd
@@ -9,16 +9,17 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeRawScopeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.scopes.scopeForClass
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
@@ -61,10 +62,17 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
|
||||
|
||||
fir.symbol.lazyResolveToPhase(requiredPhase)
|
||||
|
||||
val substitution = createSubstitution(fir.typeParameters, fullyExpandedType, useSiteSession)
|
||||
val substitutor = when {
|
||||
attributes.contains(CompilerConeAttributes.RawType) -> ConeRawScopeSubstitutor(useSiteSession)
|
||||
else -> substitutorByMap(
|
||||
createSubstitution(fir.typeParameters, fullyExpandedType, useSiteSession),
|
||||
useSiteSession,
|
||||
)
|
||||
}
|
||||
|
||||
fir.scopeForClass(substitutorByMap(substitution, useSiteSession), useSiteSession, scopeSession)
|
||||
fir.scopeForClass(substitutor, useSiteSession, scopeSession)
|
||||
}
|
||||
|
||||
is ConeTypeParameterType -> {
|
||||
val symbol = lookupTag.symbol
|
||||
scopeSession.getOrBuild(symbol, TYPE_PARAMETER_SCOPE_KEY) {
|
||||
@@ -75,6 +83,7 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
|
||||
intersectionType.scope(useSiteSession, scopeSession, requiredPhase) ?: FirTypeScope.Empty
|
||||
}
|
||||
}
|
||||
|
||||
is ConeRawType -> lowerBound.scope(useSiteSession, scopeSession, requiredPhase)
|
||||
is ConeDynamicType -> useSiteSession.dynamicMembersStorage.getDynamicScopeFor(scopeSession)
|
||||
is ConeFlexibleType -> lowerBound.scope(useSiteSession, scopeSession, requiredPhase)
|
||||
@@ -86,6 +95,7 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
|
||||
},
|
||||
this
|
||||
)
|
||||
|
||||
is ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession, requiredPhase)
|
||||
is ConeIntegerConstantOperatorType -> scopeSession.getOrBuildScopeForIntegerConstantOperatorType(useSiteSession, this)
|
||||
is ConeIntegerLiteralConstantType -> error("ILT should not be in receiver position")
|
||||
@@ -93,6 +103,13 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.obtainFirOfClass(useSiteSession: FirSession, requiredPhase: FirResolvePhase): FirClass? {
|
||||
val fullyExpandedType = fullyExpandedType(useSiteSession)
|
||||
val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass ?: return null
|
||||
|
||||
return fir.also { it.symbol.lazyResolveToPhase(requiredPhase) }
|
||||
}
|
||||
|
||||
fun FirClassSymbol<*>.defaultType(): ConeClassLikeType = fir.defaultType()
|
||||
|
||||
fun FirClass.defaultType(): ConeClassLikeType =
|
||||
|
||||
+53
@@ -6,11 +6,14 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.substitution
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.withCombinedAttributesFrom
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
@@ -221,6 +224,56 @@ class ConeSubstitutorByMap(
|
||||
override fun hashCode() = hashCode
|
||||
}
|
||||
|
||||
class ConeRawScopeSubstitutor(
|
||||
private val useSiteSession: FirSession,
|
||||
) : AbstractConeSubstitutor(useSiteSession.typeContext) {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
return when {
|
||||
type is ConeTypeParameterType -> {
|
||||
substituteOrSelf(
|
||||
listOf(type.lookupTag.symbol).eraseToUpperBounds(useSiteSession)[0] as ConeKotlinType
|
||||
)
|
||||
}
|
||||
type is ConeClassLikeType && type.typeArguments.isNotEmpty() -> {
|
||||
if (type.lookupTag.classId == StandardClassIds.Array) {
|
||||
val argument = type.typeArguments[0]
|
||||
val erasedType = argument.type?.let(this::substituteOrSelf)
|
||||
|
||||
return type.withArguments(
|
||||
arrayOf(erasedType?.toTypeProjection(argument.kind) ?: ConeStarProjection)
|
||||
)
|
||||
}
|
||||
|
||||
val firClass = type.fullyExpandedType(useSiteSession).lookupTag.toFirRegularClassSymbol(useSiteSession) ?: return null
|
||||
ConeRawType.create(
|
||||
type.withArguments(firClass.typeParameterSymbols.eraseToUpperBounds(useSiteSession)),
|
||||
type.replaceArgumentsWithStarProjections()
|
||||
)
|
||||
}
|
||||
type is ConeFlexibleType -> {
|
||||
val substitutedLowerBound = substituteOrNull(type.lowerBound)
|
||||
val substitutedUpperBound = substituteOrNull(type.upperBound)
|
||||
if (substitutedLowerBound == null && substitutedUpperBound == null) return null
|
||||
|
||||
val newLowerBound = substitutedLowerBound?.lowerBoundIfFlexible() ?: type.lowerBound
|
||||
val newUpperBound = substitutedUpperBound?.upperBoundIfFlexible() ?: type.upperBound
|
||||
|
||||
if (substitutedLowerBound is ConeRawType || substitutedUpperBound is ConeRawType) {
|
||||
return ConeRawType.create(newLowerBound, newUpperBound)
|
||||
}
|
||||
|
||||
ConeFlexibleType(newLowerBound, newUpperBound)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) = other is ConeRawScopeSubstitutor
|
||||
|
||||
override fun hashCode(): Int = 0
|
||||
}
|
||||
|
||||
fun createTypeSubstitutorByTypeConstructor(
|
||||
map: Map<TypeConstructorMarker, ConeKotlinType>,
|
||||
context: ConeTypeContext,
|
||||
|
||||
+18
-17
@@ -10,19 +10,17 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
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.declarations.utils.delegateFields
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeRawScopeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
|
||||
class FirKotlinScopeProvider(
|
||||
val declaredMemberScopeDecorator: (
|
||||
@@ -125,19 +123,22 @@ fun ConeKotlinType.scopeForSupertype(
|
||||
): FirTypeScope? {
|
||||
if (this !is ConeClassLikeType) return null
|
||||
if (this is ConeErrorType) return null
|
||||
val symbol = lookupTag.toSymbol(useSiteSession)
|
||||
return if (symbol is FirRegularClassSymbol) {
|
||||
symbol.fir.scopeForClassImpl(
|
||||
substitutor(symbol, this, useSiteSession),
|
||||
useSiteSession,
|
||||
scopeSession,
|
||||
skipPrivateMembers = true,
|
||||
classFirDispatchReceiver = subClass,
|
||||
isFromExpectClass = (subClass as? FirRegularClass)?.isExpect == true
|
||||
)
|
||||
} else {
|
||||
null
|
||||
|
||||
val symbol = lookupTag.toSymbol(useSiteSession) as? FirRegularClassSymbol ?: return null
|
||||
|
||||
val substitutor = when {
|
||||
this.type.attributes.contains(CompilerConeAttributes.RawType) -> ConeRawScopeSubstitutor(useSiteSession)
|
||||
else -> substitutor(symbol, this, useSiteSession)
|
||||
}
|
||||
|
||||
return symbol.fir.scopeForClassImpl(
|
||||
substitutor,
|
||||
useSiteSession,
|
||||
scopeSession,
|
||||
skipPrivateMembers = true,
|
||||
classFirDispatchReceiver = subClass,
|
||||
isFromExpectClass = (subClass as? FirRegularClass)?.isExpect == true
|
||||
)
|
||||
}
|
||||
|
||||
private fun substitutor(symbol: FirRegularClassSymbol, type: ConeClassLikeType, useSiteSession: FirSession): ConeSubstitutor {
|
||||
@@ -165,7 +166,7 @@ private fun FirClass.scopeForClassImpl(
|
||||
useSiteSession,
|
||||
basicScope,
|
||||
key, substitutor,
|
||||
substitutor.substituteOrSelf(classFirDispatchReceiver.defaultType()) as ConeClassLikeType,
|
||||
substitutor.substituteOrSelf(classFirDispatchReceiver.defaultType()).lowerBoundIfFlexible() as ConeClassLikeType,
|
||||
skipPrivateMembers,
|
||||
makeExpect = isFromExpectClass
|
||||
)
|
||||
|
||||
+4
-3
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
@@ -118,7 +118,7 @@ class FirClassSubstitutionScope(
|
||||
}
|
||||
|
||||
private fun ConeSimpleKotlinType.substitute(substitutor: ConeSubstitutor): ConeSimpleKotlinType? {
|
||||
return substitutor.substituteOrNull(this) as ConeSimpleKotlinType?
|
||||
return substitutor.substituteOrNull(this)?.lowerBoundIfFlexible()
|
||||
}
|
||||
|
||||
fun createSubstitutionOverrideFunction(original: FirNamedFunctionSymbol): FirNamedFunctionSymbol {
|
||||
@@ -212,7 +212,8 @@ class FirClassSubstitutionScope(
|
||||
constructor,
|
||||
FirDeclarationOrigin.SubstitutionOverride,
|
||||
newDispatchReceiverType,
|
||||
newReturnType,
|
||||
// Constructors' return types are expected to be non-flexible (i.e., non raw)
|
||||
newReturnType?.lowerBoundIfFlexible(),
|
||||
newParameterTypes,
|
||||
newContextReceiverTypes,
|
||||
newTypeParameters,
|
||||
|
||||
@@ -140,7 +140,7 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
|
||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable, attributes)
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withAttributes(attributes))
|
||||
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable, attributes)
|
||||
is ConeRawType -> ConeRawType(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
|
||||
is ConeRawType -> ConeRawType.create(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
|
||||
is ConeDynamicType -> ConeDynamicType(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
|
||||
is ConeFlexibleType -> ConeFlexibleType(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
|
||||
is ConeTypeVariableType -> ConeTypeVariableType(nullability, lookupTag, attributes)
|
||||
|
||||
Reference in New Issue
Block a user