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