From a5844b754e103f7388c04f3035e1a9c738c1976b Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Tue, 7 Dec 2021 10:31:29 -0800 Subject: [PATCH] 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 --- .../kotlin/analysis/api/fir/types/PublicTypeApproximator.kt | 1 + .../src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt | 6 ++++++ .../org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt | 6 ++++++ .../org/jetbrains/kotlin/types/AbstractTypeApproximator.kt | 4 ++-- .../jetbrains/kotlin/types/TypeApproximatorConfiguration.kt | 6 ++++++ .../org/jetbrains/kotlin/types/model/TypeSystemContext.kt | 1 + .../kotlin/types/checker/ClassicTypeSystemContext.kt | 6 ++++++ 7 files changed, 28 insertions(+), 2 deletions(-) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/PublicTypeApproximator.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/PublicTypeApproximator.kt index 0dc48f3274a..8b516c19421 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/PublicTypeApproximator.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/PublicTypeApproximator.kt @@ -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 } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 503b7367e05..d2ee6566e29 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -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) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index f20cb9db70a..36bd20cee84 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -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") diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/types/AbstractTypeApproximator.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/types/AbstractTypeApproximator.kt index ac8c3267967..fbd36112098 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/types/AbstractTypeApproximator.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/types/AbstractTypeApproximator.kt @@ -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( diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/types/TypeApproximatorConfiguration.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/types/TypeApproximatorConfiguration.kt index 9622c559f02..c88734dc6f0 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/types/TypeApproximatorConfiguration.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/types/TypeApproximatorConfiguration.kt @@ -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 diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index d5a0f1e92d1..a81df4eb87f 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -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? diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index e32e9a01c02..61bd854b362 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -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)