"Lift return / assignment": do not suggest for too long expressions

This commit is contained in:
Mikhail Glukhikh
2017-07-06 15:00:11 +03:00
parent 398f92dc6f
commit 042990dda1
4 changed files with 55 additions and 0 deletions
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.*
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.BranchedFoldingUtils
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.lineCount
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.KtVisitorVoid
@@ -31,6 +32,7 @@ class LiftReturnOrAssignmentInspection : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) =
object : KtVisitorVoid() {
private fun visitIfOrWhen(expression: KtExpression, keyword: PsiElement) {
if (expression.lineCount() > LINES_LIMIT) return
val returnNumber = BranchedFoldingUtils.getFoldableReturnNumber(expression)
if (returnNumber > 0) {
holder.registerProblem(
@@ -84,4 +86,8 @@ class LiftReturnOrAssignmentInspection : AbstractKotlinInspection() {
BranchedFoldingUtils.foldToAssignment(descriptor.psiElement.getParentOfType(true)!!)
}
}
companion object {
private val LINES_LIMIT = 15
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea.intentions.branchedTransformations
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.KtNodeTypes
@@ -254,3 +255,12 @@ private fun KtExpression.insertSafeCalls(factory: KtPsiFactory): KtExpression {
replaced.receiverExpression.let { it.replace(it.insertSafeCalls(factory)) }
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
@@ -0,0 +1,33 @@
// PROBLEM: none
fun println(s: String) {}
fun test(n: Int): String {
<caret>if (n == 1) {
println("123")
println("456")
println("789")
println("123")
println("456")
println("789")
return "one"
}
else if (n == 2) {
println("123")
println("456")
println("789")
println("123")
println("456")
println("789")
return "two"
}
else {
println("123")
println("456")
println("789")
println("123")
println("456")
println("789")
return "three"
}
}
@@ -529,6 +529,12 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
doTest(fileName);
}
@TestMetadata("ifVeryLong.kt")
public void testIfVeryLong() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/ifToReturn/ifVeryLong.kt");
doTest(fileName);
}
@TestMetadata("innerIfTransformed.kt")
public void testInnerIfTransformed() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/ifToReturn/innerIfTransformed.kt");