Add initial type attributes infra

This commit is contained in:
Irene Dea
2021-10-08 17:05:11 -07:00
committed by Dmitriy Novozhilov
parent 62bde2d686
commit fad3c1f2f6
23 changed files with 545 additions and 30 deletions
@@ -651,6 +651,7 @@ class KotlinCoreEnvironment private constructor(
CandidateInterceptor.registerExtensionPoint(project)
DescriptorSerializerPlugin.registerExtensionPoint(project)
FirExtensionRegistrarAdapter.registerExtensionPoint(project)
TypeAttributeTranslators.registerExtensionPoint(project)
}
internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) {
@@ -0,0 +1,37 @@
/*
* 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.extensions
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.types.*
interface TypeAttributeTranslatorExtension : TypeAttributesTranslator
class TypeAttributeTranslators(project: Project) {
val translators: List<TypeAttributesTranslator> =
getInstances(project) + DefaultTypeAttributesTranslator
fun toAttributes(annotations: Annotations): TypeAttributes {
val translated = translators.mapNotNull { translator ->
translator.toAttributes(annotations)
}.flatten()
return TypeAttributes.create(translated)
}
fun toAnnotations(attributes: TypeAttributes): Annotations {
val translated = translators.mapNotNull { translator ->
translator.toAnnotations(attributes)
}.flatten()
return Annotations.create(translated)
}
companion object :
ProjectExtensionDescriptor<TypeAttributeTranslatorExtension>(
"org.jetbrains.kotlin.extensions.typeAttribute",
TypeAttributeTranslatorExtension::class.java
)
}
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorImpl
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.extensions.TypeAttributeTranslators
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
@@ -69,7 +70,8 @@ class TypeResolver(
private val identifierChecker: IdentifierChecker,
private val platformToKotlinClassMapper: PlatformToKotlinClassMapper,
private val languageVersionSettings: LanguageVersionSettings,
private val upperBoundChecker: UpperBoundChecker
private val upperBoundChecker: UpperBoundChecker,
private val typeAttributeTranslators: TypeAttributeTranslators
) {
private val isNonParenthesizedAnnotationsOnFunctionalTypesEnabled =
languageVersionSettings.getFeatureSupport(LanguageFeature.NonParenthesizedAnnotationsOnFunctionalTypes) == LanguageFeature.State.ENABLED
@@ -521,7 +523,7 @@ class TypeResolver(
ErrorUtils.createErrorType("?")
else
KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
annotations,
typeAttributeTranslators.toAttributes(annotations),
typeParameter.typeConstructor,
listOf(),
false,
@@ -602,7 +604,8 @@ class TypeResolver(
" but ${collectedArgumentAsTypeProjections.size} instead of ${parameters.size} found in ${element.text}"
}
val resultingType = KotlinTypeFactory.simpleNotNullType(annotations, classDescriptor, arguments)
val resultingType =
KotlinTypeFactory.simpleNotNullType(typeAttributeTranslators.toAttributes(annotations), classDescriptor, arguments)
// We create flexible types by convention here
// This is not intended to be used in normal users' environments, only for tests and debugger etc
@@ -699,7 +702,12 @@ class TypeResolver(
}
return if (c.abbreviated) {
val abbreviatedType = KotlinTypeFactory.simpleType(annotations, descriptor.typeConstructor, arguments, false)
val abbreviatedType = KotlinTypeFactory.simpleType(
typeAttributeTranslators.toAttributes(annotations),
descriptor.typeConstructor,
arguments,
false
)
type(abbreviatedType)
} else {
val typeAliasExpansion = TypeAliasExpansion.create(null, descriptor, arguments)
@@ -56,6 +56,8 @@ class TypeTemplate(
) {
override fun replaceAnnotations(newAnnotations: Annotations) = this
override fun replaceAttributes(newAttributes: TypeAttributes) = this
override fun makeNullableAsSpecified(newNullability: Boolean) = TypeTemplate(typeVariable, builderInferenceData, newNullability)
override val delegate: SimpleType
@@ -57,6 +57,10 @@ class RawTypeImpl private constructor(lowerBound: SimpleType, upperBound: Simple
override fun replaceAnnotations(newAnnotations: Annotations) =
RawTypeImpl(lowerBound.replaceAnnotations(newAnnotations), upperBound.replaceAnnotations(newAnnotations))
override fun replaceAttributes(newAttributes: TypeAttributes) =
RawTypeImpl(lowerBound.replaceAttributes(newAttributes), upperBound.replaceAttributes(newAttributes))
override fun makeNullableAsSpecified(newNullability: Boolean) =
RawTypeImpl(lowerBound.makeNullableAsSpecified(newNullability), upperBound.makeNullableAsSpecified(newNullability))
@@ -253,6 +253,7 @@ internal class NotNullTypeParameterImpl(override val delegate: SimpleType) : Not
}
override fun replaceAnnotations(newAnnotations: Annotations) = NotNullTypeParameterImpl(delegate.replaceAnnotations(newAnnotations))
override fun replaceAttributes(newAttributes: TypeAttributes) = NotNullTypeParameterImpl(delegate.replaceAttributes(newAttributes))
override fun makeNullableAsSpecified(newNullability: Boolean) =
if (newNullability) delegate.makeNullableAsSpecified(true) else this
@@ -75,7 +75,7 @@ class CapturedType(
val typeProjection: TypeProjection,
override val constructor: CapturedTypeConstructor = CapturedTypeConstructorImpl(typeProjection),
override val isMarkedNullable: Boolean = false,
override val annotations: Annotations = Annotations.EMPTY
override val attributes: TypeAttributes = TypeAttributes.Empty
) : SimpleType(), SubtypingRepresentatives, CapturedTypeMarker {
override val arguments: List<TypeProjection>
get() = listOf()
@@ -100,15 +100,18 @@ class CapturedType(
override fun makeNullableAsSpecified(newNullability: Boolean): CapturedType {
if (newNullability == isMarkedNullable) return this
return CapturedType(typeProjection, constructor, newNullability, annotations)
return CapturedType(typeProjection, constructor, newNullability, attributes)
}
override fun replaceAnnotations(newAnnotations: Annotations): CapturedType =
CapturedType(typeProjection, constructor, isMarkedNullable, newAnnotations)
CapturedType(typeProjection, constructor, isMarkedNullable, newAnnotations.toAttributes())
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType =
CapturedType(typeProjection, constructor, isMarkedNullable, newAttributes)
@TypeRefinement
override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) =
CapturedType(typeProjection.refine(kotlinTypeRefiner), constructor, isMarkedNullable, annotations)
CapturedType(typeProjection.refine(kotlinTypeRefiner), constructor, isMarkedNullable, attributes)
}
fun createCapturedType(typeProjection: TypeProjection): KotlinType = CapturedType(typeProjection)
@@ -0,0 +1,112 @@
/*
* 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
@@ -0,0 +1,34 @@
/*
* 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.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import kotlin.reflect.KClass
class CustomAnnotationTypeAttribute(val annotations: Annotations) : TypeAttribute<CustomAnnotationTypeAttribute>() {
constructor(annotations: List<AnnotationDescriptor>) : this(Annotations.create(annotations))
override fun union(other: CustomAnnotationTypeAttribute?): CustomAnnotationTypeAttribute? = null
override fun intersect(other: CustomAnnotationTypeAttribute?): CustomAnnotationTypeAttribute? = null
override fun add(other: CustomAnnotationTypeAttribute?): CustomAnnotationTypeAttribute {
if (other == null) return this
return CustomAnnotationTypeAttribute(Annotations.create(annotations + other.annotations))
}
override fun isSubtypeOf(other: CustomAnnotationTypeAttribute?): Boolean = true
override val key: KClass<out CustomAnnotationTypeAttribute>
get() = CustomAnnotationTypeAttribute::class
}
val TypeAttributes.custom: CustomAnnotationTypeAttribute? by TypeAttributes.attributeAccessor<CustomAnnotationTypeAttribute>()
val TypeAttributes.customAnnotations: Annotations get() = custom?.annotations ?: Annotations.EMPTY
@@ -30,11 +30,16 @@ open class ErrorType @JvmOverloads internal constructor(
override val annotations: Annotations
get() = Annotations.EMPTY
override val attributes: TypeAttributes
get() = TypeAttributes.Empty
override fun toString(): String =
constructor.toString() + if (arguments.isEmpty()) "" else arguments.joinToString(", ", "<", ">", -1, "...", null)
override fun replaceAnnotations(newAnnotations: Annotations): SimpleType = this
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType = this
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType =
ErrorType(constructor, memberScope, arguments, newNullability)
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.types.model.FlexibleTypeMarker
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
import org.jetbrains.kotlin.types.model.TypeArgumentListMarker
import org.jetbrains.kotlin.types.typeUtil.builtIns
/**
* [KotlinType] has only two direct subclasses: [WrappedType] and [UnwrappedType].
@@ -51,6 +52,9 @@ sealed class KotlinType : Annotated, KotlinTypeMarker {
abstract val arguments: List<TypeProjection>
abstract val isMarkedNullable: Boolean
abstract val memberScope: MemberScope
abstract val attributes: TypeAttributes
override val annotations: Annotations
get() = attributes.toAnnotations()
abstract fun unwrap(): UnwrappedType
@@ -74,7 +78,8 @@ sealed class KotlinType : Annotated, KotlinTypeMarker {
abstract fun refine(kotlinTypeRefiner: KotlinTypeRefiner): KotlinType
@TypeRefinement
open val hasNotTrivialRefinementFactory: Boolean get() = false
open val hasNotTrivialRefinementFactory: Boolean
get() = false
/* '0' means "hashCode wasn't computed"
@@ -128,6 +133,7 @@ abstract class WrappedType : KotlinType() {
override val arguments: List<TypeProjection> get() = delegate.arguments
override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable
override val memberScope: MemberScope get() = delegate.memberScope
override val attributes: TypeAttributes get() = delegate.attributes
final override fun unwrap(): UnwrappedType {
var result = delegate
@@ -159,6 +165,7 @@ abstract class WrappedType : KotlinType() {
*/
sealed class UnwrappedType : KotlinType() {
abstract fun replaceAnnotations(newAnnotations: Annotations): UnwrappedType
abstract fun replaceAttributes(newAttributes: TypeAttributes): UnwrappedType
abstract fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType
final override fun unwrap(): UnwrappedType = this
@@ -174,6 +181,7 @@ sealed class UnwrappedType : KotlinType() {
*/
abstract class SimpleType : UnwrappedType(), SimpleTypeMarker, TypeArgumentListMarker {
abstract override fun replaceAnnotations(newAnnotations: Annotations): SimpleType
abstract override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType
abstract override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType
@TypeRefinement
@@ -212,6 +220,7 @@ abstract class FlexibleType(val lowerBound: SimpleType, val upperBound: SimpleTy
override val arguments: List<TypeProjection> get() = delegate.arguments
override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable
override val memberScope: MemberScope get() = delegate.memberScope
override val attributes: TypeAttributes get() = delegate.attributes
override fun toString(): String = DescriptorRenderer.DEBUG_TEXT.renderType(this)
@@ -90,6 +90,31 @@ object KotlinTypeFactory {
}
}
@JvmStatic
@JvmOverloads
@OptIn(TypeRefinement::class)
fun simpleType(
attributes: TypeAttributes,
constructor: TypeConstructor,
arguments: List<TypeProjection>,
nullable: Boolean,
kotlinTypeRefiner: KotlinTypeRefiner? = null
): SimpleType {
if (attributes.isEmpty() && arguments.isEmpty() && !nullable && constructor.declarationDescriptor != null) {
return constructor.declarationDescriptor!!.defaultType
}
return simpleTypeWithNonTrivialMemberScope(
attributes, constructor, arguments, nullable,
computeMemberScope(constructor, arguments, kotlinTypeRefiner)
) f@{ refiner ->
val expandedTypeOrRefinedConstructor = refineConstructor(constructor, refiner, arguments) ?: return@f null
expandedTypeOrRefinedConstructor.expandedType?.let { return@f it }
simpleType(attributes, expandedTypeOrRefinedConstructor.refinedConstructor!!, arguments, nullable, refiner)
}
}
@JvmStatic
fun TypeAliasDescriptor.computeExpandedType(arguments: List<TypeProjection>): SimpleType {
return TypeAliasExpander(TypeAliasExpansionReportStrategy.DO_NOTHING, false).expand(
@@ -140,7 +165,34 @@ object KotlinTypeFactory {
if (annotations.isEmpty())
it
else
AnnotatedSimpleType(it, annotations)
SimpleTypeWithAttributes(it, annotations.toAttributes())
}
@JvmStatic
@OptIn(TypeRefinement::class)
fun simpleTypeWithNonTrivialMemberScope(
attributes: TypeAttributes,
constructor: TypeConstructor,
arguments: List<TypeProjection>,
nullable: Boolean,
memberScope: MemberScope
): SimpleType =
SimpleTypeImpl(constructor, arguments, nullable, memberScope) { kotlinTypeRefiner ->
val expandedTypeOrRefinedConstructor = refineConstructor(constructor, kotlinTypeRefiner, arguments) ?: return@SimpleTypeImpl null
expandedTypeOrRefinedConstructor.expandedType?.let { return@SimpleTypeImpl it }
simpleTypeWithNonTrivialMemberScope(
attributes,
expandedTypeOrRefinedConstructor.refinedConstructor!!,
arguments,
nullable,
memberScope
)
}.let {
if (attributes.isEmpty())
it
else
SimpleTypeWithAttributes(it, attributes)
}
@JvmStatic
@@ -157,7 +209,24 @@ object KotlinTypeFactory {
if (annotations.isEmpty())
it
else
AnnotatedSimpleType(it, annotations)
SimpleTypeWithAttributes(it, annotations.toAttributes())
}
@JvmStatic
fun simpleTypeWithNonTrivialMemberScope(
attributes: TypeAttributes,
constructor: TypeConstructor,
arguments: List<TypeProjection>,
nullable: Boolean,
memberScope: MemberScope,
refinedTypeFactory: RefinedTypeFactory
): SimpleType =
SimpleTypeImpl(constructor, arguments, nullable, memberScope, refinedTypeFactory)
.let {
if (attributes.isEmpty())
it
else
SimpleTypeWithAttributes(it, attributes)
}
@JvmStatic
@@ -167,6 +236,13 @@ object KotlinTypeFactory {
arguments: List<TypeProjection>
): SimpleType = simpleType(annotations, descriptor.typeConstructor, arguments, nullable = false)
@JvmStatic
fun simpleNotNullType(
attributes: TypeAttributes,
descriptor: ClassDescriptor,
arguments: List<TypeProjection>
): SimpleType = simpleType(attributes, descriptor.typeConstructor, arguments, nullable = false)
@JvmStatic
fun simpleType(
baseType: SimpleType,
@@ -207,12 +283,18 @@ private class SimpleTypeImpl(
override val hasNotTrivialRefinementFactory: Boolean get() = true
override val annotations: Annotations get() = Annotations.EMPTY
override val attributes: TypeAttributes get() = TypeAttributes.Empty
override fun replaceAttributes(newAttributes: TypeAttributes) =
if (newAttributes.isEmpty())
this
else SimpleTypeWithAttributes(this, newAttributes)
override fun replaceAnnotations(newAnnotations: Annotations) =
if (newAnnotations.isEmpty())
this
else
AnnotatedSimpleType(this, newAnnotations)
SimpleTypeWithAttributes(this, attributes.replaceAnnotations(newAnnotations))
override fun makeNullableAsSpecified(newNullability: Boolean) = when {
newNullability == isMarkedNullable -> this
@@ -243,6 +325,9 @@ class SupposititiousSimpleType(private val realType: SimpleType, val overwritten
override fun replaceAnnotations(newAnnotations: Annotations): SimpleType =
maybeWrap(realType.replaceAnnotations(newAnnotations))
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType =
maybeWrap(realType.replaceAttributes(newAttributes))
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType =
maybeWrap(realType.makeNullableAsSpecified(newNullability))
@@ -255,12 +340,19 @@ class SupposititiousSimpleType(private val realType: SimpleType, val overwritten
override val isMarkedNullable: Boolean = realType.isMarkedNullable
override val memberScope: MemberScope = realType.memberScope
override val annotations: Annotations = realType.annotations
override val attributes: TypeAttributes get() = realType.attributes
}
abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : DelegatingSimpleType() {
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType =
if (newAttributes !== attributes)
SimpleTypeWithAttributes(this, newAttributes)
else
this
override fun replaceAnnotations(newAnnotations: Annotations) =
if (newAnnotations !== annotations)
AnnotatedSimpleType(this, newAnnotations)
SimpleTypeWithAttributes(this, attributes.replaceAnnotations(newAnnotations))
else
this
@@ -270,12 +362,12 @@ abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : Del
}
}
private class AnnotatedSimpleType(
private class SimpleTypeWithAttributes(
delegate: SimpleType,
override val annotations: Annotations
override val attributes: TypeAttributes
) : DelegatingSimpleTypeImpl(delegate) {
@TypeRefinement
override fun replaceDelegate(delegate: SimpleType) = AnnotatedSimpleType(delegate, annotations)
override fun replaceDelegate(delegate: SimpleType) = SimpleTypeWithAttributes(delegate, attributes)
}
private class NullableSimpleType(delegate: SimpleType) : DelegatingSimpleTypeImpl(delegate) {
@@ -35,6 +35,7 @@ abstract class DelegatingSimpleType : SimpleType() {
override val arguments: List<TypeProjection> get() = delegate.arguments
override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable
override val memberScope: MemberScope get() = delegate.memberScope
override val attributes: TypeAttributes get() = delegate.attributes
@TypeRefinement
abstract fun replaceDelegate(delegate: SimpleType): DelegatingSimpleType
@@ -47,11 +48,14 @@ abstract class DelegatingSimpleType : SimpleType() {
class AbbreviatedType(override val delegate: SimpleType, val abbreviation: SimpleType) : DelegatingSimpleType() {
val expandedType: SimpleType get() = delegate
override fun replaceAnnotations(newAnnotations: Annotations)
= AbbreviatedType(delegate.replaceAnnotations(newAnnotations), abbreviation)
override fun replaceAnnotations(newAnnotations: Annotations) =
AbbreviatedType(delegate.replaceAnnotations(newAnnotations), abbreviation)
override fun makeNullableAsSpecified(newNullability: Boolean)
= AbbreviatedType(delegate.makeNullableAsSpecified(newNullability), abbreviation.makeNullableAsSpecified(newNullability))
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType =
AbbreviatedType(delegate.replaceAttributes(newAttributes), abbreviation)
override fun makeNullableAsSpecified(newNullability: Boolean) =
AbbreviatedType(delegate.makeNullableAsSpecified(newNullability), abbreviation.makeNullableAsSpecified(newNullability))
@TypeRefinement
override fun replaceDelegate(delegate: SimpleType) = AbbreviatedType(delegate, abbreviation)
@@ -171,6 +175,9 @@ class DefinitelyNotNullType private constructor(
override fun replaceAnnotations(newAnnotations: Annotations): DefinitelyNotNullType =
DefinitelyNotNullType(delegate.replaceAnnotations(newAnnotations), useCorrectedNullabilityForTypeParameters)
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType =
DefinitelyNotNullType(delegate.replaceAttributes(newAttributes), useCorrectedNullabilityForTypeParameters)
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType =
if (newNullability) delegate.makeNullableAsSpecified(newNullability) else this
@@ -189,7 +196,7 @@ fun SimpleType.makeSimpleTypeDefinitelyNotNullOrNotNull(useCorrectedNullabilityF
?: makeNullableAsSpecified(false)
fun NewCapturedType.withNotNullProjection() =
NewCapturedType(captureStatus, constructor, lowerType, annotations, isMarkedNullable, isProjectionNotNull = true)
NewCapturedType(captureStatus, constructor, lowerType, attributes, isMarkedNullable, isProjectionNotNull = true)
fun UnwrappedType.makeDefinitelyNotNullOrNotNull(useCorrectedNullabilityForTypeParameters: Boolean = false): UnwrappedType =
DefinitelyNotNullType.makeDefinitelyNotNull(this, useCorrectedNullabilityForTypeParameters)
@@ -61,8 +61,13 @@ abstract class AbstractStubType(val originalTypeVariable: TypeConstructor, overr
override val annotations: Annotations
get() = Annotations.EMPTY
override val attributes: TypeAttributes
get() = TypeAttributes.Empty
override fun replaceAnnotations(newAnnotations: Annotations): SimpleType = this
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType = this
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType {
return if (newNullability == isMarkedNullable) this else materialize(newNullability)
}
@@ -0,0 +1,129 @@
/*
* 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.descriptors.annotations.Annotations
import org.jetbrains.kotlin.types.model.AnnotationMarker
import org.jetbrains.kotlin.util.AttributeArrayOwner
import org.jetbrains.kotlin.util.TypeRegistry
import org.jetbrains.kotlin.utils.addIfNotNull
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
abstract class TypeAttribute<T : TypeAttribute<T>> : AnnotationMarker {
abstract fun union(other: @UnsafeVariance T?): T?
abstract fun intersect(other: @UnsafeVariance T?): T?
/*
* This function is used to decide how multiple attributes should be united in presence of typealiases:
* typealias B = @SomeAttribute(1) A
* typealias C = @SomeAttribute(2) B
*
* For determining attribute value of expanded type of C we should add @SomeAttribute(2) to @SomeAttribute(1)
*
* This function must be symmetrical: a.add(b) == b.add(a)
*/
abstract fun add(other: @UnsafeVariance T?): T
abstract fun isSubtypeOf(other: @UnsafeVariance T?): Boolean
abstract val key: KClass<out T>
}
class TypeAttributes private constructor(attributes: List<TypeAttribute<*>>) : AttributeArrayOwner<TypeAttribute<*>, TypeAttribute<*>>(),
Iterable<TypeAttribute<*>> {
companion object : TypeRegistry<TypeAttribute<*>, TypeAttribute<*>>() {
inline fun <reified T : TypeAttribute<T>> attributeAccessor(): ReadOnlyProperty<TypeAttributes, T?> {
@Suppress("UNCHECKED_CAST")
return generateNullableAccessor<TypeAttribute<*>, T>(T::class) as ReadOnlyProperty<TypeAttributes, T?>
}
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)
fun create(attributes: List<TypeAttribute<*>>): TypeAttributes {
return if (attributes.isEmpty()) {
Empty
} else {
TypeAttributes(attributes)
}
}
}
private constructor(attribute: TypeAttribute<*>) : this(listOf(attribute))
init {
for (attribute in attributes) {
registerComponent(attribute.key, attribute)
}
}
fun union(other: TypeAttributes): TypeAttributes {
return perform(other) { this.union(it) }
}
fun intersect(other: TypeAttributes): TypeAttributes {
return perform(other) { this.intersect(it) }
}
fun add(other: TypeAttributes): TypeAttributes {
return perform(other) { this.add(it) }
}
operator fun contains(attribute: TypeAttribute<*>): Boolean {
val index = getId(attribute.key)
return arrayMap[index] != null
}
@OptIn(ExperimentalStdlibApi::class)
operator fun plus(attribute: TypeAttribute<*>): TypeAttributes {
if (attribute in this) return this
if (isEmpty()) return predefinedAttributes[attribute] ?: TypeAttributes(attribute)
val newAttributes = buildList {
addAll(this)
add(attribute)
}
return TypeAttributes(newAttributes)
}
fun remove(attribute: TypeAttribute<*>): TypeAttributes {
if (isEmpty()) return this
val attributes = arrayMap.filter { it != attribute }
if (attributes.size == arrayMap.size) return this
return create(attributes)
}
private inline fun perform(other: TypeAttributes, op: TypeAttribute<*>.(TypeAttribute<*>?) -> TypeAttribute<*>?): TypeAttributes {
if (this.isEmpty() && other.isEmpty()) return this
val attributes = mutableListOf<TypeAttribute<*>>()
for (index in indices) {
val a = arrayMap[index]
val b = other.arrayMap[index]
val res = if (a == null) b?.op(a) else a.op(b)
attributes.addIfNotNull(res)
}
return create(attributes)
}
override val typeRegistry: TypeRegistry<TypeAttribute<*>, TypeAttribute<*>>
get() = Companion
}
fun TypeAttributes.toAnnotations(): Annotations =
DefaultTypeAttributesTranslator.toAnnotations(this)
fun Annotations.toAttributes(): TypeAttributes = DefaultTypeAttributesTranslator.toAttributes(this)
fun TypeAttributes.replaceAnnotations(newAnnotations: Annotations): TypeAttributes {
val withoutCustom = (custom?.let { this.remove(it) } ?: this)
return withoutCustom.add(newAnnotations.toAttributes())
}
@@ -0,0 +1,44 @@
/*
* 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.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 {
fun toAttributes(annotations: Annotations): TypeAttributes
fun toAnnotations(attributes: TypeAttributes): Annotations?
}
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)
}
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)
)
}
}
@@ -52,6 +52,12 @@ public class TypeUtils {
throw new IllegalStateException(name);
}
@NotNull
@Override
public SimpleType replaceAttributes(@NotNull TypeAttributes newAttributes) {
throw new IllegalStateException(name);
}
@NotNull
@Override
public SimpleType makeNullableAsSpecified(boolean newNullability) {
@@ -37,6 +37,9 @@ class SimpleTypeWithEnhancement(
override fun replaceAnnotations(newAnnotations: Annotations): SimpleType =
origin.replaceAnnotations(newAnnotations).wrapEnhancement(enhancement) as SimpleType
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType =
origin.replaceAttributes(newAttributes).wrapEnhancement(enhancement) as SimpleType
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType = origin.makeNullableAsSpecified(newNullability)
.wrapEnhancement(enhancement.unwrap().makeNullableAsSpecified(newNullability)) as SimpleType
@@ -64,6 +67,9 @@ class FlexibleTypeWithEnhancement(
override fun replaceAnnotations(newAnnotations: Annotations): UnwrappedType =
origin.replaceAnnotations(newAnnotations).wrapEnhancement(enhancement)
override fun replaceAttributes(newAttributes: TypeAttributes): UnwrappedType =
origin.replaceAttributes(newAttributes).wrapEnhancement(enhancement)
override fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType =
origin.makeNullableAsSpecified(newNullability).wrapEnhancement(enhancement.unwrap().makeNullableAsSpecified(newNullability))
@@ -486,7 +486,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
override fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker {
require(this is NewCapturedType, this::errorMessage)
return NewCapturedType(captureStatus, constructor, lowerType, annotations, isMarkedNullable, isProjectionNotNull = true)
return NewCapturedType(captureStatus, constructor, lowerType, attributes, isMarkedNullable, isProjectionNotNull = true)
}
override fun CapturedTypeMarker.isProjectionNotNull(): Boolean {
@@ -28,7 +28,7 @@ abstract class KotlinTypePreparator : AbstractTypePreparator() {
}
return NewCapturedType(
CaptureStatus.FOR_SUBTYPING, constructor.newTypeConstructor!!,
lowerType, type.annotations, type.isMarkedNullable
lowerType, type.attributes, type.isMarkedNullable
)
}
@@ -199,7 +199,7 @@ class NewCapturedType(
val captureStatus: CaptureStatus,
override val constructor: NewCapturedTypeConstructor,
val lowerType: UnwrappedType?, // todo check lower type for nullable captured types
override val annotations: Annotations = Annotations.EMPTY,
override val attributes: TypeAttributes = TypeAttributes.Empty,
override val isMarkedNullable: Boolean = false,
val isProjectionNotNull: Boolean = false
) : SimpleType(), CapturedTypeMarker {
@@ -213,10 +213,13 @@ class NewCapturedType(
get() = ErrorUtils.createErrorScope("No member resolution should be done on captured type!", true)
override fun replaceAnnotations(newAnnotations: Annotations) =
NewCapturedType(captureStatus, constructor, lowerType, newAnnotations, isMarkedNullable)
NewCapturedType(captureStatus, constructor, lowerType, newAnnotations.toAttributes(), isMarkedNullable)
override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType =
NewCapturedType(captureStatus, constructor, lowerType, newAttributes, isMarkedNullable)
override fun makeNullableAsSpecified(newNullability: Boolean) =
NewCapturedType(captureStatus, constructor, lowerType, annotations, newNullability)
NewCapturedType(captureStatus, constructor, lowerType, attributes, newNullability)
@TypeRefinement
override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) =
@@ -224,7 +227,7 @@ class NewCapturedType(
captureStatus,
constructor.refine(kotlinTypeRefiner),
lowerType?.let { kotlinTypeRefiner.refineType(it).unwrap() },
annotations,
attributes,
isMarkedNullable
)
}
@@ -39,11 +39,11 @@ class DynamicTypesAllowed : DynamicTypesSettings() {
fun KotlinType.isDynamic(): Boolean = unwrap() is DynamicType
fun createDynamicType(builtIns: KotlinBuiltIns) = DynamicType(builtIns, Annotations.EMPTY)
fun createDynamicType(builtIns: KotlinBuiltIns) = DynamicType(builtIns, TypeAttributes.Empty)
class DynamicType(
builtIns: KotlinBuiltIns,
override val annotations: Annotations
override val attributes: TypeAttributes
) : FlexibleType(builtIns.nothingType, builtIns.nullableAnyType), DynamicTypeMarker {
override val delegate: SimpleType get() = upperBound
@@ -52,7 +52,11 @@ class DynamicType(
override val isMarkedNullable: Boolean get() = false
override fun replaceAnnotations(newAnnotations: Annotations): DynamicType = DynamicType(delegate.builtIns, newAnnotations)
override fun replaceAnnotations(newAnnotations: Annotations): DynamicType =
DynamicType(delegate.builtIns, attributes.replaceAnnotations(newAnnotations))
override fun replaceAttributes(newAttributes: TypeAttributes): DynamicType =
DynamicType(delegate.builtIns, newAttributes)
override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String = "dynamic"
@@ -128,6 +128,9 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : Flexibl
override fun replaceAnnotations(newAnnotations: Annotations): UnwrappedType =
KotlinTypeFactory.flexibleType(lowerBound.replaceAnnotations(newAnnotations), upperBound.replaceAnnotations(newAnnotations))
override fun replaceAttributes(newAttributes: TypeAttributes): UnwrappedType =
KotlinTypeFactory.flexibleType(lowerBound.replaceAttributes(newAttributes), upperBound.replaceAttributes(newAttributes))
override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String {
if (options.debugMode) {
return "(${renderer.renderType(lowerBound)}..${renderer.renderType(upperBound)})"