[FIR] Fix TODOs and cleanup ConeTypeContext and ConeInferenceContext
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
|
||||
fun ConeKotlinType.substitutedUnderlyingTypeForInlineClass(session: FirSession, context: ConeTypeContext): ConeKotlinType? {
|
||||
val symbol = (this.fullyExpandedType(session) as? ConeLookupTagBasedType)
|
||||
?.lookupTag
|
||||
?.toSymbol(session) as? FirRegularClassSymbol
|
||||
?: return null
|
||||
symbol.ensureResolved(FirResolvePhase.STATUS, session)
|
||||
val firClass = symbol.fir
|
||||
if (!firClass.status.isInline) return null
|
||||
val constructor = firClass.declarations.singleOrNull { it is FirConstructor && it.isPrimary } as FirConstructor? ?: return null
|
||||
val valueParameter = constructor.valueParameters.singleOrNull() ?: return null
|
||||
val unsubstitutedType = valueParameter.returnTypeRef.coneType
|
||||
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(mapOf(this.typeConstructor(context) to this), context)
|
||||
return substitutor.substituteOrNull(unsubstitutedType)
|
||||
}
|
||||
+16
@@ -10,6 +10,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
|
||||
abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||
private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection {
|
||||
@@ -162,3 +166,15 @@ data class ConeSubstitutorByMap(val substitution: Map<FirTypeParameterSymbol, Co
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
|
||||
if (map.isEmpty()) return ConeSubstitutor.Empty
|
||||
return object : AbstractConeSubstitutor(),
|
||||
TypeSubstitutorMarker {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
||||
val new = map[type.typeConstructor(context)] ?: return null
|
||||
return new.approximateIntegerLiteralType().updateNullabilityIfNeeded(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ fun ConeKotlinType.createOutArrayType(nullable: Boolean = false): ConeKotlinType
|
||||
return ConeKotlinTypeProjectionOut(this).createArrayType(nullable)
|
||||
}
|
||||
|
||||
fun ConeTypeProjection.createArrayType(nullable: Boolean = false): ConeKotlinType {
|
||||
fun ConeTypeProjection.createArrayType(nullable: Boolean = false): ConeClassLikeType {
|
||||
if (this is ConeKotlinTypeProjection) {
|
||||
val type = type.lowerBoundIfFlexible()
|
||||
if (type is ConeClassLikeType && type.nullability != ConeNullability.NULLABLE) {
|
||||
|
||||
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.fir.resolve.calls.NoSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
|
||||
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.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
@@ -32,19 +32,19 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
val symbolProvider: FirSymbolProvider get() = session.symbolProvider
|
||||
|
||||
override fun nullableNothingType(): SimpleTypeMarker {
|
||||
return session.builtinTypes.nullableNothingType.type//StandardClassIds.Nothing(symbolProvider).constructType(emptyArray(), true)
|
||||
return session.builtinTypes.nullableNothingType.type
|
||||
}
|
||||
|
||||
override fun nullableAnyType(): SimpleTypeMarker {
|
||||
return session.builtinTypes.nullableAnyType.type//StandardClassIds.Any(symbolProvider).constructType(emptyArray(), true)
|
||||
return session.builtinTypes.nullableAnyType.type
|
||||
}
|
||||
|
||||
override fun nothingType(): SimpleTypeMarker {
|
||||
return session.builtinTypes.nothingType.type//StandardClassIds.Nothing(symbolProvider).constructType(emptyArray(), false)
|
||||
return session.builtinTypes.nothingType.type
|
||||
}
|
||||
|
||||
override fun anyType(): SimpleTypeMarker {
|
||||
return session.builtinTypes.anyType.type//StandardClassIds.Any(symbolProvider).constructType(emptyArray(), false)
|
||||
return session.builtinTypes.anyType.type
|
||||
}
|
||||
|
||||
override fun createFlexibleType(lowerBound: SimpleTypeMarker, upperBound: SimpleTypeMarker): KotlinTypeMarker {
|
||||
@@ -102,14 +102,13 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
|
||||
override fun KotlinTypeMarker.canHaveUndefinedNullability(): Boolean {
|
||||
require(this is ConeKotlinType)
|
||||
return this is ConeCapturedType /*|| this is ConeTypeVariable // TODO */
|
||||
return this is ConeCapturedType || this is ConeTypeVariableType
|
||||
|| this is ConeTypeParameterType
|
||||
}
|
||||
|
||||
// TODO: implement checking for extension function
|
||||
override fun SimpleTypeMarker.isExtensionFunction(): Boolean {
|
||||
require(this is ConeKotlinType)
|
||||
return false
|
||||
return this.isExtensionFunctionType
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.typeDepth() = when (this) {
|
||||
@@ -151,11 +150,6 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
if (this == null) return false
|
||||
if (!visited.add(this)) return false
|
||||
|
||||
/*
|
||||
TODO:?
|
||||
UnwrappedType unwrappedType = type.unwrap();
|
||||
*/
|
||||
|
||||
if (predicate(this)) return true
|
||||
|
||||
val flexibleType = this as? ConeFlexibleType
|
||||
@@ -300,15 +294,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
}
|
||||
|
||||
override fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): ConeSubstitutor {
|
||||
if (map.isEmpty()) return createEmptySubstitutor()
|
||||
return object : AbstractConeSubstitutor(),
|
||||
TypeSubstitutorMarker {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
||||
val new = map[type.typeConstructor()] ?: return null
|
||||
return (new as ConeKotlinType).approximateIntegerLiteralType().updateNullabilityIfNeeded(type)
|
||||
}
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return createTypeSubstitutorByTypeConstructor(map as Map<TypeConstructorMarker, ConeKotlinType>, this)
|
||||
}
|
||||
|
||||
override fun createEmptySubstitutor(): ConeSubstitutor {
|
||||
@@ -328,7 +315,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.isSpecial(): Boolean {
|
||||
// TODO
|
||||
// Cone type system doesn't have special types
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ 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.resolve.transformers.ensureResolved
|
||||
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
|
||||
@@ -100,7 +99,6 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.asCapturedType(): CapturedTypeMarker? {
|
||||
//require(this is ConeLookupTagBasedType)
|
||||
return this as? ConeCapturedType
|
||||
}
|
||||
|
||||
@@ -124,7 +122,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
is ConeClassLikeType -> lookupTag
|
||||
is ConeTypeParameterType -> lookupTag
|
||||
is ConeCapturedType -> constructor
|
||||
is ConeTypeVariableType -> lookupTag as ConeTypeVariableTypeConstructor // TODO: WTF
|
||||
is ConeTypeVariableType -> lookupTag
|
||||
is ConeIntersectionType -> this
|
||||
is ConeStubType -> variable.typeConstructor
|
||||
is ConeDefinitelyNotNullType -> original.typeConstructor()
|
||||
@@ -150,20 +148,16 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
|
||||
override fun KotlinTypeMarker.argumentsCount(): Int {
|
||||
require(this is ConeKotlinType)
|
||||
|
||||
return this.typeArguments.size
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker {
|
||||
require(this is ConeKotlinType)
|
||||
|
||||
return this.typeArguments.getOrNull(index)
|
||||
?: session.builtinTypes.anyType.type//StandardClassIds.Any(session.firSymbolProvider).constructType(emptyArray(), false) // TODO wtf
|
||||
return this.typeArguments.getOrNull(index) ?: ConeStarProjection
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.asTypeArgument(): TypeArgumentMarker {
|
||||
require(this is ConeKotlinType)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -196,7 +190,6 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.parametersCount(): Int {
|
||||
//require(this is ConeSymbol)
|
||||
return when (this) {
|
||||
is ConeTypeParameterLookupTag,
|
||||
is ConeCapturedTypeConstructor,
|
||||
@@ -204,7 +197,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
is ConeTypeVariableTypeConstructor,
|
||||
is ConeIntersectionType -> 0
|
||||
is ConeClassLikeLookupTag -> {
|
||||
when(val symbol = toSymbol(session)) {
|
||||
when (val symbol = toSymbol(session)) {
|
||||
is FirAnonymousObjectSymbol -> symbol.fir.typeParameters.size
|
||||
is FirRegularClassSymbol -> symbol.fir.typeParameters.size
|
||||
is FirTypeAliasSymbol -> symbol.fir.typeParameters.size
|
||||
@@ -212,12 +205,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
}
|
||||
}
|
||||
is ConeIntegerLiteralType -> 0
|
||||
else -> error("?!:10")
|
||||
else -> unknownConstructorError()
|
||||
}
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getParameter(index: Int): TypeParameterMarker {
|
||||
//require(this is ConeSymbol)
|
||||
return when (val symbol = toClassLikeSymbol()) {
|
||||
is FirAnonymousObjectSymbol -> symbol.fir.typeParameters[index].symbol.toLookupTag()
|
||||
is FirRegularClassSymbol -> symbol.fir.typeParameters[index].symbol.toLookupTag()
|
||||
@@ -243,7 +235,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
is ConeCapturedTypeConstructor -> supertypes!!
|
||||
is ConeIntersectionType -> intersectedTypes
|
||||
is ConeIntegerLiteralType -> supertypes
|
||||
else -> error("?!:13")
|
||||
else -> unknownConstructorError()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +244,6 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.isClassTypeConstructor(): Boolean {
|
||||
//assert(this is ConeSymbol)
|
||||
return this is ConeClassLikeLookupTag
|
||||
}
|
||||
|
||||
@@ -278,21 +269,21 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
|
||||
override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
|
||||
if (c1 is ErrorTypeConstructor || c2 is ErrorTypeConstructor) return false
|
||||
|
||||
//assert(c1 is ConeSymbol)
|
||||
//assert(c2 is ConeSymbol)
|
||||
return c1 == c2
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.isDenotable(): Boolean {
|
||||
//TODO
|
||||
return when (this) {
|
||||
is ConeClassLikeLookupTag,
|
||||
is ConeTypeParameterLookupTag -> true
|
||||
|
||||
is ConeCapturedTypeConstructor,
|
||||
is ErrorTypeConstructor,
|
||||
is ConeTypeVariableTypeConstructor,
|
||||
is ConeIntersectionType,
|
||||
is ConeIntegerLiteralType -> false
|
||||
is AbstractFirBasedSymbol<*> -> true
|
||||
else -> true
|
||||
is ConeIntegerLiteralType,
|
||||
is ConeIntersectionType -> false
|
||||
|
||||
else -> unknownConstructorError()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,9 +404,12 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
return toClassLikeSymbol()?.fir as? FirRegularClass
|
||||
}
|
||||
|
||||
override fun nullableAnyType(): SimpleTypeMarker = TODO("not implemented")
|
||||
override fun nullableAnyType(): SimpleTypeMarker = session.builtinTypes.nullableAnyType.type
|
||||
|
||||
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker = TODO("not implemented")
|
||||
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker {
|
||||
require(componentType is ConeKotlinType)
|
||||
return componentType.createArrayType(nullable = false)
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.isArrayOrNullableArray(): Boolean {
|
||||
require(this is ConeKotlinType)
|
||||
@@ -459,8 +453,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker? {
|
||||
// TODO: support inline classes
|
||||
return null
|
||||
require(this is ConeKotlinType)
|
||||
return substitutedUnderlyingTypeForInlineClass(session, this@ConeTypeContext)
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getPrimitiveType() =
|
||||
@@ -479,7 +473,10 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
|
||||
override fun TypeParameterMarker.getName() = (this as ConeTypeParameterLookupTag).name
|
||||
|
||||
override fun TypeParameterMarker.isReified(): Boolean = TODO("not implemented")
|
||||
override fun TypeParameterMarker.isReified(): Boolean {
|
||||
require(this is ConeTypeParameterLookupTag)
|
||||
return typeParameterSymbol.fir.isReified
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||
val classKind = typeConstructor().toFirRegularClass()?.classKind ?: return false
|
||||
@@ -489,6 +486,10 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
override fun TypeConstructorMarker.isError(): Boolean {
|
||||
return this is ErrorTypeConstructor
|
||||
}
|
||||
|
||||
private fun TypeConstructorMarker.unknownConstructorError(): Nothing {
|
||||
error("Unknown type constructor: ${this::class}")
|
||||
}
|
||||
}
|
||||
|
||||
class ConeTypeCheckerContext(
|
||||
|
||||
Reference in New Issue
Block a user