FIR: make substitution wrapper for class-based type scope
This commit is contained in:
@@ -11,8 +11,11 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
|||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
|
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
@@ -26,7 +29,7 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
|
|||||||
// For ConeClassLikeType they might be a type alias instead of a regular class
|
// For ConeClassLikeType they might be a type alias instead of a regular class
|
||||||
// TODO: support that case and switch back to `firUnsafe` instead of `firSafeNullable`
|
// TODO: support that case and switch back to `firUnsafe` instead of `firSafeNullable`
|
||||||
val fir = this.lookupTag.toSymbol(useSiteSession)?.firSafeNullable<FirRegularClass>() ?: return null
|
val fir = this.lookupTag.toSymbol(useSiteSession)?.firSafeNullable<FirRegularClass>() ?: return null
|
||||||
fir.buildUseSiteScope(useSiteSession, scopeSession)
|
wrapSubstitutionScopeIfNeed(useSiteSession, fir.buildUseSiteScope(useSiteSession, scopeSession), scopeSession)
|
||||||
}
|
}
|
||||||
is ConeTypeParameterType -> {
|
is ConeTypeParameterType -> {
|
||||||
// TODO: support LibraryTypeParameterSymbol or get rid of it
|
// TODO: support LibraryTypeParameterSymbol or get rid of it
|
||||||
@@ -39,8 +42,23 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ConeClassLikeType.wrapSubstitutionScopeIfNeed(
|
||||||
|
session: FirSession,
|
||||||
|
useSiteScope: FirScope,
|
||||||
|
builder: ScopeSession
|
||||||
|
): FirScope {
|
||||||
|
if (this.typeArguments.isEmpty()) return useSiteScope
|
||||||
|
val symbol = this.lookupTag.toSymbol(session) as? FirClassSymbol ?: return useSiteScope
|
||||||
|
val regularClass = symbol.fir
|
||||||
|
return builder.getOrBuild(symbol, SubstitutionScopeKey(this)) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val substitution = regularClass.typeParameters.zip(this.typeArguments) { typeParameter, typeArgument ->
|
||||||
|
typeParameter.symbol to (typeArgument as? ConeTypedProjection)?.type
|
||||||
|
}.filter { (_, type) -> type != null }.toMap() as Map<ConeTypeParameterSymbol, ConeKotlinType>
|
||||||
|
|
||||||
|
FirClassSubstitutionScope(session, useSiteScope, substitution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun FirRegularClass.defaultType(): ConeClassTypeImpl {
|
fun FirRegularClass.defaultType(): ConeClassTypeImpl {
|
||||||
return ConeClassTypeImpl(
|
return ConeClassTypeImpl(
|
||||||
|
|||||||
Reference in New Issue
Block a user