Type Approximation: add separate flag to control approx. anonymous type

This extra flexibility is useful for IDE where we always want to
approximate anonymous types but may not want to approximate other local
 types
This commit is contained in:
Tianyu Geng
2021-12-07 10:31:29 -08:00
committed by teamcity
parent c5c606924c
commit a5844b754e
7 changed files with 28 additions and 2 deletions
@@ -28,5 +28,6 @@ internal object PublicTypeApproximator {
override val definitelyNotNullType: Boolean get() = false
override val integerLiteralType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true
override val anonymous: Boolean get() = true
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.TypeCheckerState.SupertypesPolicy.DoCustomTransform
@@ -47,6 +48,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return classId.isLocal
}
override fun TypeConstructorMarker.isAnonymous(): Boolean {
if (this !is ConeClassLikeLookupTag) return false
return name == SpecialNames.ANONYMOUS
}
override val TypeVariableTypeConstructorMarker.typeParameter: TypeParameterMarker?
get() {
require(this is ConeTypeVariableTypeConstructor)
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.Variance
@@ -310,6 +311,11 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
return this.owner.classId?.isLocal == true
}
override fun TypeConstructorMarker.isAnonymous(): Boolean {
if (this !is IrClassSymbol) return false
return this.owner.classId?.shortClassName == SpecialNames.ANONYMOUS
}
override val TypeVariableTypeConstructorMarker.typeParameter: TypeParameterMarker?
get() = error("Type variables is unsupported in IR")
@@ -169,9 +169,9 @@ abstract class AbstractTypeApproximator(
private fun approximateLocalTypes(type: SimpleTypeMarker, conf: TypeApproximatorConfiguration, toSuper: Boolean): SimpleTypeMarker? {
if (!toSuper) return null
if (!conf.localTypes) return null
if (!conf.localTypes && !conf.anonymous) return null
val constructor = type.typeConstructor()
val needApproximate = conf.localTypes && constructor.isLocalType()
val needApproximate = (conf.localTypes && constructor.isLocalType()) || (conf.anonymous && constructor.isAnonymous())
if (!needApproximate) return null
val superConstructor = constructor.supertypes().first().typeConstructor()
val typeCheckerContext = newTypeCheckerState(
@@ -25,6 +25,12 @@ open class TypeApproximatorConfiguration {
open val intersectionTypesInContravariantPositions = false
open val localTypes = false
/**
* Whether to approximate anonymous type. This flag does not have any effect if `localTypes` is true because all anonymous types are
* local.
*/
open val anonymous = false
open val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean = { false }
open fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean =
true // false means that this type we can leave as is
@@ -377,6 +377,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
fun TypeConstructorMarker.isInterface(): Boolean
fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean
fun TypeConstructorMarker.isLocalType(): Boolean
fun TypeConstructorMarker.isAnonymous(): Boolean
fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker?
val TypeVariableTypeConstructorMarker.typeParameter: TypeParameterMarker?
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.impl.AbstractTypeParameterDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
@@ -44,6 +45,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
return declarationDescriptor?.classId?.isLocal == true
}
override fun TypeConstructorMarker.isAnonymous(): Boolean {
require(this is TypeConstructor, this::errorMessage)
return declarationDescriptor?.classId?.shortClassName == SpecialNames.ANONYMOUS
}
override val TypeVariableTypeConstructorMarker.typeParameter: TypeParameterMarker?
get() {
require(this is NewTypeVariableConstructor, this::errorMessage)