FIR: Use lookup tags for as type constructors instead of symbols

It may help to avoid redundant symbols lookups
This commit is contained in:
Denis Zharkov
2020-08-20 13:04:06 +03:00
parent 34b55dbeb3
commit 9ac5dd2bce
12 changed files with 116 additions and 109 deletions
@@ -7,8 +7,9 @@ package org.jetbrains.kotlin.fir.symbols
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
abstract class ConeClassifierLookupTag {
abstract class ConeClassifierLookupTag : TypeConstructorMarker {
abstract val name: Name
override fun toString(): String {
@@ -8,7 +8,10 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.arrayElementType
import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.resolve.calls.results.*
import org.jetbrains.kotlin.types.checker.requireOrDescribe
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
@@ -108,7 +111,7 @@ abstract class AbstractConeCallConflictResolver(
protected fun createFlatSignature(call: Candidate, variable: FirVariable<*>): FlatSignature<Candidate> {
return FlatSignature(
call,
(variable as? FirProperty)?.typeParameters?.map { it.symbol }.orEmpty(),
(variable as? FirProperty)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(),
listOfNotNull(variable.receiverTypeRef?.coneType),
variable.receiverTypeRef != null,
false,
@@ -121,7 +124,7 @@ abstract class AbstractConeCallConflictResolver(
protected fun createFlatSignature(call: Candidate, constructor: FirConstructor): FlatSignature<Candidate> {
return FlatSignature(
call,
constructor.typeParameters.map { it.symbol },
constructor.typeParameters.map { it.symbol.toLookupTag() },
computeParameterTypes(call, constructor),
//constructor.receiverTypeRef != null,
false,
@@ -135,7 +138,7 @@ abstract class AbstractConeCallConflictResolver(
protected fun createFlatSignature(call: Candidate, function: FirSimpleFunction): FlatSignature<Candidate> {
return FlatSignature(
call,
function.typeParameters.map { it.symbol },
function.typeParameters.map { it.symbol.toLookupTag() },
computeParameterTypes(call, function),
function.receiverTypeRef != null,
function.valueParameters.any { it.isVararg },
@@ -163,7 +166,7 @@ abstract class AbstractConeCallConflictResolver(
private fun createFlatSignature(call: Candidate, klass: FirClass<*>): FlatSignature<Candidate> {
return FlatSignature(
call,
(klass as? FirRegularClass)?.typeParameters?.map { it.symbol }.orEmpty(),
(klass as? FirRegularClass)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(),
valueParameterTypes = emptyList(),
hasExtensionReceiver = false,
hasVarargs = false,
@@ -176,4 +179,4 @@ abstract class AbstractConeCallConflictResolver(
private fun createEmptyConstraintSystem(): SimpleConstraintSystem {
return ConeSimpleConstraintSystemImpl(inferenceComponents.createConstraintSystem())
}
}
}
@@ -10,13 +10,11 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.inference.preprocessCallableReference
import org.jetbrains.kotlin.fir.resolve.inference.preprocessLambdaArgument
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.returnExpressions
@@ -24,13 +22,12 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirILTTypeRefPlaceHolder
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.types.model.CaptureStatus
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun Candidate.resolveArgumentExpression(
csBuilder: ConstraintSystemBuilder,
@@ -331,7 +328,7 @@ private fun Candidate.getExpectedTypeWithSAMConversion(
return samResolver.getFunctionTypeForPossibleSamType(candidateExpectedType).apply {
usesSAM = true
} ?: return null
}
}
fun FirExpression.isFunctional(session: FirSession): Boolean =
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.fir.resolve.inference.TypeParameterBasedTypeVariable
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeParameterMarker
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
import org.jetbrains.kotlin.utils.addToStdlib.cast
class ConeOverloadConflictResolver(
specificityComparator: TypeSpecificityComparator,
@@ -179,19 +178,20 @@ object NoSubstitutor : TypeSubstitutorMarker
class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : SimpleConstraintSystem {
override fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutorMarker = with(context) {
val csBuilder = system.getBuilder()
val substitutionMap = typeParameters.associateWith {
require(it is FirTypeParameterSymbol)
val variable = TypeParameterBasedTypeVariable(it)
val substitutionMap = typeParameters.associateBy({ (it as ConeTypeParameterLookupTag).typeParameterSymbol }) {
require(it is ConeTypeParameterLookupTag)
val variable = TypeParameterBasedTypeVariable(it.typeParameterSymbol)
csBuilder.registerVariable(variable)
variable.defaultType
}
val substitutor = substitutorByMap(substitutionMap.cast())
val substitutor = substitutorByMap(substitutionMap)
for (typeParameter in typeParameters) {
require(typeParameter is FirTypeParameterSymbol)
for (upperBound in typeParameter.fir.bounds) {
require(typeParameter is ConeTypeParameterLookupTag)
for (upperBound in typeParameter.symbol.fir.bounds) {
addSubtypeConstraint(
substitutionMap[typeParameter] ?: error("No ${typeParameter.fir.render()} in substitution map"),
substitutionMap[typeParameter.typeParameterSymbol]
?: error("No ${typeParameter.symbol.fir.render()} in substitution map"),
substitutor.substituteOrSelf(upperBound.coneType)
)
}
@@ -11,10 +11,9 @@ import org.jetbrains.kotlin.fir.resolve.calls.NoSubstitutor
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.types.AbstractTypeChecker
@@ -56,16 +55,15 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
nullable: Boolean,
isExtensionFunction: Boolean
): SimpleTypeMarker {
require(constructor is FirClassifierSymbol<*>)
@Suppress("UNCHECKED_CAST")
return when (constructor) {
is FirClassLikeSymbol<*> -> ConeClassLikeTypeImpl(
constructor.toLookupTag(),
is ConeClassLikeLookupTag -> ConeClassLikeTypeImpl(
constructor,
(arguments as List<ConeTypeProjection>).toTypedArray(),
nullable
)
is FirTypeParameterSymbol -> ConeTypeParameterTypeImpl(
constructor.toLookupTag(),
is ConeTypeParameterLookupTag -> ConeTypeParameterTypeImpl(
constructor,
nullable
)
else -> error("!")
@@ -183,7 +181,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
}
override fun TypeConstructorMarker.isUnitTypeConstructor(): Boolean {
return this is FirClassLikeSymbol<*> && this.classId == StandardClassIds.Unit
return this is ConeClassLikeLookupTag && this.classId == StandardClassIds.Unit
}
override fun Collection<KotlinTypeMarker>.singleBestRepresentative(): KotlinTypeMarker? {
@@ -346,10 +344,13 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
}
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
require(this is ErrorTypeConstructor)
return ConeClassErrorType(ConeIntermediateDiagnostic(reason))
if (this is ErrorTypeConstructor) return createErrorType(reason)
if (this is ConeClassLikeLookupTag) return createErrorType("Not found classifier: $classId")
return createErrorType("Unknown reason")
}
private fun createErrorType(reason: String) = ConeClassErrorType(ConeIntermediateDiagnostic(reason))
override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List<SimpleTypeMarker>): SimpleTypeMarker? {
return ConeIntegerLiteralTypeImpl.findCommonSuperType(explicitSupertypes)
}
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.FqName
@@ -68,7 +70,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
override fun KotlinTypeMarker.isError(): Boolean {
assert(this is ConeKotlinType)
return this is ConeClassErrorType || this is ConeKotlinErrorType || this.typeConstructor() is ErrorTypeConstructor
return this is ConeClassErrorType || this is ConeKotlinErrorType || this.typeConstructor().isError()
}
override fun KotlinTypeMarker.isUninferredParameter(): Boolean {
@@ -118,9 +120,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
return when (this) {
is ConeClassLikeType -> lookupTag.toSymbol(session)
?: ErrorTypeConstructor("Unresolved: $lookupTag")
is ConeTypeParameterType -> lookupTag.typeParameterSymbol
is ConeClassLikeType -> lookupTag
is ConeTypeParameterType -> lookupTag
is ConeCapturedType -> constructor
is ConeTypeVariableType -> lookupTag as ConeTypeVariableTypeConstructor // TODO: WTF
is ConeIntersectionType -> this
@@ -195,14 +196,19 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
override fun TypeConstructorMarker.parametersCount(): Int {
//require(this is ConeSymbol)
return when (this) {
is FirTypeParameterSymbol,
is ConeTypeParameterLookupTag,
is ConeCapturedTypeConstructor,
is ErrorTypeConstructor,
is ConeTypeVariableTypeConstructor,
is ConeIntersectionType -> 0
is FirAnonymousObjectSymbol -> fir.typeParameters.size
is FirRegularClassSymbol -> fir.typeParameters.size
is FirTypeAliasSymbol -> fir.typeParameters.size
is ConeClassLikeLookupTag -> {
when(val symbol = toSymbol(session)) {
is FirAnonymousObjectSymbol -> symbol.fir.typeParameters.size
is FirRegularClassSymbol -> symbol.fir.typeParameters.size
is FirTypeAliasSymbol -> symbol.fir.typeParameters.size
else -> 0
}
}
is ConeIntegerLiteralType -> 0
else -> error("?!:10")
}
@@ -210,23 +216,29 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
override fun TypeConstructorMarker.getParameter(index: Int): TypeParameterMarker {
//require(this is ConeSymbol)
return when (this) {
is FirTypeParameterSymbol -> error("?!:11")
is FirAnonymousObjectSymbol -> fir.typeParameters[index].symbol
is FirRegularClassSymbol -> fir.typeParameters[index].symbol
is FirTypeAliasSymbol -> fir.typeParameters[index].symbol
return when (val symbol = toClassLikeSymbol()) {
is FirAnonymousObjectSymbol -> symbol.fir.typeParameters[index].symbol.toLookupTag()
is FirRegularClassSymbol -> symbol.fir.typeParameters[index].symbol.toLookupTag()
is FirTypeAliasSymbol -> symbol.fir.typeParameters[index].symbol.toLookupTag()
else -> error("?!:12")
}
}
private fun TypeConstructorMarker.toClassLikeSymbol(): FirClassLikeSymbol<*>? = (this as? ConeClassLikeLookupTag)?.toSymbol(session)
override fun TypeConstructorMarker.supertypes(): Collection<KotlinTypeMarker> {
if (this is ErrorTypeConstructor) return emptyList()
//require(this is ConeSymbol)
return when (this) {
is ConeTypeVariableTypeConstructor -> emptyList()
is FirTypeParameterSymbol -> fir.bounds.map { it.coneType }
is FirClassSymbol<*> -> fir.superConeTypes
is FirTypeAliasSymbol -> listOfNotNull(fir.expandedConeType)
is ConeTypeParameterLookupTag -> symbol.fir.bounds.map { it.coneType }
is ConeClassLikeLookupTag -> {
when (val symbol = toClassLikeSymbol()) {
is FirClassSymbol<*> -> symbol.fir.superConeTypes
is FirTypeAliasSymbol -> listOfNotNull(symbol.fir.expandedConeType)
else -> emptyList()
}
}
is ConeCapturedTypeConstructor -> supertypes!!
is ConeIntersectionType -> intersectedTypes
is ConeIntegerLiteralType -> supertypes
@@ -240,26 +252,26 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
override fun TypeConstructorMarker.isClassTypeConstructor(): Boolean {
//assert(this is ConeSymbol)
return this is FirClassSymbol<*>
return this is ConeClassLikeLookupTag
}
override fun TypeParameterMarker.getVariance(): TypeVariance {
require(this is FirTypeParameterSymbol)
return this.fir.variance.convertVariance()
require(this is ConeTypeParameterLookupTag)
return this.symbol.fir.variance.convertVariance()
}
override fun TypeParameterMarker.upperBoundCount(): Int {
require(this is FirTypeParameterSymbol)
return this.fir.bounds.size
require(this is ConeTypeParameterLookupTag)
return this.symbol.fir.bounds.size
}
override fun TypeParameterMarker.getUpperBound(index: Int): KotlinTypeMarker {
require(this is FirTypeParameterSymbol)
return this.fir.bounds[index].coneType
require(this is ConeTypeParameterLookupTag)
return this.symbol.fir.bounds[index].coneType
}
override fun TypeParameterMarker.getTypeConstructor(): TypeConstructorMarker {
require(this is FirTypeParameterSymbol)
require(this is ConeTypeParameterLookupTag)
return this
}
@@ -284,8 +296,9 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
}
override fun TypeConstructorMarker.isCommonFinalClassConstructor(): Boolean {
if (this is FirAnonymousObjectSymbol) return true
val classSymbol = this as? FirRegularClassSymbol ?: return false
val symbol = toClassLikeSymbol() ?: return false
if (symbol is FirAnonymousObjectSymbol) return true
val classSymbol = symbol as? FirRegularClassSymbol ?: return false
val fir = classSymbol.fir
return fir.modality == Modality.FINAL &&
fir.classKind != ClassKind.ENUM_ENTRY &&
@@ -350,11 +363,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
}
override fun TypeConstructorMarker.isAnyConstructor(): Boolean {
return this is FirClassLikeSymbol<*> && classId == StandardClassIds.Any
return this is ConeClassLikeLookupTag && classId == StandardClassIds.Any
}
override fun TypeConstructorMarker.isNothingConstructor(): Boolean {
return this is FirClassLikeSymbol<*> && classId == StandardClassIds.Nothing
return this is ConeClassLikeLookupTag && classId == StandardClassIds.Nothing
}
override fun SimpleTypeMarker.isSingleClassifierType(): Boolean {
@@ -367,8 +380,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
if (this is ConeDefinitelyNotNullType) return true
require(this is ConeLookupTagBasedType)
val typeConstructor = this.typeConstructor()
return typeConstructor is FirClassSymbol<*> ||
typeConstructor is FirTypeParameterSymbol
return typeConstructor is ConeClassLikeLookupTag ||
typeConstructor is ConeTypeParameterLookupTag
}
override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? {
@@ -431,8 +444,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
}
private fun TypeConstructorMarker.toFirRegularClass(): FirRegularClass? {
if (this !is FirClassLikeSymbol<*>) return null
return fir as? FirRegularClass
return toClassLikeSymbol()?.fir as? FirRegularClass
}
override fun nullableAnyType(): SimpleTypeMarker = TODO("not implemented")
@@ -460,7 +472,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
}
override fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? {
return this as? FirTypeParameterSymbol
return this as? ConeTypeParameterLookupTag
}
override fun TypeConstructorMarker.isInlineClass(): Boolean {
@@ -472,8 +484,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
}
override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker {
require(this is FirTypeParameterSymbol)
return this.fir.bounds.getOrNull(0)?.let { it.coneType }
require(this is ConeTypeParameterLookupTag)
return this.symbol.fir.bounds.getOrNull(0)?.coneType
?: session.builtinTypes.nullableAnyType.type
}
@@ -492,11 +504,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
getClassFqNameUnsafe()?.startsWith(Name.identifier("kotlin")) == true
override fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe? {
if (this !is FirClassLikeSymbol<*>) return null
return toLookupTag().classId.asSingleFqName().toUnsafe()
if (this !is ConeClassLikeLookupTag) return null
return classId.asSingleFqName().toUnsafe()
}
override fun TypeParameterMarker.getName() = (this as FirTypeParameterSymbol).name
override fun TypeParameterMarker.getName() = (this as ConeTypeParameterLookupTag).name
override fun TypeParameterMarker.isReified(): Boolean = TODO("not implemented")
@@ -506,7 +518,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
}
override fun TypeConstructorMarker.isError(): Boolean {
return this is ErrorTypeConstructor
return this is ErrorTypeConstructor || (this is ConeClassLikeLookupTag && this.toSymbol(session) == null)
}
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
import org.jetbrains.kotlin.types.model.CaptureStatus
@@ -18,22 +19,22 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker
class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSessionComponent {
private val context = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session = session)
private val cache = HashMap<FirClassLikeSymbol<*>, Map<FirClassLikeSymbol<*>, List<ConeClassLikeType>>?>(1000, 0.5f)
private val cache = HashMap<ConeClassLikeLookupTag, Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>?>(1000, 0.5f)
fun getCorrespondingSupertypes(
type: ConeKotlinType,
supertypeConstructor: TypeConstructorMarker
): List<ConeClassLikeType>? {
if (type !is ConeClassLikeType || supertypeConstructor !is FirClassLikeSymbol<*>) return null
if (type !is ConeClassLikeType || supertypeConstructor !is ConeClassLikeLookupTag) return null
val symbol = type.lookupTag.toSymbol(session) ?: return null
if (symbol == supertypeConstructor) return listOf(captureType(type))
val lookupTag = type.lookupTag
if (lookupTag == supertypeConstructor) return listOf(captureType(type))
if (symbol !in cache) {
cache[symbol] = computeSupertypesMap(type, symbol)
if (lookupTag !in cache) {
cache[lookupTag] = computeSupertypesMap(lookupTag)
}
val resultTypes = cache[symbol]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null
val resultTypes = cache[lookupTag]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null
if (type.typeArguments.isEmpty()) return resultTypes
val capturedType = captureType(type)
@@ -46,18 +47,12 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
private fun captureType(type: ConeClassLikeType): ConeClassLikeType =
(context.captureFromArguments(type, CaptureStatus.FOR_SUBTYPING) ?: type) as ConeClassLikeType
private fun computeSupertypesMap(
subtype: ConeLookupTagBasedType,
subtypeSymbol: FirClassLikeSymbol<*>
): Map<FirClassLikeSymbol<*>, List<ConeClassLikeType>>? {
val resultingMap = HashMap<FirClassLikeSymbol<*>, List<ConeClassLikeType>>()
private fun computeSupertypesMap(subtypeLookupTag: ConeClassLikeLookupTag): Map<ConeClassLikeLookupTag, List<ConeClassLikeType>>? {
val resultingMap = HashMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>()
val subtypeClassSymbol: FirClassLikeSymbol<*> = with(context) {
subtype.typeConstructor() as? FirClassLikeSymbol<*> ?: return null
}
val subtypeFirClass: FirClassLikeDeclaration<*> = subtypeClassSymbol.fir
val subtypeFirClass: FirClassLikeDeclaration<*> = subtypeLookupTag.toSymbol(session)?.fir ?: return null
val defaultType = subtypeClassSymbol.toLookupTag().constructClassType(
val defaultType = subtypeLookupTag.constructClassType(
(subtypeFirClass as? FirTypeParameterRefsOwner)?.typeParameters?.map {
it.symbol.toLookupTag().constructType(emptyArray(), isNullable = false)
}?.toTypedArray().orEmpty(),
@@ -67,25 +62,24 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess
if (context.anySupertype(
defaultType,
{ it !is ConeClassLikeType || it.lookupTag.toSymbol(session) !is FirClassLikeSymbol<*> }
) { supertype -> computeSupertypePolicyAndPutInMap(supertype, subtypeSymbol, resultingMap) }
) { supertype -> computeSupertypePolicyAndPutInMap(supertype, resultingMap) }
) {
return null
}
return resultingMap
return resultingMap.also {
it.remove(subtypeLookupTag) // Just optimization: do not preserve mapping from MyClass to MyClas itself
}
}
private fun computeSupertypePolicyAndPutInMap(
supertype: SimpleTypeMarker,
subtypeSymbol: FirClassLikeSymbol<*>,
resultingMap: MutableMap<FirClassLikeSymbol<*>, List<ConeClassLikeType>>
resultingMap: MutableMap<ConeClassLikeLookupTag, List<ConeClassLikeType>>
): AbstractTypeCheckerContext.SupertypesPolicy {
val supertypeSymbol = (supertype as ConeClassLikeType).lookupTag.toSymbol(session) as FirClassLikeSymbol<*>
val supertypeLookupTag = (supertype as ConeClassLikeType).lookupTag
val captured = context.captureFromArguments(supertype, CaptureStatus.FOR_SUBTYPING) as ConeClassLikeType? ?: supertype
if (supertypeSymbol != subtypeSymbol) {
resultingMap[supertypeSymbol] = listOf(captured)
}
resultingMap[supertypeLookupTag] = listOf(captured)
return when {
with(context) { captured.argumentsCount() } == 0 -> {
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
@@ -122,7 +121,7 @@ fun ConeTypeContext.hasNullableSuperType(type: ConeKotlinType): Boolean {
if (type is ConeClassLikeType) return false
if (type !is ConeLookupTagBasedType) return false // TODO?
val symbol = type.lookupTag.toSymbol(session) ?: return false // TODO?!
val symbol = type.lookupTag
for (superType in symbol.supertypes()) {
if (superType.isNullableType()) return true
}
@@ -242,4 +241,4 @@ fun FirTypeRef.isExtensionFunctionType(session: FirSession): Boolean {
fun ConeKotlinType.isExtensionFunctionType(session: FirSession): Boolean {
val type = this.lowerBoundIfFlexible().fullyExpandedType(session)
return type.attributes.extensionFunctionType != null
}
}
@@ -5,13 +5,15 @@
package org.jetbrains.kotlin.fir.symbols
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.model.TypeParameterMarker
data class ConeTypeParameterLookupTag(val typeParameterSymbol: FirTypeParameterSymbol) : ConeClassifierLookupTagWithFixedSymbol() {
data class ConeTypeParameterLookupTag(
val typeParameterSymbol: FirTypeParameterSymbol
) : ConeClassifierLookupTagWithFixedSymbol(), TypeParameterMarker {
override val name: Name get() = typeParameterSymbol.name
override val symbol: FirClassifierSymbol<*>
override val symbol: FirTypeParameterSymbol
get() = typeParameterSymbol
}
@@ -7,10 +7,9 @@ package org.jetbrains.kotlin.fir.symbols
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
interface FirBasedSymbol<E> : TypeConstructorMarker where E : FirSymbolOwner<E>, E : FirDeclaration {
interface FirBasedSymbol<E> where E : FirSymbolOwner<E>, E : FirDeclaration {
val fir: E
fun bind(e: E)
}
}
@@ -9,9 +9,8 @@ import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.types.model.TypeParameterMarker
abstract class FirClassifierSymbol<E> : AbstractFirBasedSymbol<E>(), TypeParameterMarker
abstract class FirClassifierSymbol<E> : AbstractFirBasedSymbol<E>()
where E : FirSymbolOwner<E>, E : FirDeclaration {
abstract fun toLookupTag(): ConeClassifierLookupTag
}
}
@@ -75,5 +75,5 @@ fun test() {
}
// TODO: FIR
// {AbstractAssert<*, out Any!>! & EnumerableAssert<*, {Comparable<*> & java.io.Serializable!}>!} with unfolded flexible nullability
<!DEBUG_INFO_EXPRESSION_TYPE("AbstractAssert<out AbstractAssert<*, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!> & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!>? & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!> & EnumerableAssert<out AbstractAssert<*, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!> & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!>? & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<out AbstractAssert<*, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!> & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!>? & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!>? & EnumerableAssert<out AbstractAssert<*, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!> & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Unresolved: <error>..ERROR CLASS: Unresolved: <error>!>? & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?")!>assertion<!>
<!DEBUG_INFO_EXPRESSION_TYPE("AbstractAssert<out AbstractAssert<*, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!> & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!>? & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!> & EnumerableAssert<out AbstractAssert<*, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!> & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!>? & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<out AbstractAssert<*, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!> & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!>? & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!>? & EnumerableAssert<out AbstractAssert<*, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!> & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Not found classifier: /<error>..ERROR CLASS: Not found classifier: /<error>!>? & EnumerableAssert<*, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?, out kotlin.Comparable<kotlin.String & kotlin.Char> & java.io.Serializable..kotlin.Comparable<kotlin.String & kotlin.Char>? & java.io.Serializable?>?")!>assertion<!>
}