FIR: allow nullable types in diagnostic parameters

This commit is contained in:
Tianyu Geng
2021-04-29 16:19:21 -07:00
committed by Ilya Kirillov
parent 594fbbb4ef
commit cceb7197a5
14 changed files with 98 additions and 78 deletions
@@ -41,28 +41,28 @@ private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
psiSourceElement,
a,
severity,
factory as FirDiagnosticFactory1<PsiElement, Any>
factory as FirDiagnosticFactory1<PsiElement, Any?>
)
is FirLightDiagnosticWithParameters2<*, *> -> FirPsiDiagnosticWithParameters2(
psiSourceElement,
a, b,
severity,
factory as FirDiagnosticFactory2<PsiElement, Any, Any>
factory as FirDiagnosticFactory2<PsiElement, Any?, Any?>
)
is FirLightDiagnosticWithParameters3<*, *, *> -> FirPsiDiagnosticWithParameters3(
psiSourceElement,
a, b, c,
severity,
factory as FirDiagnosticFactory3<PsiElement, Any, Any, Any>
factory as FirDiagnosticFactory3<PsiElement, Any?, Any?, Any?>
)
is FirLightDiagnosticWithParameters4<*, *, *, *> -> FirPsiDiagnosticWithParameters4(
psiSourceElement,
a, b, c, d,
severity,
factory as FirDiagnosticFactory4<PsiElement, Any, Any, Any, Any>
factory as FirDiagnosticFactory4<PsiElement, Any?, Any?, Any?, Any?>
)
else -> error("Unknown diagnostic type ${this::class.simpleName}")
}
@@ -73,16 +73,21 @@ object HLDiagnosticConverter {
private object FirToKtConversionCreator {
fun createConversion(type: KType): HLParameterConversion {
val nullable = type.isMarkedNullable
val kClass = type.classifier as KClass<*>
return tryMapAllowedType(kClass)
?: tryMapPsiElementType(type, kClass)
?: tryMapFirTypeToKtType(kClass)
?: tryMapFirTypeToKtType(kClass, nullable)
?: tryMapPlatformType(type, kClass)
?: error("Unsupported type $type, consider add corresponding mapping")
}
private fun tryMapFirTypeToKtType(kClass: KClass<*>): HLParameterConversion? {
return typeMapping[kClass]
private fun tryMapFirTypeToKtType(kClass: KClass<*>, nullable: Boolean): HLParameterConversion? {
return if (nullable) {
nullableTypeMapping[kClass] ?: typeMapping[kClass]
} else {
typeMapping[kClass]
}
}
private fun tryMapAllowedType(kClass: KClass<*>): HLParameterConversion? {
@@ -116,6 +121,17 @@ private object FirToKtConversionCreator {
return null
}
private val nullableTypeMapping: Map<KClass<*>, HLFunctionCallConversion> = mapOf(
FirExpression::class to HLFunctionCallConversion(
"{0}?.source?.psi as? KtExpression",
KtExpression::class.createType(nullable = true),
importsToAdd = listOf(
"org.jetbrains.kotlin.psi.KtExpression",
"org.jetbrains.kotlin.fir.psi"
)
),
)
private val typeMapping: Map<KClass<*>, HLFunctionCallConversion> = mapOf(
AbstractFirBasedSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0}.fir as FirDeclaration)",
@@ -11,13 +11,14 @@ import kotlin.reflect.KType
internal fun SmartPrinter.printTypeWithShortNames(type: KType) {
fun typeConversion(type: KType): String {
val nullableSuffix = if (type.isMarkedNullable) "?" else ""
val simpleName = (type.classifier as KClass<*>).simpleName!!
return if (type.arguments.isEmpty()) simpleName
return if (type.arguments.isEmpty()) simpleName + nullableSuffix
else simpleName + type.arguments.joinToString(separator = ", ", prefix = "<", postfix = ">") {
when (val typeArgument = it.type) {
null -> "*"
else -> typeConversion(typeArgument)
}
} + nullableSuffix
}
}
print(typeConversion(type))
@@ -15,19 +15,19 @@ internal fun interface KtFirDiagnostic0Creator : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirSimpleDiagnostic<*>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic1Creator<A : Any> : KtFirDiagnosticCreator {
internal fun interface KtFirDiagnostic1Creator<A> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters1<*, A>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic2Creator<A : Any, B : Any> : KtFirDiagnosticCreator {
internal fun interface KtFirDiagnostic2Creator<A, B> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters2<*, A, B>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic3Creator<A : Any, B : Any, C : Any> : KtFirDiagnosticCreator {
internal fun interface KtFirDiagnostic3Creator<A, B, C> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters3<*, A, B, C>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic4Creator<A : Any, B : Any, C : Any, D : Any> : KtFirDiagnosticCreator {
internal fun interface KtFirDiagnostic4Creator<A, B, C, D> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters4<*, A, B, C, D>): KtFirDiagnostic<*>
}
@@ -42,17 +42,17 @@ internal class KtDiagnosticConverter(private val conversions: Map<AbstractFirDia
is KtFirDiagnostic0Creator -> with(creator) {
create(diagnostic as FirSimpleDiagnostic<*>)
}
is KtFirDiagnostic1Creator<*> -> with(creator as KtFirDiagnostic1Creator<Any>) {
create(diagnostic as FirDiagnosticWithParameters1<FirSourceElement, Any>)
is KtFirDiagnostic1Creator<*> -> with(creator as KtFirDiagnostic1Creator<Any?>) {
create(diagnostic as FirDiagnosticWithParameters1<FirSourceElement, Any?>)
}
is KtFirDiagnostic2Creator<*, *> -> with(creator as KtFirDiagnostic2Creator<Any, Any>) {
create(diagnostic as FirDiagnosticWithParameters2<FirSourceElement, Any, Any>)
is KtFirDiagnostic2Creator<*, *> -> with(creator as KtFirDiagnostic2Creator<Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters2<FirSourceElement, Any?, Any?>)
}
is KtFirDiagnostic3Creator<*, *, *> -> with(creator as KtFirDiagnostic3Creator<Any, Any, Any>) {
create(diagnostic as FirDiagnosticWithParameters3<FirSourceElement, Any, Any, Any>)
is KtFirDiagnostic3Creator<*, *, *> -> with(creator as KtFirDiagnostic3Creator<Any?, Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters3<FirSourceElement, Any?, Any?, Any?>)
}
is KtFirDiagnostic4Creator<*, *, *, *> -> with(creator as KtFirDiagnostic4Creator<Any, Any, Any, Any>) {
create(diagnostic as FirDiagnosticWithParameters4<FirSourceElement, Any, Any, Any, Any>)
is KtFirDiagnostic4Creator<*, *, *, *> -> with(creator as KtFirDiagnostic4Creator<Any?, Any?, Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters4<FirSourceElement, Any?, Any?, Any?, Any?>)
}
else -> error("Invalid KtFirDiagnosticCreator ${creator::class.simpleName}")
}
@@ -67,19 +67,19 @@ internal class KtDiagnosticConverterBuilder private constructor() {
conversions[diagnostic] = creator
}
fun <A : Any> add(diagnostic: FirDiagnosticFactory1<*, A>, creator: KtFirDiagnostic1Creator<A>) {
fun <A> add(diagnostic: FirDiagnosticFactory1<*, A>, creator: KtFirDiagnostic1Creator<A>) {
conversions[diagnostic] = creator
}
fun <A : Any, B : Any> add(diagnostic: FirDiagnosticFactory2<*, A, B>, creator: KtFirDiagnostic2Creator<A, B>) {
fun <A, B> add(diagnostic: FirDiagnosticFactory2<*, A, B>, creator: KtFirDiagnostic2Creator<A, B>) {
conversions[diagnostic] = creator
}
fun <A : Any, B : Any, C : Any> add(diagnostic: FirDiagnosticFactory3<*, A, B, C>, creator: KtFirDiagnostic3Creator<A, B, C>) {
fun <A, B, C> add(diagnostic: FirDiagnosticFactory3<*, A, B, C>, creator: KtFirDiagnostic3Creator<A, B, C>) {
conversions[diagnostic] = creator
}
fun <A : Any, B : Any, C : Any, D : Any> add(diagnostic: FirDiagnosticFactory4<*, A, B, C, D>, creator: KtFirDiagnostic4Creator<A, B, C, D>) {
fun <A, B, C, D> add(diagnostic: FirDiagnosticFactory4<*, A, B, C, D>, creator: KtFirDiagnostic4Creator<A, B, C, D>) {
conversions[diagnostic] = creator
}