[FIR] Support methods of cone type contexts with annotation markers
This commit is contained in:
@@ -82,6 +82,17 @@ object CompilerConeAttributes {
|
|||||||
|
|
||||||
override fun toString(): String = "@UnsafeVariance"
|
override fun toString(): String = "@UnsafeVariance"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val compilerAttributeByClassId: Map<ClassId, ConeAttribute<*>> = 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,
|
||||||
|
FlexibleNullability.ANNOTATION_CLASS_ID to FlexibleNullability,
|
||||||
|
UnsafeVariance.ANNOTATION_CLASS_ID to UnsafeVariance
|
||||||
|
)
|
||||||
|
|
||||||
|
val compilerAttributeByFqName: Map<FqName, ConeAttribute<*>> = compilerAttributeByClassId.mapKeys { it.key.asSingleFqName() }
|
||||||
}
|
}
|
||||||
|
|
||||||
val ConeAttributes.exact: CompilerConeAttributes.Exact? by ConeAttributes.attributeAccessor<CompilerConeAttributes.Exact>()
|
val ConeAttributes.exact: CompilerConeAttributes.Exact? by ConeAttributes.attributeAccessor<CompilerConeAttributes.Exact>()
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import org.jetbrains.kotlin.fir.utils.AttributeArrayOwner
|
|||||||
import org.jetbrains.kotlin.fir.utils.Protected
|
import org.jetbrains.kotlin.fir.utils.Protected
|
||||||
import org.jetbrains.kotlin.fir.utils.TypeRegistry
|
import org.jetbrains.kotlin.fir.utils.TypeRegistry
|
||||||
import org.jetbrains.kotlin.fir.utils.isEmpty
|
import org.jetbrains.kotlin.fir.utils.isEmpty
|
||||||
|
import org.jetbrains.kotlin.types.model.AnnotationMarker
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
abstract class ConeAttribute<T : ConeAttribute<T>> {
|
abstract class ConeAttribute<T : ConeAttribute<T>> : AnnotationMarker {
|
||||||
abstract fun union(other: @UnsafeVariance T?): T?
|
abstract fun union(other: @UnsafeVariance T?): T?
|
||||||
abstract fun intersect(other: @UnsafeVariance T?): T?
|
abstract fun intersect(other: @UnsafeVariance T?): T?
|
||||||
abstract fun isSubtypeOf(other: @UnsafeVariance T?): Boolean
|
abstract fun isSubtypeOf(other: @UnsafeVariance T?): Boolean
|
||||||
@@ -69,6 +70,13 @@ class ConeAttributes private constructor(attributes: List<ConeAttribute<*>>) : A
|
|||||||
return perform(other) { this.intersect(it) }
|
return perform(other) { this.intersect(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun remove(attribute: ConeAttribute<*>): ConeAttributes {
|
||||||
|
if (arrayMap.isEmpty()) return this
|
||||||
|
val attributes = arrayMap.filter { it != attribute }
|
||||||
|
if (attributes.size == arrayMap.size) return this
|
||||||
|
return create(attributes)
|
||||||
|
}
|
||||||
|
|
||||||
override fun iterator(): Iterator<ConeAttribute<*>> {
|
override fun iterator(): Iterator<ConeAttribute<*>> {
|
||||||
return arrayMap.iterator()
|
return arrayMap.iterator()
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
|||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
@@ -45,16 +46,15 @@ fun ConeKotlinType.isKMutableProperty(session: FirSession): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeKotlinType.functionClassKind(session: FirSession): FunctionClassKind? {
|
private fun ConeKotlinType.functionClassKind(session: FirSession): FunctionClassKind? {
|
||||||
val classId = classId(session) ?: return null
|
return classId(session)?.toFunctionClassKind()
|
||||||
return FunctionClassKind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString())
|
}
|
||||||
|
|
||||||
|
private fun ClassId.toFunctionClassKind(): FunctionClassKind? {
|
||||||
|
return FunctionClassKind.byClassNamePrefix(packageFqName, relativeClassName.asString())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConeKotlinType.isBuiltinFunctionalType(session: FirSession): Boolean {
|
fun ConeKotlinType.isBuiltinFunctionalType(session: FirSession): Boolean {
|
||||||
val kind = functionClassKind(session) ?: return false
|
return functionClassKind(session) != null
|
||||||
return kind == FunctionClassKind.Function ||
|
|
||||||
kind == FunctionClassKind.KFunction ||
|
|
||||||
kind == FunctionClassKind.SuspendFunction ||
|
|
||||||
kind == FunctionClassKind.KSuspendFunction
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConeKotlinType.isFunctionalType(session: FirSession): Boolean {
|
fun ConeKotlinType.isFunctionalType(session: FirSession): Boolean {
|
||||||
@@ -62,6 +62,10 @@ fun ConeKotlinType.isFunctionalType(session: FirSession): Boolean {
|
|||||||
return kind == FunctionClassKind.Function
|
return kind == FunctionClassKind.Function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ConeClassLikeLookupTag.isBuiltinFunctionalType(): Boolean {
|
||||||
|
return classId.toFunctionClassKind() != null
|
||||||
|
}
|
||||||
|
|
||||||
fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean {
|
fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean {
|
||||||
val kind = functionClassKind(session) ?: return false
|
val kind = functionClassKind(session) ?: return false
|
||||||
return kind == FunctionClassKind.SuspendFunction ||
|
return kind == FunctionClassKind.SuspendFunction ||
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.isPrimitiveNumberOrUnsignedNumberType
|
|||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.NoSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.calls.NoSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.isFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
|
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
@@ -59,11 +60,23 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
arguments: List<TypeArgumentMarker>,
|
arguments: List<TypeArgumentMarker>,
|
||||||
nullable: Boolean,
|
nullable: Boolean,
|
||||||
isExtensionFunction: Boolean,
|
isExtensionFunction: Boolean,
|
||||||
annotations: List<AnnotationMarker>? // TODO: process annotations
|
annotations: List<AnnotationMarker>?
|
||||||
): SimpleTypeMarker {
|
): SimpleTypeMarker {
|
||||||
val attributes = if (isExtensionFunction) // TODO: assert correct type constructor
|
val attributesList = annotations?.filterIsInstanceTo<ConeAttribute<*>, MutableList<ConeAttribute<*>>>(mutableListOf())
|
||||||
ConeAttributes.WithExtensionFunctionType
|
val attributes: ConeAttributes = if (isExtensionFunction) {
|
||||||
else ConeAttributes.Empty
|
require(constructor is ConeClassLikeLookupTag && constructor.isBuiltinFunctionalType())
|
||||||
|
// We don't want to create new instance of ConeAttributes which
|
||||||
|
// contains only CompilerConeAttributes.ExtensionFunctionType
|
||||||
|
// to avoid memory consumption
|
||||||
|
if (attributesList != null) {
|
||||||
|
attributesList += CompilerConeAttributes.ExtensionFunctionType
|
||||||
|
ConeAttributes.create(attributesList)
|
||||||
|
} else {
|
||||||
|
ConeAttributes.WithExtensionFunctionType
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
attributesList?.let { ConeAttributes.create(it) } ?: ConeAttributes.Empty
|
||||||
|
}
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return when (constructor) {
|
return when (constructor) {
|
||||||
is ConeClassLikeLookupTag -> ConeClassLikeTypeImpl(
|
is ConeClassLikeLookupTag -> ConeClassLikeTypeImpl(
|
||||||
@@ -74,7 +87,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
)
|
)
|
||||||
is ConeTypeParameterLookupTag -> ConeTypeParameterTypeImpl(
|
is ConeTypeParameterLookupTag -> ConeTypeParameterTypeImpl(
|
||||||
constructor,
|
constructor,
|
||||||
nullable
|
nullable,
|
||||||
|
attributes
|
||||||
)
|
)
|
||||||
else -> error("!")
|
else -> error("!")
|
||||||
}
|
}
|
||||||
@@ -245,7 +259,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker {
|
||||||
return this // TODO
|
require(this is ConeKotlinType)
|
||||||
|
return withAttributes(ConeAttributes.Empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.replaceArguments(newArguments: List<TypeArgumentMarker>): SimpleTypeMarker {
|
override fun SimpleTypeMarker.replaceArguments(newArguments: List<TypeArgumentMarker>): SimpleTypeMarker {
|
||||||
@@ -349,8 +364,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
||||||
// TODO
|
require(this is ConeKotlinType)
|
||||||
return this
|
return withAttributes(attributes.remove(CompilerConeAttributes.Exact))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
|
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
|
||||||
@@ -384,8 +399,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
this,
|
this,
|
||||||
{
|
{
|
||||||
// FIXME supertypes of type constructor contain unsubstituted arguments
|
// FIXME supertypes of type constructor contain unsubstituted arguments
|
||||||
@Suppress("UNCHECKED_CAST")
|
it.typeConstructor().supertypes()
|
||||||
it.typeConstructor().supertypes() as Collection<ConeKotlinType>
|
|
||||||
},
|
},
|
||||||
DFS.VisitedWithSet(),
|
DFS.VisitedWithSet(),
|
||||||
object : DFS.AbstractNodeHandler<ConeKotlinType, Boolean>() {
|
object : DFS.AbstractNodeHandler<ConeKotlinType, Boolean>() {
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.arguments
|
||||||
import org.jetbrains.kotlin.fir.resolve.correspondingSupertypesCache
|
import org.jetbrains.kotlin.fir.resolve.correspondingSupertypesCache
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
@@ -349,7 +353,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
|
|
||||||
override fun KotlinTypeMarker.getAnnotations(): List<AnnotationMarker> {
|
override fun KotlinTypeMarker.getAnnotations(): List<AnnotationMarker> {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return emptyList() // TODO
|
return attributes.arrayMap.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.isStubType(): Boolean {
|
override fun SimpleTypeMarker.isStubType(): Boolean {
|
||||||
@@ -425,13 +429,30 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean {
|
override fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean {
|
||||||
// TODO support annotations
|
require(this is ConeKotlinType)
|
||||||
return false
|
val compilerAttribute = CompilerConeAttributes.compilerAttributeByFqName[fqName]
|
||||||
|
if (compilerAttribute != null) {
|
||||||
|
return compilerAttribute in attributes
|
||||||
|
}
|
||||||
|
val customAnnotations = attributes.customAnnotations
|
||||||
|
return customAnnotations.any {
|
||||||
|
it.typeRef.coneTypeSafe<ConeKotlinType>()?.fullyExpandedType(session)?.classId?.asSingleFqName() == fqName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any? {
|
override fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any? {
|
||||||
// TODO support annotations
|
require(this is ConeKotlinType)
|
||||||
return null
|
// We don't check for compiler attributes because all of them doesn't have parameters
|
||||||
|
val customAnnotations = attributes.customAnnotations
|
||||||
|
val annotationCall = customAnnotations.firstOrNull {
|
||||||
|
it.typeRef.coneTypeSafe<ConeKotlinType>()?.fullyExpandedType(session)?.classId?.asSingleFqName() == fqName
|
||||||
|
} ?: return null
|
||||||
|
val argument = when (val argument = annotationCall.arguments.firstOrNull() ?: return null) {
|
||||||
|
is FirVarargArgumentsExpression -> argument.arguments.firstOrNull()
|
||||||
|
is FirNamedArgumentExpression -> argument.expression
|
||||||
|
else -> argument
|
||||||
|
} ?: return null
|
||||||
|
return (argument as? FirConstExpression<*>)?.value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? {
|
override fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? {
|
||||||
|
|||||||
Reference in New Issue
Block a user