Repository: JetBrains/kotlin
File: idea/idea-core/src/org/jetbrains/kotlin/idea/core/util/PsiLinesUtils.kt (Kotlin)

Code before:
            return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java, PsiComment::class.java)?.startOffset ?: startOffset
        }
        return startOffset
    }

    return null
}

fun PsiFile.getLineEndOffset(line: Int): Int? {
    val document = viewProvider.document ?: PsiDocumentManager.getInstance(project).getDocument(this)
    return document?.getLineEndOffset(line)
}

fun PsiElement.getLineNumber(start: Boolean = true): Int {
    val document = containingFile.viewProvider.document ?: PsiDocumentManager.getInstance(project).getDocument(containingFile)
    return document?.getLineNumber(if (start) this.startOffset else this.endOffset) ?: 0
}

fun PsiElement.getLineCount(): Int {
    val doc = containingFile?.let { file -> PsiDocumentManager.getInstance(project).getDocument(file) }
    if (doc != null) {
        val spaceRange = textRange ?: TextRange.EMPTY_RANGE

        if (spaceRange.endOffset <= doc.textLength && spaceRange.startOffset < spaceRange.endOffset) {
            val startLine = doc.getLineNumber(spaceRange.startOffset)
            val endLine = doc.getLineNumber(spaceRange.endOffset)

            return endLine - startLine + 1
        }
    }

    return (text ?: "").count { it == '\n' } + 1
}

fun PsiElement.isMultiLine(): ThreeState {
    val i = getLineCount().takeIf { it >= 0 } ?: return ThreeState.UNSURE
    return ThreeState.fromBoolean(i > 1)
}

fun PsiElement.isOneLiner(): ThreeState {
    val i = getLineCount().takeIf { it >= 0 } ?: return ThreeState.UNSURE
    return ThreeState.fromBoolean(i == 1)
}

fun Document.getLineCountInRange(textRange: TextRange): Int = abs(getLineNumber(textRange.startOffset) - getLineNumber(textRange.endOffset))

fun Document.containsLineBreakInRange(textRange: TextRange): Boolean = getLineCountInRange(textRange) != 0

Review comment (bug):
BTW, `getLineNumber` JavaDoc is incorrect. It accepts ints from range [0, textLength]. I fixed JavaDoc in community: https://github.com/JetBrains/intellij-community/commit/9e4198f84cdbd3f67f6a8fb94bb3f46a4e9dbb45

Code after:
        }
        return startOffset
    }

    return null
}

fun PsiFile.getLineEndOffset(line: Int): Int? {
    val document = viewProvider.document ?: PsiDocumentManager.getInstance(project).getDocument(this)
    return document?.getLineEndOffset(line)
}

fun PsiElement.getLineNumber(start: Boolean = true): Int {
    val document = containingFile.viewProvider.document ?: PsiDocumentManager.getInstance(project).getDocument(containingFile)
    return document?.getLineNumber(if (start) this.startOffset else this.endOffset) ?: 0
}

// Copied to formatter
fun PsiElement.getLineCount(): Int {
    val doc = containingFile?.let { file -> PsiDocumentManager.getInstance(project).getDocument(file) }
    if (doc != null) {
        val spaceRange = textRange ?: TextRange.EMPTY_RANGE

        if (spaceRange.endOffset <= doc.textLength && spaceRange.startOffset < spaceRange.endOffset) {
            val startLine = doc.getLineNumber(spaceRange.startOffset)
            val endLine = doc.getLineNumber(spaceRange.endOffset)

            return endLine - startLine + 1
        }
    }

    return StringUtil.getLineBreakCount(text ?: error("Cannot count number of lines")) + 1
}

fun PsiElement.isMultiLine() = getLineCount() > 1

fun PsiElement.isOneLiner() = getLineCount() == 1

fun Document.getLineCountInRange(textRange: TextRange): Int = abs(getLineNumber(textRange.startOffset) - getLineNumber(textRange.endOffset))

fun Document.containsLineBreakInRange(textRange: TextRange): Boolean = getLineCountInRange(textRange) != 0