Repository: apple/pkl
File: pkl-formatter/src/main/kotlin/org/pkl/formatter/Builder.kt (Kotlin)

Code before:
          continue
        }
        val elem = cursor.next()
        if (elem.type == NodeType.TERMINAL && elem.text().endsWith("(")) {
          isInStringInterpolation = true
        }
        add(format(elem))
        prev = elem
      }
    }
  }

  private fun formatSingleLineString(node: Node): FormatNode {
    return Group(newId(), formatStringParts(node.children))
  }

  private fun formatMultilineString(node: Node): FormatNode {
    val nodes = formatStringParts(node.children)
    return MultilineStringGroup(node.children.last().span.colBegin, nodes)
  }

  private fun formatIf(node: Node): FormatNode {
    val nodes =
      formatGeneric(node.children) { prev, next ->
        when {
          next.type == NodeType.IF_ELSE_EXPR && next.children[0].type == NodeType.IF_EXPR -> Space
          next.type == NodeType.IF_THEN_EXPR ||
            next.type == NodeType.IF_ELSE_EXPR ||
            next.isTerminal("else") ->
            if (prev.linesBetween(next) > 0) forceLine() else spaceOrLine()
          else -> spaceOrLine()
        }
      }
    return Group(newId(), nodes)
  }

  private fun formatIfHeader(node: Node): FormatNode {
    val nodes =
      formatGeneric(node.children) { _, next ->
        if (next.type == NodeType.IF_CONDITION) Space else spaceOrLine()
      }
    return Group(newId(), nodes)
  }

  private fun formatIfCondition(node: Node): FormatNode {
    val nodes =
      formatGeneric(node.children) { prev, next ->
        if (prev.isTerminal("(") || next.isTerminal(")")) line() else spaceOrLine()
      }
    return Group(newId(), nodes)
  }

Review comment (bug):
I thought I spotted a bug here: we can't use `next.children[0]` because the first child might be an affix. But then I remembered I did this on purpose: if you add a comment between the `else` and the next `if` we are not lining up the else/ifs as they can't be properly lined anyway. But I forgot to add a comment there telling why we are using `children[0]`.


Code after:
          continue
        }
        val elem = cursor.next()
        if (elem.type == NodeType.TERMINAL && elem.text().endsWith("(")) {
          isInStringInterpolation = true
        }
        add(format(elem))
        prev = elem
      }
    }
  }

  private fun formatSingleLineString(node: Node): FormatNode {
    return Group(newId(), formatStringParts(node.children))
  }

  private fun formatMultilineString(node: Node): FormatNode {
    val nodes = formatStringParts(node.children)
    return MultilineStringGroup(node.children.last().span.colBegin, nodes)
  }

  private fun formatIf(node: Node): FormatNode {
    val separator = if (node.isMultiline()) forceLine() else spaceOrLine()
    val nodes =
      formatGeneric(node.children) { _, next ->
        // produce `else if` in the case of nested if.
        // note: don't need to handle if `next.children[0]` is an affix because that can't be
        // emitted as `else if` anyway.
        if (next.type == NodeType.IF_ELSE_EXPR && next.children[0].type == NodeType.IF_EXPR) Space
        else separator
      }
    return Group(newId(), nodes)
  }

  private fun formatIfHeader(node: Node): FormatNode {
    val nodes =
      formatGeneric(node.children) { _, next ->
        if (next.type == NodeType.IF_CONDITION) Space else spaceOrLine()
      }
    return Group(newId(), nodes)
  }

  private fun formatIfCondition(node: Node): FormatNode {
    val nodes =
      formatGeneric(node.children) { prev, next ->
        if (prev.isTerminal("(") || next.isTerminal(")")) line() else spaceOrLine()
      }
    return Group(newId(), nodes)
  }

  private fun formatIfThen(node: Node): FormatNode {