Cleanup getLineCount

This commit is contained in:
Nikita Bobko
2020-05-22 17:57:25 +03:00
committed by Nikita Bobko
parent 603bae398f
commit a94d2211e4
16 changed files with 38 additions and 48 deletions
@@ -29,6 +29,7 @@ fun ASTBlock.requireNode() = node ?: error("ASTBlock.getNode() returned null")
*/
val isDefaultOfficialCodeStyle by lazy { !KotlinCodeStyleSettings.defaultSettings().CONTINUATION_INDENT_FOR_CHAINED_CALLS }
// Copied from idea-core
fun PsiElement.getLineCount(): Int {
val doc = containingFile?.let { PsiDocumentManager.getInstance(project).getDocument(it) }
if (doc != null) {
@@ -36,13 +37,13 @@ fun PsiElement.getLineCount(): Int {
if (spaceRange.endOffset <= doc.textLength && spaceRange.startOffset < spaceRange.endOffset) {
val startLine = doc.getLineNumber(spaceRange.startOffset)
val endLine = doc.getLineNumber(spaceRange.endOffset - 1)
val endLine = doc.getLineNumber(spaceRange.endOffset)
return endLine - startLine + 1
}
}
return StringUtil.getLineBreakCount(text ?: "") + 1
return StringUtil.getLineBreakCount(text ?: error("Cannot count number of lines")) + 1
}
fun PsiElement.isMultiline() = getLineCount() > 1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.core.util
import com.intellij.openapi.editor.Document
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -42,23 +43,26 @@ fun PsiElement.getLineNumber(start: Boolean = true): Int {
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) {
if (spaceRange.endOffset <= doc.textLength && spaceRange.startOffset < spaceRange.endOffset) {
val startLine = doc.getLineNumber(spaceRange.startOffset)
val endLine = doc.getLineNumber(spaceRange.endOffset)
return endLine - startLine
return endLine - startLine + 1
}
}
return (text ?: "").count { it == '\n' } + 1
return StringUtil.getLineBreakCount(text ?: error("Cannot count number of lines")) + 1
}
fun PsiElement.isMultiLine(): Boolean = getLineCount() > 1
fun PsiElement.isMultiLine() = getLineCount() > 1
fun PsiElement.isOneLiner() = getLineCount() == 1
fun Document.getLineCountInRange(textRange: TextRange): Int = abs(getLineNumber(textRange.startOffset) - getLineNumber(textRange.endOffset))
@@ -35,7 +35,7 @@ abstract class AbstractBreakpointApplicabilityTest : KotlinLightCodeInsightFixtu
private fun checkBreakpoints(file: KtFile, checker: BreakpointChecker): String {
val lineCount = file.getLineCount()
return (0..lineCount).joinToString("\n") { line -> checkLine(file, line, checker) }
return (0 until lineCount).joinToString("\n") { line -> checkLine(file, line, checker) }
}
private fun checkLine(file: KtFile, line: Int, checker: BreakpointChecker): String {
@@ -10,6 +10,7 @@ import com.intellij.codeInsight.editorActions.moveUpDown.StatementUpDownMover
import com.intellij.openapi.editor.Editor
import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.core.util.getLineCount
import org.jetbrains.kotlin.idea.core.util.isMultiLine
import org.jetbrains.kotlin.idea.formatter.trailingComma.TrailingCommaHelper
import org.jetbrains.kotlin.idea.util.isComma
@@ -552,7 +553,7 @@ class KotlinExpressionMover : AbstractKotlinUpDownMover() {
}
if (whiteSpaceTestSubject is PsiWhiteSpace) {
if (whiteSpaceTestSubject.isMultiLine()) {
if (whiteSpaceTestSubject.getLineCount() >= 3) {
val nearLine = if (down) sourceRange.endLine else sourceRange.startLine - 1
info.toMove = sourceRange
info.toMove2 = LineRange(nearLine, nearLine + 1)
@@ -10,9 +10,9 @@ import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.core.util.isOneLiner
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfToWhenIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isElseIf
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isOneLiner
import org.jetbrains.kotlin.idea.intentions.branches
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
@@ -23,9 +23,9 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.util.getLineCount
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.BranchedFoldingUtils
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isElseIf
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.lineCount
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -115,7 +115,7 @@ class LiftReturnOrAssignmentInspection @JvmOverloads constructor(private val ski
keyword: PsiElement,
skipLongExpressions: Boolean
): List<LiftState>? {
if (skipLongExpressions && expression.lineCount() > LINES_LIMIT) return null
if (skipLongExpressions && expression.getLineCount() > LINES_LIMIT) return null
if (expression.isElseIf()) return null
val foldableReturns = BranchedFoldingUtils.getFoldableReturns(expression)
@@ -17,7 +17,7 @@ import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.SmartPsiElementPointer
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.core.moveCaret
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isOneLiner
import org.jetbrains.kotlin.idea.core.util.isOneLiner
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.countUsages
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.previousStatement
import org.jetbrains.kotlin.lexer.KtTokens
@@ -14,8 +14,9 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.core.util.getLineCount
import org.jetbrains.kotlin.idea.core.util.isMultiLine
import org.jetbrains.kotlin.idea.intentions.*
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.lineCount
import org.jetbrains.kotlin.idea.util.textRangeIn
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
@@ -249,7 +250,7 @@ private fun KtFunctionLiteral.valueParameterReferences(callExpression: KtCallExp
private fun isSingleLine(element: KtCallExpression): Boolean {
val qualifiedExpression = element.getQualifiedExpressionForSelector() ?: return true
var receiver = qualifiedExpression.receiverExpression
if (receiver.lineCount() > 1) return false
if (receiver.isMultiLine()) return false
var count = 1
while (true) {
if (count > 2) return false
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.canOmitDeclaredType
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.core.setType
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isOneLiner
import org.jetbrains.kotlin.idea.core.util.isOneLiner
import org.jetbrains.kotlin.idea.intentions.hasResultingIfWithoutElse
import org.jetbrains.kotlin.idea.intentions.resultingWhens
import org.jetbrains.kotlin.idea.util.CommentSaver
@@ -361,13 +361,4 @@ private fun KtExpression.insertSafeCalls(factory: KtPsiFactory): KtExpression {
return replaced
}
// Returns -1 if cannot obtain a document
internal fun KtExpression.lineCount(): Int {
val file = containingFile?.virtualFile ?: return -1
val document = FileDocumentManager.getInstance().getDocument(file) ?: return -1
return document.getLineNumber(textRange.endOffset) - document.getLineNumber(textRange.startOffset) + 1
}
internal fun KtExpression.isOneLiner(): Boolean = lineCount() == 1
internal fun KtExpression.isElseIf() = parent.node.elementType == KtNodeTypes.ELSE
@@ -21,12 +21,8 @@ import com.intellij.openapi.editor.Document
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.core.util.getLineCount
import org.jetbrains.kotlin.idea.intentions.ConvertToStringTemplateIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.lineCount
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
class JoinToStringTemplateHandler : JoinRawLinesHandlerDelegate {
@@ -42,10 +38,9 @@ class JoinToStringTemplateHandler : JoinRawLinesHandlerDelegate {
if (!binaryExpr.joinable()) return -1
val lineCount = binaryExpr.getLineCount()
val nextLineCount = lineCount + 1
var parent = binaryExpr.parent
while (parent is KtBinaryExpression && parent.joinable() && parent.lineCount() == nextLineCount) {
while (parent is KtBinaryExpression && parent.joinable() && parent.getLineCount() == lineCount) {
binaryExpr = parent
parent = parent.parent
}
@@ -54,7 +49,7 @@ class JoinToStringTemplateHandler : JoinRawLinesHandlerDelegate {
var left = binaryExpr.left
while (left is KtBinaryExpression && left.joinable()) {
val leftLeft = (left as? KtBinaryExpression)?.left ?: break
if (leftLeft.lineCount() < lineCount) break
if (leftLeft.getLineCount() < lineCount - 1) break
rightText = ConvertToStringTemplateIntention.buildText(left.right, false) + rightText
left = left.left
}
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.idea.parameterInfo
import com.intellij.codeInsight.hints.InlayInfo
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isOneLiner
import org.jetbrains.kotlin.idea.core.util.isOneLiner
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
@@ -14,8 +14,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
import org.jetbrains.kotlin.idea.core.util.getLineCount
import org.jetbrains.kotlin.idea.core.util.isMultiLine
import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.lineCount
import org.jetbrains.kotlin.idea.refactoring.getLineNumber
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.idea.util.getResolutionScope
@@ -104,7 +105,7 @@ fun provideTypeHint(element: KtCallableDeclaration, offset: Int): List<InlayInfo
return emptyList()
}
if (element is KtProperty && element.isLocal && type.isUnit() && element.lineCount() > 1) {
if (element is KtProperty && element.isLocal && type.isUnit() && element.isMultiLine()) {
val propertyLine = element.getLineNumber()
val equalsTokenLine = element.equalsToken?.getLineNumber() ?: -1
val initializerLine = element.initializer?.getLineNumber() ?: -1
@@ -603,7 +603,7 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
val bodyExpression = body.statements.singleOrNull()
val bodyOwner = body.parent as KtDeclarationWithBody
val useExpressionBodyInspection = UseExpressionBodyInspection()
if (bodyExpression != null && !bodyExpression.isMultiLine() && useExpressionBodyInspection.isActiveFor(bodyOwner)) {
if (bodyExpression != null && useExpressionBodyInspection.isActiveFor(bodyOwner)) {
useExpressionBodyInspection.simplify(bodyOwner, !useExplicitReturnType())
}
}
@@ -8,10 +8,8 @@ fun foo(a: Int): Int {
return i(a, b)
}
private fun i(a: Int, b: Int): Int {
return when (a + b) {
0 -> b
1 -> -b
else -> a - b
}
private fun i(a: Int, b: Int) = when (a + b) {
0 -> b
1 -> -b
else -> a - b
}
@@ -18,11 +18,9 @@ fun foo(o: Any) {
val x = i(o)
}
private fun i(o: Any): Int {
return when (o) {
is A -> {
if (o is T) o.a + o.t else o.a
}
else -> o.hashCode()
private fun i(o: Any) = when (o) {
is A -> {
if (o is T) o.a + o.t else o.a
}
else -> o.hashCode()
}