in vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/services/VimVariableServiceBase.kt [301:383]
override fun <T : Any> convertToKotlinType(
vimDataType: VimDataType,
type: KType,
): T {
val clazz: KClass<*> = type.classifier as KClass<*>
return when (clazz) {
Int::class -> {
if (vimDataType is VimInt) {
vimDataType.value
} else if(vimDataType is VimString && vimDataType.value.toIntOrNull() != null) {
vimDataType.value.toInt()
} else {
throw IllegalArgumentException("Expected Int, but got ${vimDataType::class.simpleName}")
}
}
String::class -> {
if (vimDataType is VimString) {
vimDataType.value
} else {
throw IllegalArgumentException("Expected String, but got ${vimDataType::class.simpleName}")
}
}
Double::class -> {
if (vimDataType is VimFloat) {
vimDataType.value
} else {
throw IllegalArgumentException("Expected Double, but got ${vimDataType::class.simpleName}")
}
}
Float::class -> {
if (vimDataType is VimFloat) {
vimDataType.value.toFloat()
} else {
throw IllegalArgumentException("Expected Float, but got ${vimDataType::class.simpleName}")
}
}
List::class -> {
if (vimDataType is VimList) {
val list = mutableListOf<Any>()
val values = vimDataType.values
val listArgumentType: KType = type.arguments.firstNotNullOf { it.type }
for (value in values) {
list.add(convertToKotlinType(value, listArgumentType))
}
list.toList()
} else {
throw IllegalArgumentException("Expected List, but got ${vimDataType::class.simpleName}")
}
}
Map::class -> {
if (vimDataType is VimDictionary) {
val mapArgumentTypes: List<KType> = type.arguments.mapNotNull { it.type }
val values: HashMap<VimString, VimDataType> = vimDataType.dictionary
// the fist argument has to be string
val keyArgumentType: KType = mapArgumentTypes[0]
if (keyArgumentType != String::class.createType()) {
throw IllegalArgumentException("Expected Map with String as key, but got ${vimDataType::class.simpleName}")
}
val valueArgumentType: KType = mapArgumentTypes[1]
val map: MutableMap<String, Any> = mutableMapOf()
for ((key, value) in values) {
val keyValue: String = convertToKotlinType(key, keyArgumentType)
val valueValue: Any = convertToKotlinType(value, valueArgumentType)
map[keyValue] = valueValue
}
map.toMap()
} else {
throw IllegalArgumentException("Expected Map, but got ${vimDataType::class.simpleName}")
}
}
else -> throw IllegalArgumentException("Unsupported type: ${clazz.simpleName}")
} as T
}