Union type attributes for common super type calculation

This commit is contained in:
Irene Dea
2021-10-13 14:37:31 -07:00
committed by Dmitriy Novozhilov
parent db471ca61e
commit 56d817b49f
11 changed files with 44 additions and 150 deletions
@@ -11,6 +11,9 @@
<extensionPoint qualifiedName="org.jetbrains.kotlin.extensions.internal.typeResolutionInterceptorExtension"
interface="org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptorExtension"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.extensions.TypeAttributeTranslatorExtension"
interface="org.jetbrains.kotlin.extensions.TypeAttributeTranslatorExtension"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.diagnosticSuppressor"
interface="org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor"
dynamic="true"/>
@@ -415,7 +415,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return false
}
override fun KotlinTypeMarker.getAnnotations(): List<AnnotationMarker> {
override fun KotlinTypeMarker.getAttributes(): List<AnnotationMarker> {
require(this is ConeKotlinType)
return attributes.toList()
}
@@ -397,7 +397,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun SimpleTypeMarker.isPrimitiveType(): Boolean =
this is IrSimpleType && irTypePredicates_isPrimitiveType()
override fun KotlinTypeMarker.getAnnotations(): List<AnnotationMarker> {
override fun KotlinTypeMarker.getAttributes(): List<AnnotationMarker> {
require(this is IrType)
return this.annotations.map { object : AnnotationMarker, IrElement by it {} }
}
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.types.model.*
object NewCommonSuperTypeCalculator {
fun TypeSystemCommonSuperTypesContext.commonSuperType(types: List<KotlinTypeMarker>): KotlinTypeMarker {
val maxDepth = types.maxOfOrNull { it.typeDepth() } ?: 0
return commonSuperType(types, -maxDepth, true)
return commonSuperType(types, -maxDepth, true).replaceTypeAttributes(unionTypeAttributes(types))
}
private fun TypeSystemCommonSuperTypesContext.commonSuperType(
@@ -80,7 +80,7 @@ class PostponedArgumentInputTypesResolver(
}
}
val annotations = functionalTypesFromConstraints?.map { it.type.getAnnotations() }?.flatten()?.distinct()
val annotations = functionalTypesFromConstraints?.map { it.type.getAttributes() }?.flatten()?.distinct()
val extensionFunctionTypePresentInConstraints = functionalTypesFromConstraints?.any { it.type.isExtensionFunctionType() } == true
@@ -139,7 +139,11 @@ class MutableVariableWithConstraints private constructor(
return false
return when (old.kind) {
ConstraintKind.EQUALITY -> true
ConstraintKind.EQUALITY -> {
with(context) {
old.type.getAttributes() == new.type.getAttributes()
}
}
ConstraintKind.LOWER -> new.kind.isLower()
ConstraintKind.UPPER -> new.kind.isUpper()
}
@@ -133,6 +133,10 @@ interface TypeSystemCommonSuperTypesContext : TypeSystemContext, TypeSystemTypeF
* Used only in FIR
*/
fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker
fun unionTypeAttributes(types: List<KotlinTypeMarker>): List<AnnotationMarker> = emptyList()
fun KotlinTypeMarker.replaceTypeAttributes(newAttributes: List<AnnotationMarker>): KotlinTypeMarker = this
}
// This interface is only used to declare that implementing class is supposed to be used as a TypeSystemInferenceExtensionContext component
@@ -494,7 +498,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
fun SimpleTypeMarker.isPrimitiveType(): Boolean
fun KotlinTypeMarker.getAnnotations(): List<AnnotationMarker>
fun KotlinTypeMarker.getAttributes(): List<AnnotationMarker>
fun substitutionSupertypePolicy(type: SimpleTypeMarker): TypeCheckerState.SupertypesPolicy
@@ -1,112 +0,0 @@
/*
* 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.types
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import kotlin.reflect.KClass
object CompilerTypeAttributes {
object Exact : TypeAttribute<Exact>() {
val ANNOTATION_CLASS_ID = ClassId(FqName("kotlin.internal"), Name.identifier("Exact"))
override fun union(other: Exact?): Exact? = null
override fun intersect(other: Exact?): Exact? = null
override fun add(other: Exact?): Exact = this
override fun isSubtypeOf(other: Exact?): Boolean = true
override val key: KClass<out Exact> = Exact::class
override fun toString(): String = "@Exact"
}
object NoInfer : TypeAttribute<NoInfer>() {
val ANNOTATION_CLASS_ID = ClassId(FqName("kotlin.internal"), Name.identifier("NoInfer"))
override fun union(other: NoInfer?): NoInfer? = null
override fun intersect(other: NoInfer?): NoInfer? = null
override fun add(other: NoInfer?): NoInfer = this
override fun isSubtypeOf(other: NoInfer?): Boolean = true
override val key: KClass<out NoInfer> = NoInfer::class
override fun toString(): String = "@NoInfer"
}
object EnhancedNullability : TypeAttribute<EnhancedNullability>() {
val ANNOTATION_CLASS_ID = StandardClassIds.Annotations.EnhancedNullability
override fun union(other: EnhancedNullability?): EnhancedNullability? = other
override fun intersect(other: EnhancedNullability?): EnhancedNullability = this
override fun add(other: EnhancedNullability?): EnhancedNullability = this
override fun isSubtypeOf(other: EnhancedNullability?): Boolean = true
override val key: KClass<out EnhancedNullability> = EnhancedNullability::class
override fun toString(): String = "@EnhancedNullability"
}
object ExtensionFunctionType : TypeAttribute<ExtensionFunctionType>() {
val ANNOTATION_CLASS_ID = ClassId(FqName("kotlin"), Name.identifier("ExtensionFunctionType"))
override fun union(other: ExtensionFunctionType?): ExtensionFunctionType? = other
override fun intersect(other: ExtensionFunctionType?): ExtensionFunctionType = this
override fun add(other: ExtensionFunctionType?): ExtensionFunctionType = this
override fun isSubtypeOf(other: ExtensionFunctionType?): Boolean = true
override val key: KClass<out ExtensionFunctionType> = ExtensionFunctionType::class
override fun toString(): String = "@ExtensionFunctionType"
}
object UnsafeVariance : TypeAttribute<UnsafeVariance>() {
val ANNOTATION_CLASS_ID = ClassId(FqName("kotlin"), Name.identifier("UnsafeVariance"))
override fun union(other: UnsafeVariance?): UnsafeVariance? = null
override fun intersect(other: UnsafeVariance?): UnsafeVariance? = null
override fun add(other: UnsafeVariance?): UnsafeVariance = this
override fun isSubtypeOf(other: UnsafeVariance?): Boolean = true
override val key: KClass<out UnsafeVariance> = UnsafeVariance::class
override fun toString(): String = "@UnsafeVariance"
}
val compilerAttributeByClassId: Map<ClassId, TypeAttribute<*>> = mapOf(
Exact.ANNOTATION_CLASS_ID to Exact,
NoInfer.ANNOTATION_CLASS_ID to NoInfer,
EnhancedNullability.ANNOTATION_CLASS_ID to EnhancedNullability,
ExtensionFunctionType.ANNOTATION_CLASS_ID to ExtensionFunctionType,
UnsafeVariance.ANNOTATION_CLASS_ID to UnsafeVariance
)
val compilerAttributeByFqName: Map<FqName, TypeAttribute<*>> = compilerAttributeByClassId.mapKeys { it.key.asSingleFqName() }
}
val TypeAttributes.exact: CompilerTypeAttributes.Exact? by TypeAttributes.attributeAccessor<CompilerTypeAttributes.Exact>()
val TypeAttributes.noInfer: CompilerTypeAttributes.NoInfer? by TypeAttributes.attributeAccessor<CompilerTypeAttributes.NoInfer>()
val TypeAttributes.enhancedNullability: CompilerTypeAttributes.EnhancedNullability? by TypeAttributes.attributeAccessor<CompilerTypeAttributes.EnhancedNullability>()
val TypeAttributes.extensionFunctionType: CompilerTypeAttributes.ExtensionFunctionType? by TypeAttributes.attributeAccessor<CompilerTypeAttributes.ExtensionFunctionType>()
val TypeAttributes.unsafeVarianceType: CompilerTypeAttributes.UnsafeVariance? by TypeAttributes.attributeAccessor<CompilerTypeAttributes.UnsafeVariance>()
// ------------------------------------------------------------------
val TypeAttributes.hasEnhancedNullability: Boolean
get() = enhancedNullability != null
// ------------------------------------------------------------------
val KotlinType.hasEnhancedNullability: Boolean
get() = attributes.enhancedNullability != null
val KotlinType.isExtensionFunctionType: Boolean
get() = attributes.extensionFunctionType != null
@@ -42,11 +42,6 @@ class TypeAttributes private constructor(attributes: List<TypeAttribute<*>>) : A
}
val Empty: TypeAttributes = TypeAttributes(emptyList())
val WithExtensionFunctionType: TypeAttributes = TypeAttributes(listOf(CompilerTypeAttributes.ExtensionFunctionType))
private val predefinedAttributes: Map<TypeAttribute<*>, TypeAttributes> = mapOf(
CompilerTypeAttributes.EnhancedNullability.predefined()
)
private fun TypeAttribute<*>.predefined(): Pair<TypeAttribute<*>, TypeAttributes> = this to TypeAttributes(this)
@@ -87,7 +82,7 @@ class TypeAttributes private constructor(attributes: List<TypeAttribute<*>>) : A
@OptIn(ExperimentalStdlibApi::class)
operator fun plus(attribute: TypeAttribute<*>): TypeAttributes {
if (attribute in this) return this
if (isEmpty()) return predefinedAttributes[attribute] ?: TypeAttributes(attribute)
if (isEmpty()) return TypeAttributes(attribute)
val newAttributes = buildList {
addAll(this)
add(attribute)
@@ -5,9 +5,6 @@
package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
interface TypeAttributesTranslator {
@@ -17,28 +14,10 @@ interface TypeAttributesTranslator {
object DefaultTypeAttributesTranslator : TypeAttributesTranslator {
override fun toAnnotations(attributes: TypeAttributes): Annotations {
val compilerAnnotations = CompilerTypeAttributes.compilerAttributeByFqName.mapNotNull { (fqName, attribute) ->
val annotationClass = DefaultBuiltIns.Instance.getBuiltInClassByFqName(fqName)
if (attribute in attributes)
AnnotationDescriptorImpl(annotationClass.defaultType, mapOf(), annotationClass.source)
else null
}
return Annotations.create(compilerAnnotations + attributes.customAnnotations)
return attributes.customAnnotations
}
override fun toAttributes(annotations: Annotations): TypeAttributes {
val customAnnotations = mutableListOf<AnnotationDescriptor>()
val compilerAttributes = mutableListOf<TypeAttribute<*>>()
annotations.forEach { annotation ->
val compilerAttribute = CompilerTypeAttributes.compilerAttributeByFqName[annotation.fqName]
if (compilerAttribute != null)
compilerAttributes.add(compilerAttribute)
else
customAnnotations.add(annotation)
}
return TypeAttributes.create(
compilerAttributes + CustomAnnotationTypeAttribute(customAnnotations)
)
return TypeAttributes.create(listOf(CustomAnnotationTypeAttribute(annotations)))
}
}
@@ -533,7 +533,12 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
}
@Suppress("UNCHECKED_CAST")
return KotlinTypeFactory.simpleType(resultingAnnotations, constructor, arguments as List<TypeProjection>, nullable)
return KotlinTypeFactory.simpleType(
DefaultTypeAttributesTranslator.toAttributes(resultingAnnotations),
constructor,
arguments as List<TypeProjection>,
nullable
)
}
override fun createTypeArgument(type: KotlinTypeMarker, variance: TypeVariance): TypeArgumentMarker {
@@ -634,6 +639,22 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
return IntegerLiteralTypeConstructor.findCommonSuperType(explicitSupertypes)
}
override fun unionTypeAttributes(types: List<KotlinTypeMarker>): List<AnnotationMarker> {
@Suppress("UNCHECKED_CAST")
types as List<KotlinType>
return types.map { it.unwrap().attributes }.reduce { x, y -> x.union(y) }.toList()
}
override fun KotlinTypeMarker.replaceTypeAttributes(newAttributes: List<AnnotationMarker>): KotlinTypeMarker {
require(this is KotlinType)
val typeAttributes = newAttributes.filterIsInstance<TypeAttribute<*>>()
require(typeAttributes.size == newAttributes.size)
if (newAttributes.isEmpty()) return this
return this.unwrap().replaceAttributes(
TypeAttributes.create(typeAttributes)
)
}
override fun TypeConstructorMarker.isError(): Boolean {
require(this is TypeConstructor, this::errorMessage)
return ErrorUtils.isError(declarationDescriptor)
@@ -649,9 +670,9 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
return KotlinBuiltIns.isPrimitiveType(this)
}
override fun KotlinTypeMarker.getAnnotations(): List<AnnotationMarker> {
override fun KotlinTypeMarker.getAttributes(): List<AnnotationMarker> {
require(this is KotlinType, this::errorMessage)
return this.annotations.toList()
return this.attributes.toList()
}
override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? {