[LL API] Introduce converters from plugin defined diagnostics to KtDiagnostics

This commit is contained in:
Dmitriy Novozhilov
2022-06-17 14:18:54 +03:00
committed by teamcity
parent 22dae9bff4
commit 441f3d202a
8 changed files with 541 additions and 96 deletions
@@ -0,0 +1,96 @@
/*
* Copyright 2010-2022 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.analysis.api.fir.generator
import org.jetbrains.kotlin.fir.checkers.generator.printImports
import org.jetbrains.kotlin.fir.tree.generator.printer.printCopyright
import org.jetbrains.kotlin.fir.tree.generator.printer.printGeneratedMessage
import org.jetbrains.kotlin.fir.tree.generator.util.writeToFileUsingSmartPrinterIfFileContentChanged
import org.jetbrains.kotlin.util.SmartPrinter
import org.jetbrains.kotlin.util.withIndent
import java.io.File
import kotlin.reflect.KClass
import kotlin.reflect.full.createType
private const val CONVERT_ARGUMENT = "convertArgument"
object ArgumentsConverterGenerator {
fun render(file: File, packageName: String) {
val convertArgumentFunctionCallConversion = HLFunctionCallConversion(
"$CONVERT_ARGUMENT({0}, firSymbolBuilder)",
callType = Any::class.createType(nullable = true)
)
val convertersMap = FirToKtConversionCreator.getAllConverters(convertArgumentFunctionCallConversion)
file.writeToFileUsingSmartPrinterIfFileContentChanged { generate(packageName, convertersMap) }
}
private fun SmartPrinter.generate(packageName: String, convertersMap: Map<KClass<*>, HLParameterConversion>) {
printCopyright()
println("@file:Suppress(\"UNUSED_PARAMETER\")")
println()
println("package $packageName")
println()
collectAndPrintImports(convertersMap)
println()
printGeneratedMessage()
generateDispatchingConverter(convertersMap)
for ((type, converter) in convertersMap) {
generateSingleConverter(type, converter)
}
}
private fun SmartPrinter.collectAndPrintImports(convertersMap: Map<KClass<*>, HLParameterConversion>) {
val imports = buildList {
add("org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder")
add("org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession")
convertersMap.values.flatMapTo(this) { it.importsToAdd }
convertersMap.keys.mapNotNullTo(this) { it.qualifiedName }
}
printImports(imports)
}
private fun SmartPrinter.generateDispatchingConverter(convertersMap: Map<KClass<*>, HLParameterConversion>) {
println("internal fun $CONVERT_ARGUMENT(argument: Any?, analysisSession: KtFirAnalysisSession): Any? {")
withIndent {
println("return $CONVERT_ARGUMENT(argument, analysisSession.firSymbolBuilder)")
}
println("}")
println()
println("private fun $CONVERT_ARGUMENT(argument: Any?, firSymbolBuilder: KtSymbolByFirBuilder): Any? {")
withIndent {
println("return when (argument) {")
withIndent {
println("null -> null")
for (type in convertersMap.keys) {
println("is ${type.typeWithStars} -> $CONVERT_ARGUMENT(argument, firSymbolBuilder)")
}
println("else -> argument")
}
println("}")
}
println("}")
println()
}
private fun SmartPrinter.generateSingleConverter(type: KClass<*>, converter: HLParameterConversion) {
println("private fun $CONVERT_ARGUMENT(argument: ${type.typeWithStars}, firSymbolBuilder: KtSymbolByFirBuilder): Any? {")
withIndent {
println("return ${converter.convertExpression("argument", ConversionContext(getCurrentIndentInUnits(), getIndentUnit()))}")
}
println("}")
println()
}
private val KClass<*>.typeWithStars: String
get() = buildString {
append(simpleName)
if (typeParameters.isNotEmpty()) {
append(typeParameters.joinToString(", ", "<", ">") { "*" })
}
}
}
@@ -18,5 +18,6 @@ object DiagnosticClassGenerator {
KtDiagnosticClassRenderer.render(path.resolve("KtFirDiagnostics.kt"), diagnosticList, packageName, emptySet())
KtDiagnosticClassImplementationRenderer.render(path.resolve("KtFirDiagnosticsImpl.kt"), diagnosticList, packageName, emptySet())
FirDiagnosticToKtDiagnosticConverterRenderer.render(path.resolve("KtFirDataClassConverters.kt"), diagnosticList, packageName, emptySet())
ArgumentsConverterGenerator.render(path.resolve("KtFirArgumentsConverter.kt"), packageName)
}
}
@@ -43,7 +43,6 @@ import kotlin.reflect.full.createType
import kotlin.reflect.full.isSubclassOf
object HLDiagnosticConverter {
@OptIn(ExperimentalStdlibApi::class)
fun convert(diagnosticList: DiagnosticList): HLDiagnosticList {
return HLDiagnosticList(diagnosticList.allDiagnostics.flatMap(::convertDiagnostic))
}
@@ -107,8 +106,7 @@ object HLDiagnosticConverter {
}
private object FirToKtConversionCreator {
internal object FirToKtConversionCreator {
fun createConversion(type: KType): HLParameterConversion {
val nullable = type.isMarkedNullable
val kClass = type.classifier as KClass<*>
@@ -119,6 +117,32 @@ private object FirToKtConversionCreator {
?: error("Unsupported type $type, consider add corresponding mapping")
}
fun getAllConverters(conversionForCollectionValues: HLParameterConversion): Map<KClass<*>, HLParameterConversion> {
return buildMap {
putAll(typeMapping)
put(
Map::class,
HLMapParameterConversion(
"key",
"value",
conversionForCollectionValues,
conversionForCollectionValues
)
)
put(
Collection::class,
HLCollectionParameterConversion("value", conversionForCollectionValues)
)
put(
Pair::class,
HLPairParameterConversion(
conversionForCollectionValues,
conversionForCollectionValues
)
)
}
}
private fun tryMapFirTypeToKtType(kClass: KClass<*>, nullable: Boolean): HLParameterConversion? {
return if (nullable) {
nullableTypeMapping[kClass] ?: typeMapping[kClass]
@@ -188,19 +212,7 @@ private object FirToKtConversionCreator {
)
private val typeMapping: Map<KClass<*>, HLFunctionCallConversion> = mapOf(
FirBasedSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0})",
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
),
FirClass::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0}.symbol)",
KtClassLikeSymbol::class.createType()
),
FirClassSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0})",
KtClassLikeSymbol::class.createType()
),
// ------------------ symbols ------------------
FirRegularClass::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0}.symbol) as KtNamedClassOrObjectSymbol",
KtNamedClassOrObjectSymbol::class.createType(),
@@ -209,27 +221,6 @@ private object FirToKtConversionCreator {
"org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol"
)
),
FirExpression::class to HLFunctionCallConversion(
"{0}.source!!.psi as KtExpression",
KtExpression::class.createType(),
importsToAdd = listOf(
"org.jetbrains.kotlin.psi.KtExpression",
"org.jetbrains.kotlin.psi"
)
),
FirQualifiedAccess::class to HLFunctionCallConversion(
"{0}.source!!.psi as KtExpression",
KtExpression::class.createType(),
importsToAdd = listOf(
"org.jetbrains.kotlin.psi.KtExpression",
"org.jetbrains.kotlin.psi"
)
),
FirValueParameter::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0}.symbol)",
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
),
FirValueParameterSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0})",
KtSymbol::class.createType(),
@@ -239,66 +230,58 @@ private object FirToKtConversionCreator {
"firSymbolBuilder.buildSymbol({0})",
KtSymbol::class.createType(),
),
FirClassLikeSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0})",
KtClassLikeSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirClass")
),
FirRegularClassSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0})",
KtClassLikeSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirRegularClass")
KtClassLikeSymbol::class.createType()
),
FirMemberDeclaration::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0} as FirDeclaration)",
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
),
FirCallableDeclaration::class to HLFunctionCallConversion(
"firSymbolBuilder.callableBuilder.buildCallableSymbol({0} as FirCallableDeclaration)",
KtCallableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration")
),
FirCallableSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.callableBuilder.buildCallableSymbol({0})",
KtCallableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration")
),
FirTypeParameterSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol({0})",
KtTypeParameterSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirTypeParameter")
),
FirTypeParameter::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol({0})",
KtTypeParameterSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirTypeParameter")
),
ConeKotlinType::class to HLFunctionCallConversion(
"firSymbolBuilder.typeBuilder.buildKtType({0})",
KtType::class.createType()
),
FirTypeRef::class to HLFunctionCallConversion(
"firSymbolBuilder.typeBuilder.buildKtType({0})",
KtType::class.createType()
FirNamedFunctionSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.functionLikeBuilder.buildFunctionSymbol({0})",
KtFunctionLikeSymbol::class.createType()
),
FirPropertySymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.variableLikeBuilder.buildVariableSymbol({0})",
KtVariableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty")
KtVariableSymbol::class.createType()
),
FirBackingFieldSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.variableLikeBuilder.buildVariableSymbol({0}.fir.propertySymbol)",
KtVariableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty")
KtVariableSymbol::class.createType()
),
FirVariableSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.variableLikeBuilder.buildVariableLikeSymbol({0})",
KtVariableLikeSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirVariable")
KtVariableLikeSymbol::class.createType()
),
FirDeclaration::class to HLFunctionCallConversion(
FirTypeParameterSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol({0})",
KtTypeParameterSymbol::class.createType()
),
FirCallableSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.callableBuilder.buildCallableSymbol({0})",
KtCallableSymbol::class.createType()
),
FirClassSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0})",
KtClassLikeSymbol::class.createType()
),
FirClassLikeSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0})",
KtClassLikeSymbol::class.createType()
),
FirBasedSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0})",
KtSymbol::class.createType()
),
// ------------------ FIR elements ------------------
FirClass::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0}.symbol)",
KtClassLikeSymbol::class.createType()
),
FirTypeParameter::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol({0}.symbol)",
KtTypeParameterSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirTypeParameter")
),
FirValueParameter::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0}.symbol)",
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
),
@@ -307,10 +290,46 @@ private object FirToKtConversionCreator {
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirFunction")
),
FirNamedFunctionSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.functionLikeBuilder.buildFunctionSymbol({0})",
KtFunctionLikeSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirSimpleFunction")
FirCallableDeclaration::class to HLFunctionCallConversion(
"firSymbolBuilder.callableBuilder.buildCallableSymbol({0}.symbol)",
KtCallableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration")
),
FirMemberDeclaration::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0} as FirDeclaration)",
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
),
FirDeclaration::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0})",
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
),
FirQualifiedAccess::class to HLFunctionCallConversion(
"{0}.source!!.psi as KtExpression",
KtExpression::class.createType(),
importsToAdd = listOf(
"org.jetbrains.kotlin.psi.KtExpression",
"org.jetbrains.kotlin.psi"
)
),
FirExpression::class to HLFunctionCallConversion(
"{0}.source!!.psi as KtExpression",
KtExpression::class.createType(),
importsToAdd = listOf(
"org.jetbrains.kotlin.psi.KtExpression",
"org.jetbrains.kotlin.psi"
)
),
// ------------------ other ------------------
ConeKotlinType::class to HLFunctionCallConversion(
"firSymbolBuilder.typeBuilder.buildKtType({0})",
KtType::class.createType()
),
FirTypeRef::class to HLFunctionCallConversion(
"firSymbolBuilder.typeBuilder.buildKtType({0})",
KtType::class.createType()
),
KtSourceElement::class to HLFunctionCallConversion(
"({0} as KtPsiSourceElement).psi",