Add intentions to put arguments / parameters on one line #KT-23266 Fixed

This commit is contained in:
Toshiaki Kameyama
2018-03-26 15:49:49 +03:00
committed by Mikhail Glukhikh
parent 96581f1ecb
commit 03902030ed
28 changed files with 285 additions and 33 deletions
+10
View File
@@ -1572,6 +1572,16 @@
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.JoinParameterListIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.JoinArgumentListIntention</className>
<category>Kotlin</category>
</intentionAction>
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
displayName="Object literal can be converted to lambda"
groupPath="Kotlin"
@@ -29,9 +29,9 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.psi.psiUtil.startOffset
abstract class AbstractChopListIntention<TList : KtElement, TElement : KtElement>(
private val listClass: Class<TList>,
private val elementClass: Class<TElement>,
text: String
private val listClass: Class<TList>,
private val elementClass: Class<TElement>,
text: String
) : SelfTargetingOffsetIndependentIntention<TList>(listClass, text), LowPriorityAction {
override fun isApplicableTo(element: TList): Boolean {
@@ -41,20 +41,20 @@ abstract class AbstractChopListIntention<TList : KtElement, TElement : KtElement
return true
}
override fun applyTo(list: TList, editor: Editor?) {
val project = list.project
override fun applyTo(element: TList, editor: Editor?) {
val project = element.project
val document = editor!!.document
val startOffset = list.startOffset
val startOffset = element.startOffset
val elements = list.elements()
val elements = element.elements()
if (!hasLineBreakAfter(elements.last())) {
val rpar = list.allChildren.lastOrNull { it.node.elementType == KtTokens.RPAR }
val rpar = element.allChildren.lastOrNull { it.node.elementType == KtTokens.RPAR }
rpar?.startOffset?.let { document.insertString(it, "\n") }
}
for (element in elements.asReversed()) {
if (!hasLineBreakBefore(element)) {
document.insertString(element.startOffset, "\n")
for (e in elements.asReversed()) {
if (!hasLineBreakBefore(e)) {
document.insertString(e.startOffset, "\n")
}
}
@@ -65,35 +65,43 @@ abstract class AbstractChopListIntention<TList : KtElement, TElement : KtElement
CodeStyleManager.getInstance(project).adjustLineIndent(psiFile, newList.textRange)
}
private fun hasLineBreakAfter(element: TElement): Boolean {
return element
.siblings(withItself = false)
.takeWhile { !elementClass.isInstance(it) }
.any { it is PsiWhiteSpace && it.textContains('\n') }
protected fun hasLineBreakAfter(element: TElement): Boolean {
return nextBreak(element) != null
}
private fun hasLineBreakBefore(element: TElement): Boolean {
protected fun nextBreak(element: TElement): PsiWhiteSpace? {
return element
.siblings(withItself = false, forward = false)
.takeWhile { !elementClass.isInstance(it) }
.any { it is PsiWhiteSpace && it.textContains('\n') }
.siblings(withItself = false)
.takeWhile { !elementClass.isInstance(it) }
.firstOrNull { it is PsiWhiteSpace && it.textContains('\n') } as? PsiWhiteSpace
}
private fun TList.elements(): List<TElement> {
protected fun hasLineBreakBefore(element: TElement): Boolean {
return prevBreak(element) != null
}
protected fun prevBreak(element: TElement): PsiWhiteSpace? {
return element
.siblings(withItself = false, forward = false)
.takeWhile { !elementClass.isInstance(it) }
.firstOrNull { it is PsiWhiteSpace && it.textContains('\n') } as? PsiWhiteSpace
}
protected fun TList.elements(): List<TElement> {
return allChildren
.filter { elementClass.isInstance(it) }
.map {
@Suppress("UNCHECKED_CAST")
it as TElement
}
.toList()
.filter { elementClass.isInstance(it) }
.map {
@Suppress("UNCHECKED_CAST")
it as TElement
}
.toList()
}
}
class ChopParameterListIntention : AbstractChopListIntention<KtParameterList, KtParameter>(
KtParameterList::class.java,
KtParameter::class.java,
"Put parameters on separate lines"
KtParameterList::class.java,
KtParameter::class.java,
"Put parameters on separate lines"
) {
override fun isApplicableTo(element: KtParameterList): Boolean {
if (element.parent is KtFunctionLiteral) return false
@@ -102,7 +110,7 @@ class ChopParameterListIntention : AbstractChopListIntention<KtParameterList, Kt
}
class ChopArgumentListIntention : AbstractChopListIntention<KtValueArgumentList, KtValueArgument>(
KtValueArgumentList::class.java,
KtValueArgument::class.java,
"Put arguments on separate lines"
KtValueArgumentList::class.java,
KtValueArgument::class.java,
"Put arguments on separate lines"
)
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.intentions
import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.psi.*
abstract class AbstractJoinListIntention<TList : KtElement, TElement : KtElement>(
listClass: Class<TList>,
elementClass: Class<TElement>,
text: String
) : AbstractChopListIntention<TList, TElement>(listClass, elementClass, text) {
override fun isApplicableTo(element: TList): Boolean {
val elements = element.elements()
if (elements.isEmpty()) return false
return hasLineBreakBefore(elements.first()) || elements.any { hasLineBreakAfter(it) }
}
override fun applyTo(element: TList, editor: Editor?) {
val elements = element.elements()
prevBreak(elements.first())?.delete()
elements.forEach { nextBreak(it)?.delete() }
}
}
class JoinParameterListIntention : AbstractJoinListIntention<KtParameterList, KtParameter>(
KtParameterList::class.java,
KtParameter::class.java,
"Put parameters on one line"
) {
override fun isApplicableTo(element: KtParameterList): Boolean {
if (element.parent is KtFunctionLiteral) return false
return super.isApplicableTo(element)
}
}
class JoinArgumentListIntention : AbstractJoinListIntention<KtValueArgumentList, KtValueArgument>(
KtValueArgumentList::class.java,
KtValueArgument::class.java,
"Put arguments on one line"
)