FIR: make substitution wrapper for class-based type scope

This commit is contained in:
Mikhail Glukhikh
2019-04-16 17:20:57 +03:00
parent 93496f1dee
commit f47258c6b1
@@ -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.firUnsafe
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.symbols.ConeTypeParameterSymbol
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.impl.ConeClassTypeImpl
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
// TODO: support that case and switch back to `firUnsafe` instead of `firSafeNullable`
val fir = this.lookupTag.toSymbol(useSiteSession)?.firSafeNullable<FirRegularClass>() ?: return null
fir.buildUseSiteScope(useSiteSession, scopeSession)
wrapSubstitutionScopeIfNeed(useSiteSession, fir.buildUseSiteScope(useSiteSession, scopeSession), scopeSession)
}
is ConeTypeParameterType -> {
// 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 {
return ConeClassTypeImpl(