Formatter: support trailing comma in destruction declarations

#KT-34744
This commit is contained in:
Dmitry Gridin
2019-12-30 20:52:54 +07:00
parent 96a11707ca
commit b72da6c4fc
11 changed files with 700 additions and 18 deletions
@@ -642,6 +642,23 @@ abstract class KotlinCommonBlock(
}
}
elementType === DESTRUCTURING_DECLARATION -> {
nodePsi as KtDestructuringDeclaration
if (nodePsi.valOrVarKeyword == null) return defaultTrailingCommaWrappingStrategy(LPAR, RPAR)
else if (nodePsi.needTrailingComma(settings)) {
val check = thisOrPrevIsMultiLineElement(COMMA, LPAR, RPAR)
return block@{ childElement ->
val childElementType = childElement.elementType
if (childElementType === EQ) return@block null
createWrapAlwaysIf(
childElementType === RPAR ||
getSiblingWithoutWhitespaceAndComments(childElement)?.elementType === LPAR ||
getSiblingWithoutWhitespaceAndComments(childElement, true) != null && check(childElement)
)
}
}
}
elementType === INDICES -> return defaultTrailingCommaWrappingStrategy(LBRACKET, RBRACKET)
elementType === TYPE_PARAMETER_LIST -> return defaultTrailingCommaWrappingStrategy(LT, GT)
@@ -13,12 +13,11 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.codeStyle.CodeStyleSettings
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
import org.jetbrains.kotlin.idea.formatter.kotlinCustomSettings
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtFunctionLiteral
import org.jetbrains.kotlin.psi.KtWhenEntry
import org.jetbrains.kotlin.psi.KtWhenExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
/*
* ASTBlock.node is nullable, this extension was introduced to minimize changes
@@ -48,22 +47,38 @@ fun PsiElement.getLineCount(): Int {
fun PsiElement.isMultiline() = getLineCount() > 1
fun KtFunctionLiteral.needTrailingComma(settings: CodeStyleSettings): Boolean = valueParameterList?.trailingComma != null ||
settings.kotlinCustomSettings.ALLOW_TRAILING_COMMA &&
run(fun(): Boolean {
val startOffset = valueParameterList?.startOffset ?: return false
val endOffset = arrow?.endOffset ?: return false
return containsLineBreakInThis(startOffset, endOffset)
})
fun KtFunctionLiteral.needTrailingComma(settings: CodeStyleSettings): Boolean = needTrailingComma(
settings = settings,
trailingComma = { valueParameterList?.trailingComma },
globalStartOffset = { valueParameterList?.startOffset },
globalEndOffset = { arrow?.endOffset }
)
fun KtWhenEntry.needTrailingComma(settings: CodeStyleSettings): Boolean = trailingComma != null ||
!isElse &&
settings.kotlinCustomSettings.ALLOW_TRAILING_COMMA &&
parent.safeAs<KtWhenExpression>()?.leftParenthesis != null &&
run(fun(): Boolean {
val endOffset = arrow?.endOffset ?: return false
return containsLineBreakInThis(startOffset, endOffset)
})
fun KtWhenEntry.needTrailingComma(settings: CodeStyleSettings): Boolean = needTrailingComma(
settings = settings,
trailingComma = { trailingComma },
additionalCheck = { !isElse },
globalEndOffset = { arrow?.endOffset }
)
fun KtDestructuringDeclaration.needTrailingComma(settings: CodeStyleSettings): Boolean = needTrailingComma(
settings = settings,
trailingComma = { trailingComma },
globalStartOffset = { lPar?.startOffset },
globalEndOffset = { rPar?.endOffset }
)
fun <T : PsiElement> T.needTrailingComma(
settings: CodeStyleSettings,
trailingComma: T.() -> PsiElement?,
additionalCheck: () -> Boolean = { true },
globalStartOffset: T.() -> Int? = PsiElement::startOffset,
globalEndOffset: T.() -> Int? = PsiElement::endOffset
) = trailingComma() != null || settings.kotlinCustomSettings.ALLOW_TRAILING_COMMA && additionalCheck() && run(fun(): Boolean {
val startOffset = globalStartOffset() ?: return false
val endOffset = globalEndOffset() ?: return false
return containsLineBreakInThis(startOffset, endOffset)
})
fun PsiElement.containsLineBreakInThis(globalStartOffset: Int, globalEndOffset: Int): Boolean {
val textRange = TextRange.create(globalStartOffset, globalEndOffset).shiftLeft(startOffset)