[FIR-IDE] Add conversion for Map type

This commit is contained in:
Dmitriy Novozhilov
2021-06-02 11:46:27 +03:00
committed by teamcityserver
parent 3b2df7ade3
commit b363d95160
2 changed files with 63 additions and 3 deletions
@@ -98,14 +98,32 @@ private object FirToKtConversionCreator {
return null
}
private fun KType.toParameterName(): String {
return kClass.simpleName!!.replaceFirstChar(Char::lowercaseChar)
}
private fun tryMapPlatformType(type: KType, kClass: KClass<*>): HLParameterConversion? {
if (kClass.isSubclassOf(Collection::class)) {
val elementType = type.arguments.single().type ?: return HLIdParameterConversion
return HLMapParameterConversion(
parameterName = elementType.kClass.simpleName!!.replaceFirstChar(Char::lowercaseChar),
return HLCollectionParameterConversion(
parameterName = elementType.toParameterName(),
mappingConversion = createConversion(elementType)
)
}
if (kClass.isSubclassOf(Map::class)) {
val keyType = type.arguments.getOrNull(0)?.type
val valueType = type.arguments.getOrNull(1)?.type
val keyConversion = keyType?.let { createConversion(it) } ?: HLIdParameterConversion
val valueConversion = valueType?.let { createConversion(it) } ?: HLIdParameterConversion
if (keyConversion.isTrivial && valueConversion.isTrivial) return HLIdParameterConversion
return HLMapParameterConversion(
keyName = keyType?.toParameterName() ?: "key",
valueName = valueType?.toParameterName() ?: "value",
mappingConversionForKeys = keyConversion,
mappingConversionForValues = valueConversion
)
}
if (kClass.isSubclassOf(Pair::class)) {
val first = type.arguments.getOrNull(0)?.type ?: return HLIdParameterConversion
val second = type.arguments.getOrNull(1)?.type ?: return HLIdParameterConversion
@@ -21,7 +21,7 @@ object HLIdParameterConversion : HLParameterConversion() {
override fun convertType(type: KType): KType = type
}
class HLMapParameterConversion(
class HLCollectionParameterConversion(
private val parameterName: String,
private val mappingConversion: HLParameterConversion,
) : HLParameterConversion() {
@@ -47,6 +47,45 @@ class HLMapParameterConversion(
override val importsToAdd get() = mappingConversion.importsToAdd
}
class HLMapParameterConversion(
private val keyName: String,
private val valueName: String,
private val mappingConversionForKeys: HLParameterConversion,
private val mappingConversionForValues: HLParameterConversion,
) : HLParameterConversion() {
override fun convertExpression(expression: String, context: ConversionContext): String {
val keyTransformation = mappingConversionForKeys.convertExpression(keyName, context.increaseIndent())
val valueTransformation = mappingConversionForValues.convertExpression(valueName, context.increaseIndent())
return buildString {
appendLine("$expression.mapKeys { ($keyName, _) ->")
appendLine(keyTransformation.withIndent(context.increaseIndent()))
appendLine("}.mapValues { (_, $valueName) -> ".withIndent(context))
appendLine(valueTransformation.withIndent(context.increaseIndent()))
append("}".withIndent(context))
}
}
override fun convertType(type: KType): KType {
val keyArgument = type.arguments[0]
val valueArgument = type.arguments[1]
return Map::class.createType(
arguments = listOf(
KTypeProjection(
variance = KVariance.INVARIANT,
type = keyArgument.type?.let(mappingConversionForKeys::convertType)
),
KTypeProjection(
variance = KVariance.INVARIANT,
type = valueArgument.type?.let(mappingConversionForValues::convertType)
)
)
)
}
override val importsToAdd: List<String>
get() = (mappingConversionForKeys.importsToAdd + mappingConversionForValues.importsToAdd).distinct()
}
class HLPairParameterConversion(
private val mappingConversionFirst: HLParameterConversion,
private val mappingConversionSecond: HLParameterConversion,
@@ -93,3 +132,6 @@ private fun String.withIndent(context: ConversionContext): String {
val newIndent = " ".repeat(context.currentIndent * context.indentUnitValue)
return replaceIndent(newIndent)
}
val HLParameterConversion.isTrivial: Boolean
get() = this is HLIdParameterConversion