[FIR] Add extracting @Exact and @NoInfer attributes from annotations

This commit is contained in:
Dmitriy Novozhilov
2020-06-04 12:57:51 +03:00
parent e43932f147
commit e4c8c14e3e
3 changed files with 31 additions and 5 deletions
@@ -5,10 +5,15 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import kotlin.reflect.KClass
object CompilerConeAttributes {
object Exact : ConeAttribute<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 isSubtypeOf(other: Exact?): Boolean = true
@@ -17,6 +22,8 @@ object CompilerConeAttributes {
}
object NoInfer : ConeAttribute<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 isSubtypeOf(other: NoInfer?): Boolean = true
@@ -165,19 +165,24 @@ fun ConeClassifierLookupTag.toSymbol(useSiteSession: FirSession): FirClassifierS
fun ConeTypeParameterLookupTag.toSymbol(): FirTypeParameterSymbol = this.symbol as FirTypeParameterSymbol
fun FirClassifierSymbol<*>.constructType(typeArguments: Array<ConeTypeProjection>, isNullable: Boolean): ConeLookupTagBasedType {
fun FirClassifierSymbol<*>.constructType(
typeArguments: Array<ConeTypeProjection>,
isNullable: Boolean,
attributes: ConeAttributes = ConeAttributes.Empty
): ConeLookupTagBasedType {
return when (this) {
is FirTypeParameterSymbol -> {
ConeTypeParameterTypeImpl(this.toLookupTag(), isNullable)
ConeTypeParameterTypeImpl(this.toLookupTag(), isNullable, attributes)
}
is FirClassSymbol -> {
ConeClassLikeTypeImpl(this.toLookupTag(), typeArguments, isNullable)
ConeClassLikeTypeImpl(this.toLookupTag(), typeArguments, isNullable, attributes)
}
is FirTypeAliasSymbol -> {
ConeClassLikeTypeImpl(
this.toLookupTag(),
typeArguments = typeArguments,
isNullable = isNullable,
attributes = attributes
)
}
else -> error("!")
@@ -191,8 +196,9 @@ fun FirClassifierSymbol<*>.constructType(
parts: List<FirQualifierPart>,
isNullable: Boolean,
symbolOriginSession: FirSession,
attributes: ConeAttributes = ConeAttributes.Empty
): ConeKotlinType =
constructType(parts.toTypeProjections(), isNullable)
constructType(parts.toTypeProjections(), isNullable, attributes)
.also {
val lookupTag = it.lookupTag
if (lookupTag is ConeClassLikeLookupTagImpl && this is FirClassLikeSymbol<*>) {
@@ -84,7 +84,20 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver {
if (symbol == null) {
return ConeKotlinErrorType("Symbol not found, for `${typeRef.render()}`")
}
return symbol.constructType(typeRef.qualifier, typeRef.isMarkedNullable, symbolOriginSession = session)
return symbol.constructType(typeRef.qualifier, typeRef.isMarkedNullable, symbolOriginSession = session, typeRef.computeTypeAttributes())
}
private fun FirTypeRef.computeTypeAttributes(): ConeAttributes {
if (annotations.isEmpty()) return ConeAttributes.Empty
val attributes = mutableListOf<ConeAttribute<*>>()
for (annotation in annotations) {
val type = annotation.annotationTypeRef.coneTypeSafe<ConeClassLikeType>() ?: continue
when (type.lookupTag.classId) {
CompilerConeAttributes.Exact.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.Exact
CompilerConeAttributes.NoInfer.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.NoInfer
}
}
return ConeAttributes.create(attributes)
}