Formatter: fix line break between declarations with comment
#KT-12490 Fixed #KT-35088 Fixed
This commit is contained in:
@@ -17,7 +17,8 @@ import com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.idea.util.requireNode
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import java.util.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.children
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtModifierListElementType
|
||||
import kotlin.math.max
|
||||
|
||||
fun CommonCodeStyleSettings.createSpaceBeforeRBrace(numSpacesOtherwise: Int, textRange: TextRange): Spacing? {
|
||||
@@ -103,13 +104,20 @@ class KotlinSpacingBuilder(val commonCodeStyleSettings: CommonCodeStyleSettings,
|
||||
val lastChild = left.node?.psi?.lastChild
|
||||
val leftEndsWithComment = lastChild is PsiComment && lastChild.tokenType == KtTokens.EOL_COMMENT
|
||||
val dependentSpacingRule = DependentSpacingRule(Trigger.HAS_LINE_FEEDS).registerData(Anchor.MIN_LINE_FEEDS, emptyLines + 1)
|
||||
val textRange = left.node
|
||||
?.children()
|
||||
?.firstOrNull { it.elementType !in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET }
|
||||
?.startOffset
|
||||
?.let { TextRange.create(it, left.textRange.endOffset) }
|
||||
?: left.textRange
|
||||
|
||||
spacingBuilderUtil.createLineFeedDependentSpacing(
|
||||
numSpacesOtherwise,
|
||||
numSpacesOtherwise,
|
||||
if (leftEndsWithComment) max(1, numberOfLineFeedsOtherwise) else numberOfLineFeedsOtherwise,
|
||||
commonCodeStyleSettings.KEEP_LINE_BREAKS,
|
||||
commonCodeStyleSettings.KEEP_BLANK_LINES_IN_DECLARATIONS,
|
||||
left.textRange,
|
||||
textRange,
|
||||
dependentSpacingRule
|
||||
)
|
||||
}
|
||||
@@ -200,3 +208,8 @@ fun rules(
|
||||
builder.init()
|
||||
return builder
|
||||
}
|
||||
|
||||
internal fun ASTNode.startOfDeclaration(): ASTNode? = children().firstOrNull {
|
||||
val elementType = it.elementType
|
||||
elementType !is KtModifierListElementType<*> && elementType !in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.intellij.formatting.SpacingBuilder
|
||||
import com.intellij.formatting.SpacingBuilder.RuleBuilder
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings
|
||||
@@ -32,6 +33,8 @@ val MODIFIERS_LIST_ENTRIES = TokenSet.orSet(TokenSet.create(ANNOTATION_ENTRY, AN
|
||||
val EXTEND_COLON_ELEMENTS =
|
||||
TokenSet.create(TYPE_CONSTRAINT, CLASS, OBJECT_DECLARATION, TYPE_PARAMETER, ENUM_ENTRY, SECONDARY_CONSTRUCTOR)
|
||||
|
||||
val DECLARATIONS = TokenSet.create(PROPERTY, FUN, CLASS, OBJECT_DECLARATION, ENUM_ENTRY, SECONDARY_CONSTRUCTOR, CLASS_INITIALIZER)
|
||||
|
||||
fun SpacingBuilder.beforeInside(element: IElementType, tokenSet: TokenSet, spacingFun: RuleBuilder.() -> Unit) {
|
||||
tokenSet.types.forEach { inType -> beforeInside(element, inType).spacingFun() }
|
||||
}
|
||||
@@ -47,9 +50,6 @@ fun createSpacingBuilder(settings: CodeStyleSettings, builderUtil: KotlinSpacing
|
||||
val kotlinCommonSettings = settings.kotlinCommonSettings
|
||||
val kotlinCustomSettings = settings.kotlinCustomSettings
|
||||
return rules(kotlinCommonSettings, builderUtil) {
|
||||
val DECLARATIONS =
|
||||
TokenSet.create(PROPERTY, FUN, CLASS, OBJECT_DECLARATION, ENUM_ENTRY, SECONDARY_CONSTRUCTOR, CLASS_INITIALIZER)
|
||||
|
||||
simple {
|
||||
before(FILE_ANNOTATION_LIST).lineBreakInCode()
|
||||
after(FILE_ANNOTATION_LIST).blankLines(1)
|
||||
@@ -87,8 +87,21 @@ fun createSpacingBuilder(settings: CodeStyleSettings, builderUtil: KotlinSpacing
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
inPosition(right = BLOCK_COMMENT).spacing(commentSpacing(0))
|
||||
inPosition(right = EOL_COMMENT).spacing(commentSpacing(1))
|
||||
inPosition(leftSet = DECLARATIONS, rightSet = DECLARATIONS).customRule(fun(
|
||||
_: ASTBlock,
|
||||
_: ASTBlock,
|
||||
right: ASTBlock
|
||||
): Spacing? {
|
||||
val firstChild = right.node?.firstChildNode as? PsiComment ?: return null
|
||||
val whiteSpace = firstChild.nextSibling as? PsiWhiteSpace ?: return null
|
||||
return if (StringUtil.containsLineBreak(firstChild.text) || StringUtil.containsLineBreak(whiteSpace.text)) {
|
||||
createSpacing(0, minLineFeeds = 2)
|
||||
} else
|
||||
null
|
||||
})
|
||||
|
||||
inPosition(left = CLASS, right = CLASS).emptyLinesIfLineBreakInLeft(1)
|
||||
inPosition(left = CLASS, right = OBJECT_DECLARATION).emptyLinesIfLineBreakInLeft(1)
|
||||
|
||||
Reference in New Issue
Block a user