override fun convertToKotlinType()

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
  }