TrailingComma: Join Lines should remove trailing comma

#KT-34744
#KT-36084 Fixed
This commit is contained in:
Dmitry Gridin
2020-02-06 19:23:53 +07:00
parent cb66625688
commit f428bbb782
20 changed files with 162 additions and 1 deletions

View File

@@ -5,11 +5,13 @@
package org.jetbrains.kotlin.idea.core.util
import com.intellij.openapi.editor.Document
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import kotlin.math.abs
fun PsiFile.getLineStartOffset(line: Int): Int? {
return getLineStartOffset(line, skipWhitespace = true)
@@ -56,4 +58,8 @@ fun PsiElement.getLineCount(): Int {
return (text ?: "").count { it == '\n' } + 1
}
fun PsiElement.isMultiLine(): Boolean = getLineCount() > 1
fun PsiElement.isMultiLine(): Boolean = getLineCount() > 1
fun Document.getLineCountInRange(textRange: TextRange): Int = abs(getLineNumber(textRange.startOffset) - getLineNumber(textRange.endOffset))
fun Document.containsLineBreakInRange(textRange: TextRange): Boolean = getLineCountInRange(textRange) != 0

View File

@@ -813,6 +813,7 @@
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinBlockIntoSingleStatementHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinStatementsAddSemicolonHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinToStringTemplateHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinWithTrailingCommaHandler"/>
<targetElementEvaluator
language="kotlin"

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.joinLines
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate.CANNOT_JOIN
import com.intellij.openapi.editor.Document
import com.intellij.psi.PsiFile
import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.kotlin.idea.core.util.containsLineBreakInRange
import org.jetbrains.kotlin.idea.formatter.TrailingCommaHelper
import org.jetbrains.kotlin.idea.util.addTrailingCommaIsAllowedForThis
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.psiUtil.startOffset
class JoinWithTrailingCommaHandler : JoinLinesHandlerDelegate {
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int): Int {
if (file !is KtFile) return CANNOT_JOIN
val commaOwner = file.findElementAt(start)
?.parentsWithSelf
?.filter { !document.containsLineBreakInRange(it.textRange) }
?.findLast { it.addTrailingCommaIsAllowedForThis() } as? KtElement
?: return CANNOT_JOIN
if (TrailingCommaHelper.needComma(commaOwner, null, true)) return CANNOT_JOIN
val result = CodeStyleManager.getInstance(file.project).reformat(commaOwner) as KtElement
return TrailingCommaHelper.elementAfterLastElement(result)?.startOffset ?: end - 1
}
}

View File

@@ -0,0 +1,4 @@
fun a() {
val (a,<caret>
b,) = 1 to 2
}

View File

@@ -0,0 +1,3 @@
fun a() {
val (a, b<caret>) = 1 to 2
}

View File

@@ -0,0 +1,4 @@
fun a() {
val <caret>a = { (a, b // awd
,/**/), c, -> }
}

View File

@@ -0,0 +1,3 @@
fun a() {
val a = { (a, b /* awd*//**/), c -> <caret>}
}

View File

@@ -0,0 +1,4 @@
fun a(<caret>
a: Int, b: Any = fun(a: Int,),) {
}

View File

@@ -0,0 +1,3 @@
fun a(a: Int, b: Any = fun(a: Int)<caret>) {
}

View File

@@ -0,0 +1,6 @@
fun a() {
<caret>val a = { a: Int,
b: Int, ->
}
}

View File

@@ -0,0 +1,5 @@
fun a() {
val a = { a: Int, b: Int <caret>->
}
}

View File

@@ -0,0 +1,4 @@
fun a(<caret>
a: Int,) {
}

View File

@@ -0,0 +1,3 @@
fun a(a: Int<caret>) {
}

View File

@@ -0,0 +1,2 @@
fun <T,<caret>
B,> a() = Unit

View File

@@ -0,0 +1 @@
fun <T, B<caret>> a() = Unit

View File

@@ -0,0 +1,7 @@
fun a() {
when (val b = 5) {
1, 2,
<caret>3,
->
}
}

View File

@@ -0,0 +1,6 @@
fun a() {
when (val b = 5) {
1, 2,
3, ->
}
}

View File

@@ -0,0 +1,6 @@
fun a() {
when (val b = 5) {
<caret>1, 2,
3, ->
}
}

View File

@@ -0,0 +1,5 @@
fun a() {
when (val b = 5) {
1, 2, 3 <caret>->
}
}

View File

@@ -393,6 +393,59 @@ public class JoinLinesTestGenerated extends AbstractJoinLinesTest {
}
}
@TestMetadata("idea/testData/joinLines/removeTrailingComma")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class RemoveTrailingComma extends AbstractJoinLinesTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInRemoveTrailingComma() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/joinLines/removeTrailingComma"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("destructionDeclaration.kt")
public void testDestructionDeclaration() throws Exception {
runTest("idea/testData/joinLines/removeTrailingComma/destructionDeclaration.kt");
}
@TestMetadata("destructionDeclarationInLambda.kt")
public void testDestructionDeclarationInLambda() throws Exception {
runTest("idea/testData/joinLines/removeTrailingComma/destructionDeclarationInLambda.kt");
}
@TestMetadata("inner.kt")
public void testInner() throws Exception {
runTest("idea/testData/joinLines/removeTrailingComma/inner.kt");
}
@TestMetadata("lambda.kt")
public void testLambda() throws Exception {
runTest("idea/testData/joinLines/removeTrailingComma/lambda.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("idea/testData/joinLines/removeTrailingComma/simple.kt");
}
@TestMetadata("typeParameters.kt")
public void testTypeParameters() throws Exception {
runTest("idea/testData/joinLines/removeTrailingComma/typeParameters.kt");
}
@TestMetadata("whenEntry.kt")
public void testWhenEntry() throws Exception {
runTest("idea/testData/joinLines/removeTrailingComma/whenEntry.kt");
}
@TestMetadata("whenEntry2.kt")
public void testWhenEntry2() throws Exception {
runTest("idea/testData/joinLines/removeTrailingComma/whenEntry2.kt");
}
}
@TestMetadata("idea/testData/joinLines/stringTemplate")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)