FIR: Refactor Cone types

- Get rid of AbbreviatedType
This commit is contained in:
Denis Zharkov
2019-11-19 14:59:57 +03:00
parent e03162f2dd
commit 159aefd26d
19 changed files with 105 additions and 147 deletions
@@ -109,16 +109,10 @@ abstract class ConeLookupTagBasedType : ConeKotlinType(), SimpleTypeMarker {
abstract val lookupTag: ConeClassifierLookupTag
}
sealed class ConeClassLikeType : ConeLookupTagBasedType() {
abstract class ConeClassLikeType : ConeLookupTagBasedType() {
abstract override val lookupTag: ConeClassLikeLookupTag
}
abstract class ConeClassType : ConeClassLikeType()
abstract class ConeAbbreviatedType : ConeClassLikeType() {
abstract val abbreviationLookupTag: ConeClassLikeLookupTag
}
open class ConeFlexibleType(val lowerBound: ConeKotlinType, val upperBound: ConeKotlinType) : ConeKotlinType(),
FlexibleTypeMarker {
@@ -6,13 +6,15 @@
package org.jetbrains.kotlin.fir.types.impl
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinTypeProjection
import org.jetbrains.kotlin.fir.types.ConeNullability
open class ConeClassLikeTypeImpl(
override val lookupTag: ConeClassLikeLookupTag,
override val typeArguments: Array<out ConeKotlinTypeProjection>,
isNullable: Boolean
) : ConeClassType() {
) : ConeClassLikeType() {
override val nullability: ConeNullability = ConeNullability.create(isNullable)
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -34,15 +36,3 @@ open class ConeClassLikeTypeImpl(
return result
}
}
class ConeAbbreviatedTypeImpl(
override val abbreviationLookupTag: ConeClassLikeLookupTag,
override val typeArguments: Array<out ConeKotlinTypeProjection>,
isNullable: Boolean
) : ConeAbbreviatedType() {
override val lookupTag: ConeClassLikeLookupTag
get() = abbreviationLookupTag
override val nullability: ConeNullability = ConeNullability.create(isNullable)
}
@@ -21,12 +21,17 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.directExpansionType
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.withNullability
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirAmbiguityError
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirInapplicableCandidateError
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
@@ -635,8 +640,19 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
private fun FlowContent.generate(type: ConeClassLikeType) {
resolved {
symbolRef(type.lookupTag.toSymbol(session)) {
fqn(type.lookupTag.classId.relativeClassName)
when (val symbol = type.lookupTag.toSymbol(session)) {
is FirTypeAliasSymbol -> {
symbolRef(symbol) {
simpleName(type.lookupTag.name)
}
+" = "
generate(type.directExpansionType(session) ?: ConeKotlinErrorType("No expansion for type-alias"))
}
else -> {
symbolRef(symbol) {
fqn(type.lookupTag.classId.relativeClassName)
}
}
}
}
}
@@ -720,13 +736,6 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
when (type) {
is ConeClassErrorType -> error { +type.reason }
is ConeClassLikeType -> generate(type)
is ConeAbbreviatedType -> resolved {
symbolRef(type.abbreviationLookupTag.toSymbol(session)) {
simpleName(type.abbreviationLookupTag.name)
}
+" = "
generate(type.directExpansionType(session) ?: ConeKotlinErrorType("No expansion for type-alias"))
}
is ConeTypeParameterType -> resolved {
symbolRef(type.lookupTag.toSymbol()) {
simpleName(type.lookupTag.name)
@@ -24,8 +24,8 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.resolve.directExpansionType
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.resolveSupertypesInTheAir
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
@@ -208,10 +208,8 @@ private fun createJavaFileStub(packageFqName: FqName, files: Collection<KtFile>)
}
private fun ConeClassLikeType.toFirClass(session: FirSession): FirRegularClass? {
return when (this) {
is ConeAbbreviatedType -> this.directExpansionType(session)?.toFirClass(session)
else -> (this.lookupTag.toSymbol(session) as? FirClassSymbol)?.fir
} as? FirRegularClass
val expandedType = this.fullyExpandedType(session)
return (expandedType.lookupTag.toSymbol(session) as? FirClassSymbol)?.fir as? FirRegularClass
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -232,13 +230,12 @@ private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
private fun ConeClassLikeType.mapToCanonicalString(session: FirSession): String {
return when (this) {
is ConeAbbreviatedType -> this.directExpansionType(session)?.mapToCanonicalString(session) ?: ERROR_TYPE_STUB
is ConeClassType -> mapToCanonicalString(session)
is ConeClassErrorType -> ERROR_TYPE_STUB
else -> fullyExpandedType(session).mapToCanonicalNoExpansionString(session)
}
}
private fun ConeClassType.mapToCanonicalString(session: FirSession): String {
private fun ConeClassLikeType.mapToCanonicalNoExpansionString(session: FirSession): String {
if (lookupTag.classId == StandardClassIds.Array) {
return when (val typeProjection = typeArguments[0]) {
is ConeStarProjection -> CommonClassNames.JAVA_LANG_OBJECT
@@ -10,12 +10,13 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
import org.jetbrains.kotlin.fir.declarations.addDefaultBoundIfNecessary
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
import org.jetbrains.kotlin.fir.resolve.toTypeProjection
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
@@ -133,7 +134,7 @@ class FirTypeDeserializer(
val abbreviatedTypeProto = proto.abbreviatedType(typeTable) ?: return simpleType
return ConeAbbreviatedTypeImpl(typeSymbol(abbreviatedTypeProto) as ConeClassLikeLookupTag, arguments, isNullable = false)
return ConeClassLikeTypeImpl(typeSymbol(abbreviatedTypeProto) as ConeClassLikeLookupTag, arguments, isNullable = false)
}
@@ -10,8 +10,8 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.componentArrayAccessor
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirStubDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.FirStubDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvable
@@ -31,7 +31,10 @@ import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -60,11 +63,19 @@ fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): FirClassLikeSym
return firSymbolProvider.getSymbolByLookupTag(this)
}
fun ConeAbbreviatedType.directExpansionType(
tailrec fun ConeClassLikeType.fullyExpandedType(
useSiteSession: FirSession,
expandedConeType: (FirTypeAlias) -> ConeClassLikeType? = FirTypeAlias::expandedConeType
): ConeClassLikeType {
val directExpansionType = directExpansionType(useSiteSession, expandedConeType) ?: return this
return directExpansionType.fullyExpandedType(useSiteSession, expandedConeType)
}
fun ConeClassLikeType.directExpansionType(
useSiteSession: FirSession,
expandedConeType: (FirTypeAlias) -> ConeClassLikeType? = FirTypeAlias::expandedConeType
): ConeClassLikeType? {
val typeAlias = abbreviationLookupTag
val typeAlias = lookupTag
.toSymbol(useSiteSession)
?.safeAs<FirTypeAliasSymbol>()?.fir ?: return null
@@ -73,7 +84,11 @@ fun ConeAbbreviatedType.directExpansionType(
return mapTypeAliasArguments(typeAlias, this, resultType) as? ConeClassLikeType
}
private fun mapTypeAliasArguments(typeAlias: FirTypeAlias, abbreviatedType: ConeAbbreviatedType, resultingType: ConeClassLikeType): ConeKotlinType {
private fun mapTypeAliasArguments(
typeAlias: FirTypeAlias,
abbreviatedType: ConeClassLikeType,
resultingType: ConeClassLikeType
): ConeKotlinType {
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
val substitutor = object : AbstractConeSubstitutor() {
@@ -129,8 +144,8 @@ fun FirClassifierSymbol<*>.constructType(typeArguments: Array<ConeKotlinTypeProj
ConeClassLikeTypeImpl(this.toLookupTag(), typeArguments, isNullable)
}
is FirTypeAliasSymbol -> {
ConeAbbreviatedTypeImpl(
abbreviationLookupTag = this.toLookupTag(),
ConeClassLikeTypeImpl(
this.toLookupTag(),
typeArguments = typeArguments,
isNullable = isNullable
)
@@ -170,12 +185,7 @@ fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability): T {
return when (this) {
is ConeClassErrorType -> this
is ConeClassTypeImpl -> ConeClassTypeImpl(lookupTag, typeArguments, nullability.isNullable) as T
is ConeAbbreviatedTypeImpl -> ConeAbbreviatedTypeImpl(
abbreviationLookupTag,
typeArguments,
nullability.isNullable
) as T
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable) as T
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable) as T
is ConeFlexibleType -> ConeFlexibleType(lowerBound.withNullability(nullability), upperBound.withNullability(nullability)) as T
is ConeTypeVariableType -> ConeTypeVariableType(nullability, lookupTag) as T
@@ -205,12 +215,7 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeKotlinTypeProj
return when (this) {
is ConeClassErrorType -> this
is ConeClassTypeImpl -> ConeClassTypeImpl(lookupTag, arguments, nullability.isNullable) as T
is ConeAbbreviatedTypeImpl -> ConeAbbreviatedTypeImpl(
abbreviationLookupTag,
arguments,
nullability.isNullable
) as T
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(original.withArguments(arguments)) as T
else -> error("Not supported: $this: ${this.render()}")
}
@@ -366,4 +371,4 @@ fun BodyResolveComponents.transformQualifiedAccessUsingSmartcastInfo(qualifiedAc
annotations += qualifiedAccessExpression.resultType.annotations
}
return FirExpressionWithSmartcastImpl(qualifiedAccessExpression, intersectedTypeRef, typesFromSmartCast)
}
}
@@ -56,7 +56,7 @@ class FirSamResolverImpl(
)
is ConeClassErrorType, is ConeStubType -> null
// TODO: support those types as well
is ConeAbbreviatedType, is ConeTypeParameterType, is ConeTypeVariableType,
is ConeTypeParameterType, is ConeTypeVariableType,
is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType -> null
// TODO: Thing of getting rid of this branch since ConeLookupTagBasedType should be a sealed class
is ConeLookupTagBasedType -> null
@@ -18,11 +18,15 @@ import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
return when (this) {
is ConeKotlinErrorType -> null
is ConeAbbreviatedType -> directExpansionType(useSiteSession)?.scope(useSiteSession, scopeSession)
is ConeClassLikeType -> {
// TODO: for ConeClassLikeType they might be a type alias instead of a class
val fir = this.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass<*> ?: return null
wrapSubstitutionScopeIfNeed(useSiteSession, fir.buildUseSiteMemberScope(useSiteSession, scopeSession)!!, fir, scopeSession)
val fullyExpandedType = fullyExpandedType(useSiteSession)
val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass<*> ?: return null
fullyExpandedType.wrapSubstitutionScopeIfNeed(
useSiteSession,
fir.buildUseSiteMemberScope(useSiteSession, scopeSession)!!,
fir,
scopeSession
)
}
is ConeTypeParameterType -> {
// TODO: support LibraryTypeParameterSymbol or get rid of it
@@ -132,18 +132,10 @@ fun ConeClassLikeType.wrapSubstitutionScopeIfNeed(
}
}
private tailrec fun ConeClassLikeType.computePartialExpansion(
private fun ConeClassLikeType.computePartialExpansion(
useSiteSession: FirSession,
supertypeSupplier: SupertypeSupplier
): ConeClassLikeType? {
return when (this) {
is ConeAbbreviatedType ->
directExpansionType(useSiteSession) {
supertypeSupplier.expansionForTypeAlias(it)
}?.computePartialExpansion(useSiteSession, supertypeSupplier)
else -> this
}
}
): ConeClassLikeType = fullyExpandedType(useSiteSession, supertypeSupplier::expansionForTypeAlias)
private fun FirClassifierSymbol<*>.collectSuperTypes(
list: MutableList<ConeClassLikeType>,
@@ -93,7 +93,7 @@ class ImplicitDispatchReceiverValue(
val klass = boundSymbol.fir as? FirRegularClass ?: return@run emptyList()
listOfNotNull(klass.companionObject?.buildUseSiteMemberScope(useSiteSession, scopeSession)) +
lookupSuperTypes(klass, lookupInterfaces = false, deep = true, useSiteSession = useSiteSession).mapNotNull {
val superClass = (it as? ConeClassType)?.lookupTag?.toSymbol(useSiteSession)?.fir as? FirRegularClass
val superClass = (it as? ConeClassLikeType)?.lookupTag?.toSymbol(useSiteSession)?.fir as? FirRegularClass
superClass?.companionObject?.buildUseSiteMemberScope(useSiteSession, scopeSession)
}
}
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.invoke
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
@@ -61,7 +61,7 @@ fun Candidate.preprocessCallableReference(
val ConeKotlinType.isBuiltinFunctionalType: Boolean
get() {
return when (this) {
is ConeClassType -> this.lookupTag.classId.asString().startsWith("kotlin/Function")
is ConeClassLikeType -> this.lookupTag.classId.asString().startsWith("kotlin/Function")
else -> false
}
}
@@ -71,7 +71,7 @@ private val ConeKotlinType.isSuspendFunctionType: Boolean
get() {
val type = this
return when (type) {
is ConeClassType -> {
is ConeClassLikeType -> {
val classId = type.lookupTag.classId
classId.packageFqName.asString() == "kotlin" && classId.relativeClassName.asString().startsWith("SuspendFunction")
}
@@ -88,14 +88,14 @@ private fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef): ConeKotlin
val ConeKotlinType.returnType: ConeKotlinType?
get() {
require(this is ConeClassType)
require(this is ConeClassLikeType)
val projection = typeArguments.last()
return (projection as? ConeTypedProjection)?.type
}
val ConeKotlinType.valueParameterTypes: List<ConeKotlinType?>
get() {
require(this is ConeClassType)
require(this is ConeClassLikeType)
return typeArguments.dropLast(1).map {
(it as? ConeTypedProjection)?.type
}
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeAbbreviatedType
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.name.FqName
@@ -324,14 +323,13 @@ private fun FirScope.getFirstClassifierOrNull(name: Name): FirClassifierSymbol<*
}
private fun finalExpansionName(symbol: FirTypeAliasSymbol, session: FirSession): Name? {
return when (val expandedType = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>()) {
is ConeAbbreviatedType ->
expandedType.abbreviationLookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()?.let {
finalExpansionName(it, session)
}
else -> expandedType.lookupTag.classId.shortClassName
}
val expandedType = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>()
val typeAliasSymbol = expandedType.lookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()
return if (typeAliasSymbol != null)
finalExpansionName(typeAliasSymbol, session)
else
expandedType.lookupTag.classId.shortClassName
}
val SAM_PARAMETER_NAME = Name.identifier("block")
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.substitution
import org.jetbrains.kotlin.fir.resolve.withNullability
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
@@ -68,8 +67,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
private fun ConeKotlinType.substituteRecursive(): ConeKotlinType? {
return when (this) {
is ConeClassErrorType -> return null
is ConeClassType -> this.substituteArguments()
is ConeAbbreviatedType -> this.substituteArguments()
is ConeClassLikeType -> this.substituteArguments()
is ConeLookupTagBasedType -> return null
is ConeFlexibleType -> this.substituteBounds()
is ConeCapturedType -> return null
@@ -130,11 +128,6 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
newArguments as Array<ConeKotlinTypeProjection>,
nullability.isNullable
)
is ConeAbbreviatedTypeImpl -> ConeAbbreviatedTypeImpl(
abbreviationLookupTag,
newArguments as Array<ConeKotlinTypeProjection>,
nullability.isNullable
)
is ConeClassLikeType -> error("Unknown class-like type to substitute: $this, ${this::class}")
else -> error("Unknown type to substitute: $this, ${this::class}")
}
@@ -248,8 +248,8 @@ private class FirSupertypeResolverVisitor(
)
val type = resolvedTypeRef.type
if (type is ConeAbbreviatedType) {
val expansionTypeAlias = type.abbreviationLookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()?.fir
if (type is ConeClassLikeType) {
val expansionTypeAlias = type.lookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()?.fir
if (expansionTypeAlias != null) {
visitTypeAlias(expansionTypeAlias)
}
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.symbols.invoke
fun ConeKotlinType.createArrayOf(session: FirSession, nullable: Boolean = false): ConeKotlinType {
val symbolProvider: FirSymbolProvider = session.firSymbolProvider
val type = lowerBoundIfFlexible()
if (type is ConeClassType) {
if (type is ConeClassLikeType) {
val primitiveArrayId = StandardClassIds.primitiveArrayTypeByElementType[type.lookupTag.classId]
if (primitiveArrayId != null) {
return primitiveArrayId.invoke(symbolProvider).constructType(emptyArray(), nullable)
@@ -29,7 +29,7 @@ fun ConeKotlinType.createArrayOf(session: FirSession, nullable: Boolean = false)
fun ConeKotlinType.arrayElementType(session: FirSession): ConeKotlinType? {
val type = this.lowerBoundIfFlexible()
if (type !is ConeClassType) return null
if (type !is ConeClassLikeType) return null
val classId = type.lookupTag.classId
if (classId == StandardClassIds.Array)
return (type.typeArguments.first() as ConeTypedProjection).type
@@ -39,4 +39,4 @@ fun ConeKotlinType.arrayElementType(session: FirSession): ConeKotlinType? {
}
return null
}
}
@@ -58,8 +58,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
override fun KotlinTypeMarker.asSimpleType(): SimpleTypeMarker? {
assert(this is ConeKotlinType)
return when (this) {
is ConeAbbreviatedType -> directExpansionType(session)
?: ConeClassErrorType("no expansion for type-alias: ${this.abbreviationLookupTag.classId}")
is ConeClassLikeType -> fullyExpandedType(session)
is ConeCapturedType -> this
is ConeLookupTagBasedType -> this
is ConeDefinitelyNotNullType -> this
@@ -126,24 +125,17 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
}
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
val typeConstructor = when (this) {
return when (this) {
is ConeCapturedType -> constructor
is ConeTypeVariableType -> this.lookupTag as ConeTypeVariableTypeConstructor // TODO: WTF
is ConeAbbreviatedType -> this.directExpansionType(session)?.typeConstructor()
?: ErrorTypeConstructor("Failed to expand alias: $this")
is ConeLookupTagBasedType -> this.lookupTag.toSymbol(session) ?: ErrorTypeConstructor("Unresolved: ${this.lookupTag}")
is ConeTypeVariableType -> lookupTag as ConeTypeVariableTypeConstructor // TODO: WTF
is ConeClassLikeType -> lookupTag.toSymbol(session)
?: ErrorTypeConstructor("Unresolved: $lookupTag")
is ConeLookupTagBasedType -> lookupTag.toSymbol(session) ?: ErrorTypeConstructor("Unresolved: $lookupTag")
is ConeIntersectionType -> this
is ConeStubType -> variable.typeConstructor
is ConeDefinitelyNotNullType -> original.typeConstructor()
else -> error("?: $this")
}
// TODO: get rid of class types with type-alias symbols
if (typeConstructor is FirTypeAliasSymbol) {
return typeConstructor.fir.expandedTypeRef.coneTypeSafe<ConeKotlinType>()?.typeConstructor()
?: ErrorTypeConstructor("Failed to expand alias: ${this}")
}
return typeConstructor
}
override fun CapturedTypeMarker.typeConstructor(): CapturedTypeConstructorMarker {
@@ -401,28 +393,9 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return ConeTypeIntersector.intersectTypes(this as ConeInferenceContext, types as List<ConeKotlinType>)
}
private fun prepareClassLikeType(
type: ConeClassLikeType,
visited: MutableSet<ConeAbbreviatedType>
): KotlinTypeMarker {
return when (type) {
is ConeAbbreviatedType -> prepareAbbreviatedType(type, visited)
else -> type
}
}
private fun prepareAbbreviatedType(
type: ConeAbbreviatedType,
visited: MutableSet<ConeAbbreviatedType> = mutableSetOf()
): KotlinTypeMarker {
if (type in visited) return ConeClassErrorType("Recursive type alias")
visited += type
return prepareClassLikeType(type.directExpansionType(session) ?: ConeClassErrorType("unresolved"), visited)
}
override fun prepareType(type: KotlinTypeMarker): KotlinTypeMarker {
return when (type) {
is ConeAbbreviatedType -> prepareAbbreviatedType(type)
is ConeClassLikeType -> type.fullyExpandedType(session)
else -> type
}
}
@@ -528,11 +501,11 @@ class ConeTypeCheckerContext(
if (type.argumentsCount() == 0) return SupertypesPolicy.LowerIfFlexible
require(type is ConeKotlinType)
val declaration = when (type) {
is ConeClassType -> type.lookupTag.toSymbol(session)?.firUnsafe<FirRegularClass>()
is ConeClassLikeType -> type.lookupTag.toSymbol(session)?.firUnsafe<FirClassLikeDeclaration<*>>()
else -> null
}
val substitutor = if (declaration != null) {
val substitutor = if (declaration is FirTypeParametersOwner) {
val substitution =
declaration.typeParameters.zip(type.typeArguments).associate { (parameter, argument) ->
parameter.symbol to ((argument as? ConeTypedProjection)?.type
@@ -560,6 +533,10 @@ class ConeTypeCheckerContext(
return super<ConeTypeContext>.prepareType(type)
}
override fun refineType(type: KotlinTypeMarker): KotlinTypeMarker {
return prepareType(type)
}
override val KotlinTypeMarker.isAllowedTypeVariable: Boolean
get() = this is ConeKotlinType && this is ConeTypeVariableType
@@ -7,20 +7,18 @@ package org.jetbrains.kotlin.fir.expressions
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorLoopImpl
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.name.ClassId
inline val FirAnnotationCall.coneClassLikeType: ConeClassLikeType?
get() = ((annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeClassLikeType)?.takeIf { it !is ConeClassErrorType }
get() = ((annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeClassLikeType)
inline val FirAnnotationCall.classId: ClassId?
get() = coneClassLikeType?.lookupTag?.classId
@@ -26,7 +26,7 @@ sealed class FirImplicitBuiltinTypeRef(
override val annotations: List<FirAnnotationCall>
get() = emptyList()
override val type: ConeClassLikeType = ConeClassTypeImpl(ConeClassLikeLookupTagImpl(id), typeArguments, isNullable)
override val type: ConeClassLikeType = ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(id), typeArguments, isNullable)
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
@@ -74,4 +74,4 @@ class FirImplicitStringTypeRef(
class FirImplicitKPropertyTypeRef(
source: FirSourceElement?,
typeArgument: ConeKotlinTypeProjection
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.KProperty, arrayOf(typeArgument))
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.KProperty, arrayOf(typeArgument))
@@ -467,7 +467,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: StringBuilder) {
val coneType = resolvedTypeRef.type
data.append(removeCurrentFilePackage(coneType.render()))
if (coneType is ConeAbbreviatedType) {
if (coneType is ConeClassLikeType) {
val original = coneType.directExpansionType(session)
original?.let { data.append(" /* = ${it.render()} */") }
}