TrailingCommaInspection: shouldn't be associated with formatter settings

#KT-34744
This commit is contained in:
Dmitry Gridin
2020-02-04 14:48:22 +07:00
parent b5d0956a5e
commit 195d9020a6
26 changed files with 14114 additions and 11893 deletions
@@ -53,7 +53,7 @@ fun PsiElement.getLineCount(): Int {
fun PsiElement.isMultiline() = getLineCount() > 1
fun KtFunctionLiteral.needTrailingComma(settings: CodeStyleSettings, checkExistingTrailingComma: Boolean = true): Boolean =
fun KtFunctionLiteral.needTrailingComma(settings: CodeStyleSettings?, checkExistingTrailingComma: Boolean = true): Boolean =
needTrailingComma(
settings = settings,
trailingComma = { if (checkExistingTrailingComma) valueParameterList?.trailingComma else null },
@@ -61,14 +61,14 @@ fun KtFunctionLiteral.needTrailingComma(settings: CodeStyleSettings, checkExisti
globalEndOffset = { arrow?.endOffset },
)
fun KtWhenEntry.needTrailingComma(settings: CodeStyleSettings, checkExistingTrailingComma: Boolean = true): Boolean = needTrailingComma(
fun KtWhenEntry.needTrailingComma(settings: CodeStyleSettings?, checkExistingTrailingComma: Boolean = true): Boolean = needTrailingComma(
settings = settings,
trailingComma = { if (checkExistingTrailingComma) trailingComma else null },
additionalCheck = { !isElse },
globalEndOffset = { arrow?.endOffset },
)
fun KtDestructuringDeclaration.needTrailingComma(settings: CodeStyleSettings, checkExistingTrailingComma: Boolean = true): Boolean =
fun KtDestructuringDeclaration.needTrailingComma(settings: CodeStyleSettings?, checkExistingTrailingComma: Boolean = true): Boolean =
needTrailingComma(
settings = settings,
trailingComma = { if (checkExistingTrailingComma) trailingComma else null },
@@ -77,13 +77,13 @@ fun KtDestructuringDeclaration.needTrailingComma(settings: CodeStyleSettings, ch
)
fun <T : PsiElement> T.needTrailingComma(
settings: CodeStyleSettings,
settings: CodeStyleSettings?,
trailingComma: T.() -> PsiElement?,
additionalCheck: () -> Boolean = { true },
globalStartOffset: T.() -> Int? = PsiElement::startOffset,
globalEndOffset: T.() -> Int? = PsiElement::endOffset,
): Boolean {
if (trailingComma() == null && !settings.kotlinCustomSettings.addTrailingCommaIsAllowedFor(this)) return false
if (trailingComma() == null && settings?.kotlinCustomSettings?.addTrailingCommaIsAllowedFor(this) == false) return false
if (!additionalCheck()) return false
val startOffset = globalStartOffset() ?: return false
@@ -19,6 +19,7 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
@@ -270,6 +271,22 @@ fun configureCompilerOptions(fileText: String, project: Project, module: Module)
return false
}
fun <T> configureRegistryAndRun(fileText: String, body: () -> T) {
val registers = InTextDirectivesUtils.findListWithPrefixes(fileText, "// REGISTRY:")
.map { it.split(' ') }
.map { Registry.get(it.first()) to it.last() }
try {
for ((register, value) in registers) {
register.setValue(value)
}
body()
} finally {
for ((register, _) in registers) {
register.resetToDefault()
}
}
}
fun rollbackCompilerOptions(project: Project, module: Module) {
configureLanguageAndApiVersion(project, module, LanguageVersion.LATEST_STABLE.versionString)
@@ -19,6 +19,7 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
@@ -272,6 +273,22 @@ fun configureCompilerOptions(fileText: String, project: Project, module: Module)
return false
}
fun <T> configureRegistryAndRun(fileText: String, body: () -> T) {
val registers = InTextDirectivesUtils.findListWithPrefixes(fileText, "// REGISTRY:")
.map { it.split(' ') }
.map { Registry.get(it.first()) to it.last() }
try {
for ((register, value) in registers) {
register.setValue(value)
}
body()
} finally {
for ((register, _) in registers) {
register.resetToDefault()
}
}
}
fun rollbackCompilerOptions(project: Project, module: Module) {
configureLanguageAndApiVersion(project, module, LanguageVersion.LATEST_STABLE.versionString)
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.idea.formatter
import com.intellij.application.options.CodeStyle
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.registry.Registry
@@ -46,7 +45,7 @@ class TrailingCommaPostFormatProcessor : PostFormatProcessor {
fun needComma(
commaOwner: KtElement,
settings: CodeStyleSettings = CodeStyle.getSettings(commaOwner.project),
settings: CodeStyleSettings?,
checkExistingTrailingComma: Boolean = true,
): Boolean = when {
commaOwner is KtWhenEntry ->
@@ -60,7 +59,7 @@ class TrailingCommaPostFormatProcessor : PostFormatProcessor {
else -> (checkExistingTrailingComma &&
trailingCommaOrLastElement(commaOwner)?.isComma == true ||
settings.kotlinCustomSettings.addTrailingCommaIsAllowedFor(commaOwner)) &&
settings?.kotlinCustomSettings?.addTrailingCommaIsAllowedFor(commaOwner) != false) &&
commaOwner.isMultiline()
}
@@ -6,28 +6,25 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.application.options.CodeStyle
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.idea.formatter.TrailingCommaPostFormatProcessor
import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.kotlin.idea.formatter.*
import org.jetbrains.kotlin.idea.formatter.TrailingCommaPostFormatProcessor.Companion.findInvalidCommas
import org.jetbrains.kotlin.idea.formatter.TrailingCommaPostFormatProcessor.Companion.needComma
import org.jetbrains.kotlin.idea.formatter.TrailingCommaPostFormatProcessor.Companion.trailingCommaAllowedInModule
import org.jetbrains.kotlin.idea.formatter.TrailingCommaPostFormatProcessor.Companion.trailingCommaOrLastElement
import org.jetbrains.kotlin.idea.formatter.TrailingCommaVisitor
import org.jetbrains.kotlin.idea.formatter.isComma
import org.jetbrains.kotlin.idea.formatter.leafIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.idea.quickfix.ReformatQuickFix
import org.jetbrains.kotlin.idea.util.isLineBreak
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.nextLeaf
import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi.psiUtil.*
import javax.swing.JComponent
class TrailingCommaInspection(
@@ -111,7 +108,7 @@ class TrailingCommaInspection(
message,
highlightType,
commaOrElement.textRangeOfCommaOrSymbolAfter.shiftLeft(problemOwner.startOffset),
ReformatQuickFix(fixMessage, commaOwner, createFormatterTextRange(commaOwner)),
createQuickFix(fixMessage, commaOwner),
)
}
@@ -126,10 +123,29 @@ class TrailingCommaInspection(
"Missing line break",
highlightType,
TextRange.from(elementForTextRange.startOffset, 1).shiftLeft(problemElement.startOffset),
ReformatQuickFix("Add line break", commaOwner, createFormatterTextRange(commaOwner)),
createQuickFix("Add line break", commaOwner),
)
}
private fun createQuickFix(
fixMessage: String,
commaOwner: KtElement,
): LocalQuickFix = object : LocalQuickFix {
val commaOwnerPointer = commaOwner.createSmartPointer()
override fun getFamilyName(): String = fixMessage
override fun applyFix(project: Project, problemDescriptor: ProblemDescriptor) {
val element = commaOwnerPointer.element ?: return
val range = createFormatterTextRange(element)
val settings = CodeStyle.getSettings(project).clone()
settings.kotlinCustomSettings.ALLOW_TRAILING_COMMA = true
CodeStyle.doWithTemporarySettings(project, settings) {
CodeStyleManager.getInstance(project).reformatRange(element, range.startOffset, range.endOffset)
}
}
}
private fun createFormatterTextRange(commaOwner: KtElement): TextRange {
val startElement = TrailingCommaPostFormatProcessor.elementBeforeFirstElement(commaOwner) ?: commaOwner
val endElement = TrailingCommaPostFormatProcessor.elementAfterLastElement(commaOwner) ?: commaOwner
@@ -158,13 +174,10 @@ private enum class TrailingCommaAction {
ADD, REFORMAT, REMOVE;
companion object {
fun create(commaOwner: KtElement): TrailingCommaAction {
val settings = CodeStyle.getSettings(commaOwner.project)
return when {
needComma(commaOwner, settings, checkExistingTrailingComma = false) -> ADD
needComma(commaOwner, settings, checkExistingTrailingComma = true) -> REFORMAT
else -> REMOVE
}
fun create(commaOwner: KtElement): TrailingCommaAction = when {
needComma(commaOwner, null, checkExistingTrailingComma = false) -> ADD
needComma(commaOwner, null, checkExistingTrailingComma = true) -> REFORMAT
else -> REMOVE
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,225 @@
fun foo() {
testtest(foofoo, foofoo, foofoo,
foofoo, bar)
testtest(
foofoo, foofoo, foofoo, foofoo, bar
)
testtest(foofoo, foofoo, foofoo, foofoo, bar
)
testtest(foofoo, foofoo, foofoo, foofoo,
bar
)
testtest(foofoo
)
testtest(
foofoo)
testtest(
foofoo
)
testtest(foofoo,)
testtest(foofoo, testtest(testtest(foofoo)))
testtest(foofoo, fososos, testtest(testtest(foofoo)),)
testtest(foofoo, testtest(testtest(foofoo,)), testsa)
testtest(foofoo, seee, testtest(testtest(foofoo,)), testsa)
useCallable("A", Callable { println("Hello world") })
useCallable("B", "C", Callable {
println("Hello world")
}, Callable {
println("Hello world")
})
useCallable(Callable { println("Hello world") })
useCallable(Callable { println("Hello world") },)
useCallable(Callable { println("Hello world") }
)
useCallable(Callable { println("Hello world") }){
}
useCallable(
Callable { println("Hello world") })
useCallable("A", { println("Hello world") })
useCallable("B", "C", {
println("Hello world")
}, {
println("Hello world")
})
useCallable({ println("Hello world") })
useCallable({ println("Hello world") },)
useCallable({ println("Hello world") }
)
useCallable({ println("Hello world") }){
}
useCallable(
{ println("Hello world") })
useCallable("A", foo() { println("Hello world") })
useCallable("B", "C", foo() {
println("Hello world")
}, foo() {
println("Hello world")
})
useCallable(foo() { println("Hello world") })
useCallable(foo() { println("Hello world") },)
useCallable(foo() { println("Hello world") }
)
useCallable(foo() { println("Hello world") }) {
}
useCallable(
foo() { println("Hello world") })
useCallable("A", object : Callable<Unit> { override fun call() { println("Hello world") } })
useCallable("A", object : Callable<Unit> {
override fun call() {
println("Hello world")
}
})
useCallable("B", "C", object : Callable<Unit> { override fun call() { println("Hello world") } }, foo() {
println("Hello world")
})
useCallable(object : Callable<Unit> { override fun call() { println("Hello world") } })
useCallable(object : Callable<Unit> { override fun call() { println("Hello world") } },)
useCallable(object : Callable<Unit> { override fun call() { println("Hello world") } }
)
useCallable(object : Callable<Unit> { override fun call() { println("Hello world") } }) {
}
useCallable(
object : Callable<Unit> { override fun call() { println("Hello world") } })
testtest(
foofoo, foofoo, foofoo, foofoo,
bar /*
*/, /* */ foo
)
testtest(/*
*/foofoo, foofoo, foofoo, /*
*/
foofoo, bar)
testtest(foofoo, foofoo, foofoo, foofoo, bar/*
*/)
testtest(foofoo, foofoo, foofoo, foofoo, bar // awdawda
)
testtest(foofoo, foofoo, foofoo, foofoo, /*
*/
bar
)
testtest(foofoo // fd
)
testtest( /**/
foofoo
)
testtest(foofoo,/**/)
testtest(foofoo, foofoo, foofoo, foofoo/*
*/ , /* */ bar
)
testtest(foofoo // fd
)
testtest( /**/
foofoo
)
testtest(foofoo,/**/)
testtest(foofoo, fososos,/*
*/ testtest(testtest(foofoo)),)
testtest(foofoo, testtest(testtest(foofoo,)), /**/testsa)
testtest(foofoo, testtest(testtest(foofoo,))/* */ , /**/testsa)
testtest(foofoo, testtest(testtest(foofoo,))/*
*/ ,testsa)
testtest(foofoo, seee, testtest(testtest(foofoo,)), /**/testsa)
testtest(foofoo, seee, testtest(testtest(foofoo,)), /*
*/testsa)
useCallable("B", "C", Callable {
println("Hello world")
}, /* */ Callable {
println("Hello world")
})
useCallable(Callable { println("Hello world") } // ffd
)
useCallable(object : Callable<Unit> { override fun call() { println("Hello world") }
},)
useCallable(foo() { println("Hello world")
},)
useCallable({
println("Hello world") },)
useCallable(Callable { println("Hello world") }
,)
testtest(foofoo, testtest(testtest(
foofoo,)), testsa)
testtest(foofoo, fososos, testtest(testtest(foofoo))
,)
}
fun test() {
baz(
f = fun(it: Int): String = "$it" /*dwdwd
*/,
name = "" /*
*/,
)
}
@@ -0,0 +1,112 @@
@Anno([1])
fun a() = Unit
@Anno([1,])
fun a() = Unit
@Anno([1
])
fun a() = Unit
@Anno([
1, ])
fun a() = Unit
@Anno([
1 ])
fun a() = Unit
@Anno([1,2])
fun a() = Unit
@Anno([1, 2,])
fun a() = Unit
@Anno([1, 2
])
fun a() = Unit
@Anno([
1, 2, ])
fun a() = Unit
@Anno([
1, 2 ])
fun a() = Unit
@Anno([1, 2, 2])
fun a() = Unit
@Anno([1, 2, 2,])
fun a() = Unit
@Anno(["1"
])
fun a() = Unit
@Anno([
1, ])
fun a() = Unit
@Anno([
1 , 2 , 2 ])
fun a() = Unit
@Anno([1/*
*/])
fun a() = Unit
@Anno([1, //dw
])
fun a() = Unit
@Anno([1 // ds
])
fun a() = Unit
@Anno([/*
*/ // d
1/*
*/,/*
*/ ])
fun a() = Unit
@Anno([
/*
*/ 1 ])
fun a() = Unit
@Anno([1/*
*/,2])
fun a() = Unit
@Anno([1, 2/*
*/,/*
*/])
fun a() = Unit
@Anno([/*
*/1, 2
])
fun a() = Unit
@Anno(["1"
])
fun a() = Unit
@Anno([
1, ])
fun a() = Unit
@Anno([
1 , 2 /*
*/ ])
fun a() = Unit
@Component(
modules = [
AppModule::class, DataModule::class,
DomainModule::class
],
)
fun b() = Unit
@@ -0,0 +1,64 @@
val x: (Pair<Int, Int>, Int) -> Unit = { (x, y,), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (x, y), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (x,
y), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (
x,
y), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (
x // adw
,y,), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (x /* val x: (Pair<Int, Int>, Int) -> Unit = { (x, y), z, ->
println(x)
}*/,), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (x, y), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (x, y/**/), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (x, y/*
*/), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (/**/x /**/ /*
*/, // awdawd
y/*
*/), z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = {
(/**/x /**/ /*
*/, // awdawd
y/*
*/),
z, ->
println(x)
}
val x: (Pair<Int, Int>, Int) -> Unit = { (x, y,),
z, ->
println(x)
}
@@ -0,0 +1,38 @@
enum class Enum1 {
A, B,;
}
enum class Enum2 {
A, B;
}
enum class Enum3 {
A, B
;
}
enum class Enum4 {
A, B,
}
enum class Enum5 {
A, B,
}
enum class Enum6(val a: Int) {
A(
1
), B,
}
enum class Enum7(val a: Int) {
A(
1
), B,;
}
enum class Enum8(val a: Int) {
A(
1
), B;
}
@@ -0,0 +1,176 @@
fun foo() {
testtest[foofoo, foofoo, foofoo,
foofoo, bar]
testtest[
foofoo, foofoo, foofoo, foofoo, bar
]
testtest[foofoo, foofoo, foofoo, foofoo, bar
]
testtest[foofoo, foofoo, foofoo, foofoo,
bar
]
testtest[foofoo
]
testtest[
foofoo]
testtest[
foofoo
]
testtest[foofoo,]
testtest[foofoo, testtest[testtest[foofoo]]]
testtest[foofoo, fososos,
testtest[testtest[foofoo]],]
testtest[foofoo, testtest[testtest[foofoo,]], testsa]
testtest[foofoo, seee, testtest[testtest[foofoo,]], testsa]
useCallable["A", Callable { println["Hello world"] }]
useCallable["B", "C", Callable {
println["Hello world"]
}, Callable {
println["Hello world"]
}]
useCallable[Callable { println["Hello world"] }]
useCallable[Callable { println["Hello world"] },]
useCallable[Callable {
println["Hello world"] },]
useCallable[Callable { println["Hello world"] }
]
useCallable[Callable { println["Hello world"] }]{
}
useCallable[
Callable { println["Hello world"] }]
useCallable["A", { println["Hello world"] }]
useCallable["B", "C", {
println["Hello world"]
}, {
println["Hello world"]
}]
useCallable[{ println["Hello world"] }]
useCallable[{ println["Hello world"] },]
useCallable[{ println["Hello world"] }
,]
useCallable[{ println["Hello world"] }
]
useCallable[
{ println["Hello world"] }]
useCallable["A", object : Callable<Unit> { override fun call() { println["Hello world"] } }]
useCallable["A", object : Callable<Unit> {
override fun call() {
println["Hello world"]
}
}]
useCallable["B", "C", object : Callable<Unit> { override fun call() { println["Hello world"] } }, foo[0,]]
useCallable[object : Callable<Unit> { override fun call() { println["Hello world"] } }]
useCallable[object : Callable<Unit> { override fun call() { println["Hello world"] } },]
useCallable[object : Callable<Unit> { override fun call() { println["Hello world"] } }
]
useCallable[object : Callable<Unit> { override fun call() { println["Hello world"] } }] {
}
useCallable[
object : Callable<Unit> { override fun call() { println["Hello world"] } }]
testtest[
foofoo, foofoo, foofoo, foofoo,
bar /*
*/, /* */ foo
]
testtest[/*
*/foofoo, foofoo, foofoo, /*
*/
foofoo, bar]
testtest[foofoo, foofoo, foofoo, foofoo, bar/*
*/]
testtest[foofoo, foofoo, foofoo, foofoo, bar // awdawda
]
testtest[foofoo, foofoo, foofoo, foofoo, /*
*/
bar
]
testtest[foofoo // fd
]
testtest[ /**/
foofoo
]
testtest[foofoo,/**/]
testtest[foofoo, foofoo, foofoo, foofoo/*
*/ , /* */ bar
]
testtest[foofoo // fd
]
testtest[ /**/
foofoo
]
testtest[foofoo,/**/]
testtest[foofoo, fososos,/*
*/ testtest[testtest[foofoo]],]
testtest[foofoo, testtest[testtest[foofoo,]], /**/testsa]
testtest[foofoo, testtest[testtest[foofoo,]]/* */ , /**/testsa]
testtest[foofoo, testtest[testtest[foofoo,]]/*
*/ ,testsa]
testtest[foofoo, seee, testtest[testtest[foofoo,]], /**/testsa]
testtest[foofoo, seee, testtest[testtest[foofoo,]], /*
*/testsa]
useCallable["B", "C", Callable {
println["Hello world"]
}, /* */ Callable {
println["Hello world"]
}]
useCallable[Callable { println["Hello world"] } // ffd
]
}
@@ -0,0 +1,190 @@
val x = {
x: Comparable<Comparable<Number>>,
y: String,
->
println("1")
}
val x = {x: Comparable<Comparable<Number>>, y: String->
println("1")
}
val x = {x: String, y
: String->
println("1")
}
val x = {
x: String,
y: String
->
println("1")
}
val x = {
x: String,
y: Comparable<Comparable<Number>>,->
println("1")
}
val x = {
x: Comparable<Comparable<Number>>,
y: String
,->
println("1")
}
val x = {
x: String,
y: Comparable<Comparable<Number>>,
z: String,
->
println("1")
}
val x = {
x: String,
y: String,
z: String
->
println("1")
}
val x = {
x: String,
y: String,
z: String,->
println("1")
}
val x = {
x: String,
y: String,
z: String
,->
println("1")
}
val x = {
x: String,
->
println("1")
}
val x = {
x: String
->
println("1")
}
val x = {
x: String,->
println("1")
}
val x = {
x: String
,->
println("1")
}
val x = {
x: String ,
y: String,
->
println("1")
}
val x = {
x: String,
z: String
->
println("1")
}
val x = {
x: String,
y: String,
z: String ,->
println("1")
}
val x = {
x: String,
z: String
, ->
println("1")
}
val x = {
x, y: String,
z: String
, ->
println("1")
}
val x = {
x: String, y: String, z: String
->
println("1")
}
val x = {
z: String, v: Comparable<Comparable<Number>>,
->
println("1")
}
val x = {x: String,
y: Comparable<Comparable<Number>>,
->
println("1")
}
val x = {
x: Int
->
println("1")
}
val x = {
x: String, y: String
, /* */ z: String
->
println("1")
}
val x = {
x: String, y: String
/* */, /* */ z: String
->
println("1")
}()
val x = {
x: String, /*
*/ y: String,
z: String ,->
println("1")
}
val x = {
x: String, y: String , z: String /*
*/
, ->
println("1")
}
val x = {
x: Comparable<Comparable<Number>>, y: String,
z: String
, ->
println("1")
}
val x = {
x: String, y: String, z: String
->
println("1")
}
@@ -0,0 +1,83 @@
fun main() {
val x: (
y: Comparable<Comparable<Number>>,
z: Iterable<Iterable<Number>> // trailing comma
) -> Int = {
10
}
val x: (
y: Comparable<Comparable<Number>>,
z: Iterable<Iterable<Number>>
) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>, z: Iterable<Iterable<Number>>) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>, z: Iterable<Iterable<Number>>,) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>, z: Iterable<Iterable<Number>>,
) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>,) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>
) -> Int = {
10
}
val x: (
y: Comparable<Comparable<Number>>) -> Int = {
10
}
val x: (
y: Comparable<Comparable<Number>>, //
z: Iterable<Iterable<Number>> // /**/
) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>, z: Iterable<Iterable<Number>>
// wd
) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>/*
*/, z: Iterable<Iterable<Number>>, /* //
*/) -> Int = {
10
}
val x: (/**/y: Comparable<Comparable<Number>>/**/) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>/**/,) -> Int = {
10
}
val x: (y: Comparable<Comparable<Number>>
) -> Int = {
10
}
val x: ( /*
*/y: Comparable<Comparable<Number>>) -> Int = {
10
}
}
@@ -0,0 +1,99 @@
fun test() {
val (a, b) = 1 to 2
val (a, b) = 1 to
2
val (a, b) = 1
to
2
val (a, b,) = 1 to 2
val (a,) =
b
val (a,
) =
b
val (a
) =
b
val (a,) = b
val (
a,) = b
val (a, b
) = 1 to 2
val (a,
b) = 1 to 2
val (
a, b
) = 1 to 2
val (
a, b,
) = 1 to 2
val (a, b, c,
d, f
) = 1 to 2
val (a, b, c,
d, f,
) = 1 to 2
val (a, b/**/) = 1 to 2
val (a, /**/b/**/) /**/=/**/ 1 to
2
val (a,/**/ b) = 1
to
2
val (a, b/**/,) = 1 to 2
val (a/**/, b/**/,/**/) = 1 to 2
val (a/**/,/**/) =
b
val (a,) = b
val (a, b/**/
) = 1 to 2
val (a, b// awd
) = 1 to 2
val (a,/**/ b /**/ // awd
) = 1 to 2
val (a, // ad
/**/b) = 1 to 2
val (
a, b // fe
/**/)/**/ = 1 to 2
val (
a, b, // awd
) = 1 to 2
val (a, b, c,
d, f // awd
/*
*/) = 1 to 2
val (a, b, c,
d, f // awd
,
) = 1 to 2
}
@@ -0,0 +1,458 @@
class A1 {
val x: String
val y: String
constructor(
x: String,
y: String,
) {
this.x = x
this.y = y
}
}
class B1 {
val x: String
val y: String
constructor(
x: String,
y: String
) {
this.x = x
this.y = y
}
}
class C1 {
val x: String
val y: String
constructor(
x: String,
y: String,) {
this.x = x
this.y = y
}
}
class D1 {
val x: String
val y: String
constructor(
x: String,
y: String
,) {
this.x = x
this.y = y
}
}
class A2 {
val x: String
val y: String
val z: String
constructor(
x: String,
y: String,
z: String,
) {
this.x = x
this.y = y
this.z = z
}
}
class B2 {
val x: String
val y: String
val z: String
constructor(
x: String,
y: String,
z: String
) {
this.x = x
this.y = y
this.z = z
}
}
class C2 {
val x: String
val y: String
val z: String
constructor(
x: String,
y: String,
z: String,) {
this.x = x
this.y = y
this.z = z
}
}
class D2 {
val x: String
val y: String
val z: String
constructor(
x: String,
y: String,
z: String
,) {
this.x = x
this.y = y
this.z = z
}
}
class A3 {
val x: String
constructor(x: String,) {
this.x = x
}
}
class B3 {
val x: String
constructor(x: String) {
this.x = x
}
}
class C3 {
val x: String
constructor(
x: String,) {
this.x = x
}
}
class D3 {
val x: String
constructor(
x: String
,) {
this.x = x
}
}
class E1 {
val x: String
val y: String
val z: String
constructor(
x: String,
y: String, z: String,) {
this.x = x
this.y = y
this.z = z
}
}
class E2 {
val x: String
val y: String
val z: String
constructor(
x: String,
y: String, z: String) {
this.x = x
this.y = y
this.z = z
}
}
class A1(
val x: String,
y: String,
)
class B1(
val x: String,
val y: String
)
class C1(
val x: String,
val y: String,)
class D1(
val x: String,
val y: String
,)
class A2(
val x: String,
val y: String,
val z: String,
)
class B2(
val x: String,
val y: String,
val z: String
)
class C2(
val x: String,
val y: String,
val z: String,)
class D2(
val x: String,
val y: String,
val z: String
,)
class A3(
val x: String,
)
class B3(
val x: String
)
class C3(
val x: String,)
class D3(
val x: String
,)
class A4(
val x: String ,
val y: String,
val z: String ,
)
class B4(
val x: String,
val y: String,
val z: String
)
class C4(
val x: String,
val y: String,
val z: String ,)
class D4(
val x: String,
val y: String,
val z: String
, )
class E1(
val x: String, val y: String,
val z: String
, )
class E2(
val x: String, val y: String, val z: String
)
class C(
z: String, val v: Int, val x: Int =
42, val y: Int =
42
)
val foo1: (Int, Int) -> Int = fun(
x,
y,
): Int = 42
val foo2: (Int, Int) -> Int = fun(
x,
y
): Int {
return x + y
}
val foo3: (Int, Int) -> Int = fun(
x, y,
): Int {
return x + y
}
val foo4: (Int) -> Int = fun(
x,
): Int = 42
val foo5: (Int) -> Int = fun(
x
): Int = 42
val foo6: (Int) -> Int = fun(x,): Int = 42
val foo7: (Int) -> Int = fun(x): Int = 42
val foo8: (Int, Int, Int) -> Int = fun (x, y: Int, z,): Int {
return x + y
}
val foo9: (Int, Int, Int) -> Int = fun (
x,
y: Int,
z,
): Int = 42
val foo10: (Int, Int, Int) -> Int = fun (
x,
y: Int,
z: Int
): Int = 43
val foo10 = fun (
x: Int,
y: Int,
z: Int
): Int = 43
val foo11 = fun (
x: Int,
y: Int,
z: Int,
): Int = 43
val foo12 = fun (
x: Int, y: Int, z: Int,
): Int = 43
val foo13 = fun (x: Int, y: Int, z: Int,
): Int = 43
val foo14 = fun (x: Int, y: Int, z: Int
,): Int = 43
fun a1(
x: String,
y: String,
) = Unit
fun b1(
x: String,
y: String
) = Unit
fun c1(
x: String,
y: String,) = Unit
fun d1(
x: String,
y: String
,) = Unit
fun a2(
x: String,
y: String,
z: String,
) = Unit
fun b2(
x: String,
y: String,
z: String
) = Unit
fun c2(
x: String,
y: String,
z: String,) = Unit
fun d2(
x: String,
y: String,
z: String
,) = Unit
fun a3(
x: String,
) = Unit
fun b3(
x: String
) = Unit
fun c3(
x: String,) = Unit
fun d3(
x: String
,) = Unit
fun a4(
x: String
,
y: String,
z: String ,
) = Unit
fun b4(
x: String,
y: String,
z: String
) = Unit
fun c4(x: String,
y: String,
z: String ,) = Unit
fun d4(
x: String,
y: String,
z: String
, ) = Unit
fun foo(
x: Int =
42
) {
}
class C(
val x: Int =
42
)
class G(
val x: String, val y: String
= "", /* */ val z: String
)
class G(
val x: String, val y: String
= "" /* */, /* */ val z: String
)
class H(
val x: String, /*
*/ val y: String,
val z: String ,)
class J(
val x: String, val y: String , val z: String /*
*/
, )
class K(
val x: String, val y: String,
val z: String
, )
class L(
val x: String, val y: String, val z: String // adwd
)
@@ -0,0 +1,113 @@
fun foo() {
testtest<foofoo,
testtest<testtest<
foofoo,
>,
>,
testsa,
>()
testtest<foofoo, foofoo, foofoo,
foofoo, bar>()
testtest<
foofoo, foofoo, foofoo, foofoo, bar
>()
testtest<foofoo, foofoo, foofoo, foofoo, bar
>()
testtest<foofoo, foofoo, foofoo, foofoo,
bar
>()
testtest<foofoo
>()
testtest<
foofoo>()
testtest<
foofoo
>()
testtest<foofoo,>()
testtest<foofoo, testtest<testtest<foofoo>>>()
testtest<foofoo, fososos, testtest<testtest<foofoo>>,>()
testtest<foofoo, fososos, testtest<testtest<foofoo>>
,>()
testtest<foofoo, testtest<testtest<foofoo,>>, testsa>()
testtest<foofoo, *, testtest<testtest<foofoo,>>, testsa>()
testtest<
foofoo, foofoo, foofoo, foofoo,
bar /*
*/, /* */ foo
>()
testtest</*
*/foofoo, foofoo, foofoo, /*
*/
foofoo, bar>()
testtest<foofoo, foofoo, foofoo, foofoo, bar/*
*/>()
testtest<foofoo, foofoo, foofoo, foofoo, bar // awdawda
>()
testtest<foofoo, foofoo, foofoo, foofoo, /*
*/
bar
>()
testtest<foofoo // fd
>()
testtest< /**/
foofoo
>()
testtest<foofoo,/**/>()
testtest<foofoo, foofoo, foofoo, foofoo/*
*/ , /* */ bar
>()
testtest<foofoo // fd
>()
testtest< /**/
foofoo
>()
testtest<foofoo,/**/>()
testtest<foofoo,/*
*/>()
testtest<
foofoo,/**/>()
testtest<foofoo, fososos,/*
*/ testtest<testtest<foofoo>>,>()
testtest<foofoo, testtest<testtest<foofoo,>>, /**/testsa>()
testtest<foofoo, testtest<testtest<foofoo,>>/* */ , /**/testsa>()
testtest<foofoo, testtest<testtest<foofoo,>>/*
*/ ,testsa>()
testtest<foofoo, seee, testtest<testtest<foofoo,>>, /**/testsa>()
testtest<foofoo, seee, testtest<testtest<foofoo,>>, /*
*/testsa>()
}
@@ -0,0 +1,261 @@
class A1<
x: String,
y: String,
>
class F<x: String, y: String>
class F2<x: String, y
: String>
class B1<
x: String,
y: String
>
class C1<
x: String,
y: String,>
class D1<
x: String,
y: String
,>
class A2<
x: String,
y: String,
z: String,
>
class B2<
x: String,
y: String,
z: String
>
class C2<
x: String,
y: String,
z: String,>
class D2<
x: String,
y: String,
z: String
,>
class A3<
x: String,
>
class B3<
x: String
>
class C3<
x: String,>
class D3<
x: String
,>
class A4<
x: String ,
y: String,
z ,
>
class B4<
x: String,
y,
z: String
>
class C4<
x: String,
y: String,
z: String ,>
class D4<
x: String,
y,
z: String
, >
class E1<
x, y: String,
z: String
, >
class E2<
x: String, y: String, z: String
>
class C<
z: String, v
>
fun <x: String,
y: String,
> a1() = Unit
fun <x: String,
y: String
> b1() = Unit
fun <
x: String,
y: String,> c1() = Unit
fun <
x: String,
y: String
,> d1() = Unit
fun <
x: String,
y: String,
z: String,
> a2() = Unit
fun <
x: String,
y: String,
z: String
> b2() = Unit
fun <
x: String,
y: String,
z: String,> c2() = Unit
fun <
x: String,
y: String,
z: String
,> d2() = Unit
fun <
x: String,
> a3() = Unit
fun <
x: String
> b3() = Unit
fun <
x: String,> c3() = Unit
fun <
x: String
,> d3() = Unit
fun <
x: String
,
y: String,
z: String ,
> a4() = Unit
fun <
x: String,
y: String,
z: String
> b4() = Unit
fun <x: String,
y: String,
z: String ,> c4() = Unit
fun <
x: String,
y: String,
z: String
, > d4() = Unit
fun <
x
> foo() {
}
fun <T> ag() {
}
fun <T,> ag() {
}
fun <
T> ag() {
}
class C<
x: Int
>
class G<
x: String, y: String
, /* */ z: String
>
class G<
x: String, y: String
/* */, /* */ z: String
>()
class H<
x: String, /*
*/ y: String,
z: String ,>
class J<
x: String, y: String , z: String /*
*/
, >
class K<
x: String, y: String,
z: String
, >
class L<
x: String, y: String, z: String
>
class C<
x: Int // adad
>
class G<
x: String, y: String
, /* */ z: String // adad
>
class G<
x: String, y: String
/* */, /* */ z: String /**/,
>()
class H<
x: String, /*
*/ y: String,
z: String /*
*/ ,>
class J<
x: String, y: String , z: String /*
*/
, /**/ >
class K<
x: String, y: String,
z: String // aw
, >
class L<
x: String, y: String, z: String //awd
>
@@ -0,0 +1,75 @@
fun foo(x: Any) = when (x) {
Comparable::class, Iterable::class, String::class, // trailing comma
-> println(1)
else -> println(3)
}
fun foo(x: Any) {
when (x) {
Comparable::class, Iterable::class, String::class /*// trailing comma*/ -> println(1)
else -> println(3)
}
when (x) {
Comparable::class, Iterable::class,
String::class /*// trailing comma*/ -> println(1)
else -> println(3)
}
when (x) {
Comparable::class, Iterable::class,
String::class /*// trailing comma*/, -> println(1)
else -> println(3)
}
when (x) {
Comparable::class, Iterable::class, String::class /*// trailing comma*/ -> println(1)
else -> println(3)
}
when (x) {
1 -> {
}
else -> println(3)
}
when (x) {
1, -> {
}
else -> println(3)
}
when (x) {
1
-> {
}
else -> println(3)
}
when (x) {
1, 2,
3 /**/ -> {
}
else -> println(3)
}
when (val c = x) {
1, 2,
3 /**/ -> {
}
else -> println(3)
}
when {
x in coll
-> {
}
else -> println(3)
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,3 @@
// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.TrailingCommaInspection
// COMPILER_ARGUMENTS: -XXLanguage:+TrailingCommas
// REGISTRY: kotlin.formatter.allowTrailingCommaOnCallSite true
File diff suppressed because it is too large Load Diff
@@ -18,10 +18,7 @@ import org.jdom.input.SAXBuilder
import org.jetbrains.kotlin.formatter.FormatSettingsUtil
import org.jetbrains.kotlin.idea.core.script.isScriptChangesNotifierDisabled
import org.jetbrains.kotlin.idea.inspections.runInspection
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.TestFixtureExtension
import org.jetbrains.kotlin.idea.test.configureCompilerOptions
import org.jetbrains.kotlin.idea.test.rollbackCompilerOptions
import org.jetbrains.kotlin.idea.test.*
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
import org.jetbrains.kotlin.test.InTextDirectivesUtils
@@ -96,7 +93,7 @@ abstract class AbstractInspectionTest : KotlinLightCodeInsightFixtureTestCase()
if (forceUsePackageFolder) {
val packageName = fileText.substring(
"package".length,
fileText.indexOfAny(charArrayOf(';', '\n'))
fileText.indexOfAny(charArrayOf(';', '\n')),
).trim()
val projectFileName = packageName.replace('.', '/') + "/" + file.name
addFileToProject(projectFileName, fileText)
@@ -117,39 +114,45 @@ abstract class AbstractInspectionTest : KotlinLightCodeInsightFixtureTestCase()
}.toList()
val codeStyleSettings = CodeStyle.getSettings(project)
try {
FormatSettingsUtil.createConfigurator(options, codeStyleSettings).configureSettings()
fixtureClasses.forEach { TestFixtureExtension.loadFixture(it, myFixture.module) }
configureRegistryAndRun(options) {
try {
FormatSettingsUtil.createConfigurator(options, codeStyleSettings).configureSettings()
fixtureClasses.forEach { TestFixtureExtension.loadFixture(it, myFixture.module) }
configExtra(psiFiles, options)
configExtra(psiFiles, options)
val presentation = runInspection(
inspectionClass, project,
settings = settingsElement,
files = psiFiles.map { it.virtualFile!! }, withTestDir = inspectionsTestDir.path
)
val presentation = runInspection(
inspectionClass, project,
settings = settingsElement,
files = psiFiles.map { it.virtualFile!! }, withTestDir = inspectionsTestDir.path,
)
if (afterFiles.isNotEmpty()) {
presentation.problemDescriptors.forEach { problem ->
problem.fixes?.forEach {
CommandProcessor.getInstance().executeCommand(project, {
runWriteAction { it.applyFix(project, problem) }
}, it.name, it.familyName)
if (afterFiles.isNotEmpty()) {
presentation.problemDescriptors.forEach { problem ->
problem.fixes?.forEach {
CommandProcessor.getInstance().executeCommand(
project,
{
runWriteAction { it.applyFix(project, problem) }
},
it.name, it.familyName,
)
}
}
for (filePath in afterFiles) {
val kotlinFile = psiFiles.first { filePath.name == it.name + ".after" }
KotlinTestUtils.assertEqualsToFile(filePath, kotlinFile.text)
}
}
for (filePath in afterFiles) {
val kotlinFile = psiFiles.first { filePath.name == it.name + ".after" }
KotlinTestUtils.assertEqualsToFile(filePath, kotlinFile.text)
} finally {
codeStyleSettings.clearCodeStyleSettings()
if (configured) {
rollbackCompilerOptions(project, module)
}
fixtureClasses.forEach { TestFixtureExtension.unloadFixture(it) }
}
} finally {
codeStyleSettings.clearCodeStyleSettings()
if (configured) {
rollbackCompilerOptions(project, module)
}
fixtureClasses.forEach { TestFixtureExtension.unloadFixture(it) }
}
}
}
@@ -388,6 +388,11 @@ public class InspectionTestGenerated extends AbstractInspectionTest {
runTest("idea/testData/inspections/trailingCommaOnWithCodeStyle/inspectionData/inspections.test");
}
@TestMetadata("trailingCommaOnWithCodeStyleAndCallSite/inspectionData/inspections.test")
public void testTrailingCommaOnWithCodeStyleAndCallSite_inspectionData_Inspections_test() throws Exception {
runTest("idea/testData/inspections/trailingCommaOnWithCodeStyleAndCallSite/inspectionData/inspections.test");
}
@TestMetadata("trailingCommaOnWithoutCodeStyle/inspectionData/inspections.test")
public void testTrailingCommaOnWithoutCodeStyle_inspectionData_Inspections_test() throws Exception {
runTest("idea/testData/inspections/trailingCommaOnWithoutCodeStyle/inspectionData/inspections.test");
-8
View File
@@ -54,11 +54,3 @@ org.jetbrains.kotlin.psi.injection.StringInterpolationInjectionTest.testInterpol
org.jetbrains.kotlin.shortenRefs.ShortenRefsTestGenerated.testExtensionForObject2, Always red
org.jetbrains.kotlin.util.KotlinVersionsTest.testVersionsAreConsistent, KT-35567
org.jetbrains.kotlinx.serialization.SerializationIrBytecodeListingTestGenerated.testBasic, Broken between 20 nov and 10 dec
org.jetbrains.kotlin.idea.inspections.LocalInspectionTestGenerated.TrailingComma.testAddComma
org.jetbrains.kotlin.idea.inspections.LocalInspectionTestGenerated.TrailingComma.testAddComma2
org.jetbrains.kotlin.idea.inspections.LocalInspectionTestGenerated.TrailingComma.testAddComma5
org.jetbrains.kotlin.idea.inspections.LocalInspectionTestGenerated.TrailingComma.testAddComma6
org.jetbrains.kotlin.idea.inspections.LocalInspectionTestGenerated.TrailingComma.testChangeCommaPosition
org.jetbrains.kotlin.idea.inspections.LocalInspectionTestGenerated.TrailingComma.testChangeCommaPosition2
org.jetbrains.kotlin.idea.inspections.LocalInspectionTestGenerated.TrailingComma.testMissingLineBreak
org.jetbrains.kotlin.idea.inspections.LocalInspectionTestGenerated.TrailingComma.testMissingLineBreak2
Can't render this file because it contains an unexpected character in line 12 and column 132.