Repository: JetBrains/compose-multiplatform
File: gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/InfoPlistBuilder.kt (Kotlin)

Code before:
/*
 * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
 */

package org.jetbrains.compose.desktop.application.internal

import org.jetbrains.compose.desktop.application.internal.InfoPlistBuilder.InfoPlistValue.*
import java.io.File
import kotlin.reflect.KProperty

private const val indent = "  "
private fun indentForLevel(level: Int) = indent.repeat(level)

internal class InfoPlistBuilder(private val extraPlistKeysRawXml: String? = null) {
    internal sealed class InfoPlistValue {
        abstract fun toString(nestingLevel: Int): String
        override fun toString(): String = toString(0)
        data class InfoPlistListValue(val elements: List<InfoPlistValue>) : InfoPlistValue() {
            override fun toString(nestingLevel: Int): String =
                if (elements.isEmpty()) "${indentForLevel(nestingLevel)}<array/>"
                else elements.joinToString(
                    separator = "\n",
                    prefix = "${indentForLevel(nestingLevel)}<array>\n",
                    postfix = "\n${indentForLevel(nestingLevel)}</array>"
                ) {
                    it.toString(nestingLevel + 1)
                }

            override fun toString(): String = super.toString()

            constructor(vararg elements: InfoPlistValue) : this(elements.asList())
        }

        data class InfoPlistMapValue(val elements: Map<InfoPlistKey, InfoPlistValue>) : InfoPlistValue() {
            override fun toString(nestingLevel: Int): String =
                if (elements.isEmpty()) "${indentForLevel(nestingLevel)}<dict/>"
                else elements.entries.joinToString(
                    separator = "\n",
                    prefix = "${indentForLevel(nestingLevel)}<dict>\n",
                    postfix = "\n${indentForLevel(nestingLevel)}</dict>",
                ) { (key, value) ->
                    "${indentForLevel(nestingLevel + 1)}<key>${key.name}</key>\n${value.toString(nestingLevel + 1)}"

Review comment (suggestion):
I wouldn't use "toString" here because it has a different semantic. It adds plist specific tags, so a function `asPlistEntry` is better

Code after:
/*
 * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
 */

package org.jetbrains.compose.desktop.application.internal

import org.jetbrains.compose.desktop.application.internal.InfoPlistBuilder.InfoPlistValue.*
import java.io.File
import kotlin.reflect.KProperty

private const val indent = "  "
private fun indentForLevel(level: Int) = indent.repeat(level)

internal class InfoPlistBuilder(private val extraPlistKeysRawXml: String? = null) {
    internal sealed class InfoPlistValue {
        abstract fun asPlistEntry(nestingLevel: Int): String
        data class InfoPlistListValue(val elements: List<InfoPlistValue>) : InfoPlistValue() {
            override fun asPlistEntry(nestingLevel: Int): String =
                if (elements.isEmpty()) "${indentForLevel(nestingLevel)}<array/>"
                else elements.joinToString(
                    separator = "\n",
                    prefix = "${indentForLevel(nestingLevel)}<array>\n",
                    postfix = "\n${indentForLevel(nestingLevel)}</array>"
                ) {
                    it.asPlistEntry(nestingLevel + 1)
                }

            constructor(vararg elements: InfoPlistValue) : this(elements.asList())
        }

        data class InfoPlistMapValue(val elements: Map<InfoPlistKey, InfoPlistValue>) : InfoPlistValue() {
            override fun asPlistEntry(nestingLevel: Int): String =
                if (elements.isEmpty()) "${indentForLevel(nestingLevel)}<dict/>"
                else elements.entries.joinToString(
                    separator = "\n",
                    prefix = "${indentForLevel(nestingLevel)}<dict>\n",
                    postfix = "\n${indentForLevel(nestingLevel)}</dict>",
                ) { (key, value) ->
                    "${indentForLevel(nestingLevel + 1)}<key>${key.name}</key>\n${value.asPlistEntry(nestingLevel + 1)}"
                }

            constructor(vararg elements: Pair<InfoPlistKey, InfoPlistValue>) : this(elements.toMap())