Reformat
This commit is contained in:
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2000-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.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.formatter
|
package org.jetbrains.kotlin.idea.formatter
|
||||||
@@ -61,18 +50,22 @@ val CodeStyleSettings.kotlinCustomSettings: KotlinCodeStyleSettings
|
|||||||
get() = getCustomSettings(KotlinCodeStyleSettings::class.java)!!
|
get() = getCustomSettings(KotlinCodeStyleSettings::class.java)!!
|
||||||
|
|
||||||
abstract class KotlinCommonBlock(
|
abstract class KotlinCommonBlock(
|
||||||
private val node: ASTNode,
|
private val node: ASTNode,
|
||||||
private val settings: CodeStyleSettings,
|
private val settings: CodeStyleSettings,
|
||||||
private val spacingBuilder: KotlinSpacingBuilder,
|
private val spacingBuilder: KotlinSpacingBuilder,
|
||||||
private val alignmentStrategy: CommonAlignmentStrategy) {
|
private val alignmentStrategy: CommonAlignmentStrategy
|
||||||
private @Volatile var mySubBlocks: List<ASTBlock>? = null
|
) {
|
||||||
|
private @Volatile
|
||||||
|
var mySubBlocks: List<ASTBlock>? = null
|
||||||
|
|
||||||
abstract protected fun createBlock(node: ASTNode,
|
abstract protected fun createBlock(
|
||||||
alignmentStrategy: CommonAlignmentStrategy,
|
node: ASTNode,
|
||||||
indent: Indent?,
|
alignmentStrategy: CommonAlignmentStrategy,
|
||||||
wrap: Wrap?,
|
indent: Indent?,
|
||||||
settings: CodeStyleSettings,
|
wrap: Wrap?,
|
||||||
spacingBuilder: KotlinSpacingBuilder): ASTBlock
|
settings: CodeStyleSettings,
|
||||||
|
spacingBuilder: KotlinSpacingBuilder
|
||||||
|
): ASTBlock
|
||||||
|
|
||||||
abstract protected fun createSyntheticSpacingNodeBlock(node: ASTNode): ASTBlock
|
abstract protected fun createSyntheticSpacingNodeBlock(node: ASTNode): ASTBlock
|
||||||
|
|
||||||
@@ -101,8 +94,7 @@ abstract class KotlinCommonBlock(
|
|||||||
|
|
||||||
if (node.elementType in QUALIFIED_EXPRESSIONS) {
|
if (node.elementType in QUALIFIED_EXPRESSIONS) {
|
||||||
nodeSubBlocks = splitSubBlocksOnDot(nodeSubBlocks)
|
nodeSubBlocks = splitSubBlocksOnDot(nodeSubBlocks)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val psi = node.psi
|
val psi = node.psi
|
||||||
if (psi is KtBinaryExpression && psi.operationToken == KtTokens.ELVIS) {
|
if (psi is KtBinaryExpression && psi.operationToken == KtTokens.ELVIS) {
|
||||||
nodeSubBlocks = splitSubBlocksOnElvis(nodeSubBlocks)
|
nodeSubBlocks = splitSubBlocksOnElvis(nodeSubBlocks)
|
||||||
@@ -125,10 +117,12 @@ abstract class KotlinCommonBlock(
|
|||||||
else
|
else
|
||||||
Indent.Type.NORMAL
|
Indent.Type.NORMAL
|
||||||
val isNonFirstChainedCall = operationBlockIndex > 0 && isCallBlock(nodeSubBlocks[operationBlockIndex - 1])
|
val isNonFirstChainedCall = operationBlockIndex > 0 && isCallBlock(nodeSubBlocks[operationBlockIndex - 1])
|
||||||
val indent = Indent.getIndent(indentType, false,
|
val indent = Indent.getIndent(
|
||||||
isNonFirstChainedCall && hasLineBreakBefore(nodeSubBlocks[operationBlockIndex - 1]))
|
indentType, false,
|
||||||
|
isNonFirstChainedCall && hasLineBreakBefore(nodeSubBlocks[operationBlockIndex - 1])
|
||||||
|
)
|
||||||
val wrap = if ((settings.kotlinCommonSettings.WRAP_FIRST_METHOD_IN_CALL_CHAIN || isNonFirstChainedCall) &&
|
val wrap = if ((settings.kotlinCommonSettings.WRAP_FIRST_METHOD_IN_CALL_CHAIN || isNonFirstChainedCall) &&
|
||||||
canWrapCallChain(node))
|
canWrapCallChain(node))
|
||||||
Wrap.createWrap(settings.kotlinCommonSettings.METHOD_CALL_CHAIN_WRAP, true)
|
Wrap.createWrap(settings.kotlinCommonSettings.METHOD_CALL_CHAIN_WRAP, true)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
@@ -141,9 +135,10 @@ abstract class KotlinCommonBlock(
|
|||||||
private fun List<ASTBlock>.splitAtIndex(index: Int, indent: Indent?, wrap: Wrap?): List<ASTBlock> {
|
private fun List<ASTBlock>.splitAtIndex(index: Int, indent: Indent?, wrap: Wrap?): List<ASTBlock> {
|
||||||
val operationBlock = this[index]
|
val operationBlock = this[index]
|
||||||
val operationSyntheticBlock = SyntheticKotlinBlock(
|
val operationSyntheticBlock = SyntheticKotlinBlock(
|
||||||
operationBlock.node,
|
operationBlock.node,
|
||||||
subList(index, size),
|
subList(index, size),
|
||||||
null, indent, wrap, spacingBuilder) { createSyntheticSpacingNodeBlock(it) }
|
null, indent, wrap, spacingBuilder
|
||||||
|
) { createSyntheticSpacingNodeBlock(it) }
|
||||||
|
|
||||||
return subList(0, index) + operationSyntheticBlock
|
return subList(0, index) + operationSyntheticBlock
|
||||||
}
|
}
|
||||||
@@ -156,19 +151,19 @@ abstract class KotlinCommonBlock(
|
|||||||
private fun canWrapCallChain(node: ASTNode): Boolean {
|
private fun canWrapCallChain(node: ASTNode): Boolean {
|
||||||
val callChainParent = node.parents().firstOrNull { it.elementType !in QUALIFIED_EXPRESSIONS } ?: return true
|
val callChainParent = node.parents().firstOrNull { it.elementType !in QUALIFIED_EXPRESSIONS } ?: return true
|
||||||
return callChainParent.elementType in CODE_BLOCKS ||
|
return callChainParent.elementType in CODE_BLOCKS ||
|
||||||
callChainParent.elementType == KtNodeTypes.PROPERTY ||
|
callChainParent.elementType == KtNodeTypes.PROPERTY ||
|
||||||
(callChainParent.elementType == KtNodeTypes.BINARY_EXPRESSION &&
|
(callChainParent.elementType == KtNodeTypes.BINARY_EXPRESSION &&
|
||||||
(callChainParent.psi as KtBinaryExpression).operationToken in KtTokens.ALL_ASSIGNMENTS) ||
|
(callChainParent.psi as KtBinaryExpression).operationToken in KtTokens.ALL_ASSIGNMENTS) ||
|
||||||
callChainParent.elementType == KtNodeTypes.RETURN
|
callChainParent.elementType == KtNodeTypes.RETURN
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun splitSubBlocksOnElvis(nodeSubBlocks: List<ASTBlock>): List<ASTBlock> {
|
private fun splitSubBlocksOnElvis(nodeSubBlocks: List<ASTBlock>): List<ASTBlock> {
|
||||||
val elvisIndex = nodeSubBlocks.indexOfBlockWithType(ELVIS_SET)
|
val elvisIndex = nodeSubBlocks.indexOfBlockWithType(ELVIS_SET)
|
||||||
if (elvisIndex >= 0) {
|
if (elvisIndex >= 0) {
|
||||||
return nodeSubBlocks.splitAtIndex(
|
return nodeSubBlocks.splitAtIndex(
|
||||||
elvisIndex,
|
elvisIndex,
|
||||||
Indent.getContinuationIndent(),
|
Indent.getContinuationIndent(),
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nodeSubBlocks
|
return nodeSubBlocks
|
||||||
@@ -245,7 +240,10 @@ abstract class KotlinCommonBlock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return when (type) {
|
return when (type) {
|
||||||
in CODE_BLOCKS, KtNodeTypes.WHEN, KtNodeTypes.IF, KtNodeTypes.FOR, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE -> ChildAttributes(Indent.getNormalIndent(), null)
|
in CODE_BLOCKS, KtNodeTypes.WHEN, KtNodeTypes.IF, KtNodeTypes.FOR, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE -> ChildAttributes(
|
||||||
|
Indent.getNormalIndent(),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
KtNodeTypes.TRY -> ChildAttributes(Indent.getNoneIndent(), null)
|
KtNodeTypes.TRY -> ChildAttributes(Indent.getNoneIndent(), null)
|
||||||
|
|
||||||
@@ -256,12 +254,12 @@ abstract class KotlinCommonBlock(
|
|||||||
if (newChildIndex != 1 && newChildIndex != 0 && newChildIndex < subBlocks.size) {
|
if (newChildIndex != 1 && newChildIndex != 0 && newChildIndex < subBlocks.size) {
|
||||||
val block = subBlocks[newChildIndex]
|
val block = subBlocks[newChildIndex]
|
||||||
ChildAttributes(block.indent, block.alignment)
|
ChildAttributes(block.indent, block.alignment)
|
||||||
}
|
} else {
|
||||||
else {
|
val indent =
|
||||||
val indent = if (type == KtNodeTypes.VALUE_PARAMETER_LIST && !settings.kotlinCustomSettings.CONTINUATION_INDENT_IN_PARAMETER_LISTS)
|
if (type == KtNodeTypes.VALUE_PARAMETER_LIST && !settings.kotlinCustomSettings.CONTINUATION_INDENT_IN_PARAMETER_LISTS)
|
||||||
Indent.getNormalIndent()
|
Indent.getNormalIndent()
|
||||||
else
|
else
|
||||||
Indent.getContinuationIndent()
|
Indent.getContinuationIndent()
|
||||||
ChildAttributes(indent, null)
|
ChildAttributes(indent, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -296,13 +294,15 @@ abstract class KotlinCommonBlock(
|
|||||||
return when {
|
return when {
|
||||||
parentType === KtNodeTypes.VALUE_PARAMETER_LIST ->
|
parentType === KtNodeTypes.VALUE_PARAMETER_LIST ->
|
||||||
getAlignmentForChildInParenthesis(
|
getAlignmentForChildInParenthesis(
|
||||||
kotlinCommonSettings.ALIGN_MULTILINE_PARAMETERS, KtNodeTypes.VALUE_PARAMETER, COMMA,
|
kotlinCommonSettings.ALIGN_MULTILINE_PARAMETERS, KtNodeTypes.VALUE_PARAMETER, COMMA,
|
||||||
kotlinCommonSettings.ALIGN_MULTILINE_METHOD_BRACKETS, LPAR, RPAR)
|
kotlinCommonSettings.ALIGN_MULTILINE_METHOD_BRACKETS, LPAR, RPAR
|
||||||
|
)
|
||||||
|
|
||||||
parentType === KtNodeTypes.VALUE_ARGUMENT_LIST ->
|
parentType === KtNodeTypes.VALUE_ARGUMENT_LIST ->
|
||||||
getAlignmentForChildInParenthesis(
|
getAlignmentForChildInParenthesis(
|
||||||
kotlinCommonSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS, KtNodeTypes.VALUE_ARGUMENT, COMMA,
|
kotlinCommonSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS, KtNodeTypes.VALUE_ARGUMENT, COMMA,
|
||||||
kotlinCommonSettings.ALIGN_MULTILINE_METHOD_BRACKETS, LPAR, RPAR)
|
kotlinCommonSettings.ALIGN_MULTILINE_METHOD_BRACKETS, LPAR, RPAR
|
||||||
|
)
|
||||||
|
|
||||||
parentType === KtNodeTypes.WHEN ->
|
parentType === KtNodeTypes.WHEN ->
|
||||||
getAlignmentForCaseBranch(kotlinCustomSettings.ALIGN_IN_COLUMNS_CASE_BRANCH)
|
getAlignmentForCaseBranch(kotlinCustomSettings.ALIGN_IN_COLUMNS_CASE_BRANCH)
|
||||||
@@ -318,7 +318,8 @@ abstract class KotlinCommonBlock(
|
|||||||
|
|
||||||
parentType === KtNodeTypes.PARENTHESIZED ->
|
parentType === KtNodeTypes.PARENTHESIZED ->
|
||||||
object : CommonAlignmentStrategy() {
|
object : CommonAlignmentStrategy() {
|
||||||
private var bracketsAlignment: Alignment? = if (kotlinCommonSettings.ALIGN_MULTILINE_BINARY_OPERATION) Alignment.createAlignment() else null
|
private var bracketsAlignment: Alignment? =
|
||||||
|
if (kotlinCommonSettings.ALIGN_MULTILINE_BINARY_OPERATION) Alignment.createAlignment() else null
|
||||||
|
|
||||||
override fun getAlignment(node: ASTNode): Alignment? {
|
override fun getAlignment(node: ASTNode): Alignment? {
|
||||||
val childNodeType = node.elementType
|
val childNodeType = node.elementType
|
||||||
@@ -353,12 +354,13 @@ abstract class KotlinCommonBlock(
|
|||||||
val operationNode = child.firstChildNode
|
val operationNode = child.firstChildNode
|
||||||
if (operationNode != null) {
|
if (operationNode != null) {
|
||||||
return createBlock(
|
return createBlock(
|
||||||
operationNode,
|
operationNode,
|
||||||
alignmentStrategy,
|
alignmentStrategy,
|
||||||
createChildIndent(child),
|
createChildIndent(child),
|
||||||
childWrap,
|
childWrap,
|
||||||
settings,
|
settings,
|
||||||
spacingBuilder)
|
spacingBuilder
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,23 +375,21 @@ abstract class KotlinCommonBlock(
|
|||||||
val binaryExpressionChildren = mutableListOf<ASTNode>()
|
val binaryExpressionChildren = mutableListOf<ASTNode>()
|
||||||
collectBinaryExpressionChildren(node, binaryExpressionChildren)
|
collectBinaryExpressionChildren(node, binaryExpressionChildren)
|
||||||
binaryExpressionChildren.asSequence()
|
binaryExpressionChildren.asSequence()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
node.children()
|
node.children()
|
||||||
}
|
}
|
||||||
|
|
||||||
return childNodes
|
return childNodes
|
||||||
.filter { it.textRange.length > 0 && it.elementType != TokenType.WHITE_SPACE }
|
.filter { it.textRange.length > 0 && it.elementType != TokenType.WHITE_SPACE }
|
||||||
.map { buildSubBlock(it, childrenAlignmentStrategy, wrappingStrategy ) }
|
.map { buildSubBlock(it, childrenAlignmentStrategy, wrappingStrategy) }
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectBinaryExpressionChildren(node: ASTNode, result: MutableList<ASTNode>) {
|
private fun collectBinaryExpressionChildren(node: ASTNode, result: MutableList<ASTNode>) {
|
||||||
for (child in node.children()) {
|
for (child in node.children()) {
|
||||||
if (child.elementType == KtNodeTypes.BINARY_EXPRESSION) {
|
if (child.elementType == KtNodeTypes.BINARY_EXPRESSION) {
|
||||||
collectBinaryExpressionChildren(child, result)
|
collectBinaryExpressionChildren(child, result)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.add(child)
|
result.add(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,23 +443,31 @@ abstract class KotlinCommonBlock(
|
|||||||
val parent = node.treeParent.psi
|
val parent = node.treeParent.psi
|
||||||
when (parent) {
|
when (parent) {
|
||||||
is KtParameter ->
|
is KtParameter ->
|
||||||
return getWrappingStrategyForItemList(commonSettings.PARAMETER_ANNOTATION_WRAP,
|
return getWrappingStrategyForItemList(
|
||||||
ANNOTATIONS,
|
commonSettings.PARAMETER_ANNOTATION_WRAP,
|
||||||
!node.treeParent.isFirstParameter())
|
ANNOTATIONS,
|
||||||
|
!node.treeParent.isFirstParameter()
|
||||||
|
)
|
||||||
is KtClassOrObject ->
|
is KtClassOrObject ->
|
||||||
return getWrappingStrategyForItemList(commonSettings.CLASS_ANNOTATION_WRAP,
|
return getWrappingStrategyForItemList(
|
||||||
ANNOTATIONS)
|
commonSettings.CLASS_ANNOTATION_WRAP,
|
||||||
|
ANNOTATIONS
|
||||||
|
)
|
||||||
|
|
||||||
is KtNamedFunction ->
|
is KtNamedFunction ->
|
||||||
return getWrappingStrategyForItemList(commonSettings.METHOD_ANNOTATION_WRAP,
|
return getWrappingStrategyForItemList(
|
||||||
ANNOTATIONS)
|
commonSettings.METHOD_ANNOTATION_WRAP,
|
||||||
|
ANNOTATIONS
|
||||||
|
)
|
||||||
|
|
||||||
is KtProperty ->
|
is KtProperty ->
|
||||||
return getWrappingStrategyForItemList(if (parent.isLocal)
|
return getWrappingStrategyForItemList(
|
||||||
commonSettings.VARIABLE_ANNOTATION_WRAP
|
if (parent.isLocal)
|
||||||
else
|
commonSettings.VARIABLE_ANNOTATION_WRAP
|
||||||
commonSettings.FIELD_ANNOTATION_WRAP,
|
else
|
||||||
ANNOTATIONS)
|
commonSettings.FIELD_ANNOTATION_WRAP,
|
||||||
|
ANNOTATIONS
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +493,8 @@ abstract class KotlinCommonBlock(
|
|||||||
nodePsi is KtProperty ->
|
nodePsi is KtProperty ->
|
||||||
return object : WrappingStrategy {
|
return object : WrappingStrategy {
|
||||||
override fun getWrap(childElement: ASTNode): Wrap? {
|
override fun getWrap(childElement: ASTNode): Wrap? {
|
||||||
val wrapSetting = if (nodePsi.isLocal) commonSettings.VARIABLE_ANNOTATION_WRAP else commonSettings.FIELD_ANNOTATION_WRAP
|
val wrapSetting =
|
||||||
|
if (nodePsi.isLocal) commonSettings.VARIABLE_ANNOTATION_WRAP else commonSettings.FIELD_ANNOTATION_WRAP
|
||||||
getWrapAfterAnnotation(childElement, wrapSetting)?.let {
|
getWrapAfterAnnotation(childElement, wrapSetting)?.let {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
@@ -572,8 +581,8 @@ private fun hasLineBreakBefore(block: ASTBlock): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun NodeIndentStrategy.PositionStrategy.continuationIf(
|
fun NodeIndentStrategy.PositionStrategy.continuationIf(
|
||||||
option: (KotlinCodeStyleSettings) -> Boolean,
|
option: (KotlinCodeStyleSettings) -> Boolean,
|
||||||
indentFirst: Boolean = false
|
indentFirst: Boolean = false
|
||||||
): NodeIndentStrategy {
|
): NodeIndentStrategy {
|
||||||
return set { settings ->
|
return set { settings ->
|
||||||
if (option(settings.kotlinCustomSettings)) {
|
if (option(settings.kotlinCustomSettings)) {
|
||||||
@@ -587,146 +596,154 @@ fun NodeIndentStrategy.PositionStrategy.continuationIf(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val INDENT_RULES = arrayOf<NodeIndentStrategy>(
|
private val INDENT_RULES = arrayOf<NodeIndentStrategy>(
|
||||||
strategy("No indent for braces in blocks")
|
strategy("No indent for braces in blocks")
|
||||||
.within(KtNodeTypes.BLOCK, KtNodeTypes.CLASS_BODY, KtNodeTypes.FUNCTION_LITERAL)
|
.within(KtNodeTypes.BLOCK, KtNodeTypes.CLASS_BODY, KtNodeTypes.FUNCTION_LITERAL)
|
||||||
.forType(RBRACE, LBRACE)
|
.forType(RBRACE, LBRACE)
|
||||||
.set(Indent.getNoneIndent()),
|
.set(Indent.getNoneIndent()),
|
||||||
|
|
||||||
strategy("Indent for block content")
|
strategy("Indent for block content")
|
||||||
.within(KtNodeTypes.BLOCK, KtNodeTypes.CLASS_BODY, KtNodeTypes.FUNCTION_LITERAL)
|
.within(KtNodeTypes.BLOCK, KtNodeTypes.CLASS_BODY, KtNodeTypes.FUNCTION_LITERAL)
|
||||||
.notForType(RBRACE, LBRACE, KtNodeTypes.BLOCK)
|
.notForType(RBRACE, LBRACE, KtNodeTypes.BLOCK)
|
||||||
.set(Indent.getNormalIndent(false)),
|
.set(Indent.getNormalIndent(false)),
|
||||||
|
|
||||||
strategy("Indent for property accessors")
|
strategy("Indent for property accessors")
|
||||||
.within(KtNodeTypes.PROPERTY).forType(KtNodeTypes.PROPERTY_ACCESSOR)
|
.within(KtNodeTypes.PROPERTY).forType(KtNodeTypes.PROPERTY_ACCESSOR)
|
||||||
.set(Indent.getNormalIndent()),
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
strategy("For a single statement in 'for'")
|
strategy("For a single statement in 'for'")
|
||||||
.within(KtNodeTypes.BODY).notForType(KtNodeTypes.BLOCK)
|
.within(KtNodeTypes.BODY).notForType(KtNodeTypes.BLOCK)
|
||||||
.set(Indent.getNormalIndent()),
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
strategy("For the entry in when")
|
strategy("For the entry in when")
|
||||||
.forType(KtNodeTypes.WHEN_ENTRY)
|
.forType(KtNodeTypes.WHEN_ENTRY)
|
||||||
.set(Indent.getNormalIndent()),
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
strategy("For single statement in THEN and ELSE")
|
strategy("For single statement in THEN and ELSE")
|
||||||
.within(KtNodeTypes.THEN, KtNodeTypes.ELSE).notForType(KtNodeTypes.BLOCK)
|
.within(KtNodeTypes.THEN, KtNodeTypes.ELSE).notForType(KtNodeTypes.BLOCK)
|
||||||
.set(Indent.getNormalIndent()),
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
strategy("Expression body")
|
strategy("Expression body")
|
||||||
.within(KtNodeTypes.FUN)
|
.within(KtNodeTypes.FUN)
|
||||||
.forElement {
|
.forElement {
|
||||||
it.psi is KtExpression && it.psi !is KtBlockExpression
|
it.psi is KtExpression && it.psi !is KtBlockExpression
|
||||||
}
|
}
|
||||||
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_FOR_EXPRESSION_BODIES, indentFirst = true),
|
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_FOR_EXPRESSION_BODIES, indentFirst = true),
|
||||||
|
|
||||||
strategy("If condition")
|
strategy("If condition")
|
||||||
.within(KtNodeTypes.CONDITION)
|
.within(KtNodeTypes.CONDITION)
|
||||||
.set { settings ->
|
.set { settings ->
|
||||||
val indentType = if (settings.kotlinCustomSettings.CONTINUATION_INDENT_IN_IF_CONDITIONS)
|
val indentType = if (settings.kotlinCustomSettings.CONTINUATION_INDENT_IN_IF_CONDITIONS)
|
||||||
Indent.Type.CONTINUATION
|
Indent.Type.CONTINUATION
|
||||||
else
|
else
|
||||||
Indent.Type.NORMAL
|
Indent.Type.NORMAL
|
||||||
Indent.getIndent(indentType, false, true)
|
Indent.getIndent(indentType, false, true)
|
||||||
},
|
},
|
||||||
|
|
||||||
strategy("Property accessor expression body")
|
strategy("Property accessor expression body")
|
||||||
.within(KtNodeTypes.PROPERTY_ACCESSOR)
|
.within(KtNodeTypes.PROPERTY_ACCESSOR)
|
||||||
.forElement {
|
.forElement {
|
||||||
it.psi is KtExpression && it.psi !is KtBlockExpression
|
it.psi is KtExpression && it.psi !is KtBlockExpression
|
||||||
}
|
}
|
||||||
.set(Indent.getNormalIndent()),
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
strategy("Property initializer")
|
strategy("Property initializer")
|
||||||
.within(KtNodeTypes.PROPERTY)
|
.within(KtNodeTypes.PROPERTY)
|
||||||
.forElement {
|
.forElement {
|
||||||
it.psi is KtExpression
|
it.psi is KtExpression
|
||||||
}
|
}
|
||||||
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_FOR_EXPRESSION_BODIES),
|
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_FOR_EXPRESSION_BODIES),
|
||||||
|
|
||||||
strategy("Indent for parts")
|
strategy("Indent for parts")
|
||||||
.within(KtNodeTypes.PROPERTY, KtNodeTypes.FUN, KtNodeTypes.DESTRUCTURING_DECLARATION, KtNodeTypes.SECONDARY_CONSTRUCTOR)
|
.within(KtNodeTypes.PROPERTY, KtNodeTypes.FUN, KtNodeTypes.DESTRUCTURING_DECLARATION, KtNodeTypes.SECONDARY_CONSTRUCTOR)
|
||||||
.notForType(KtNodeTypes.BLOCK, FUN_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, CONSTRUCTOR_KEYWORD, KtTokens.RPAR)
|
.notForType(KtNodeTypes.BLOCK, FUN_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, CONSTRUCTOR_KEYWORD, KtTokens.RPAR)
|
||||||
.set(Indent.getContinuationWithoutFirstIndent()),
|
.set(Indent.getContinuationWithoutFirstIndent()),
|
||||||
|
|
||||||
strategy("Chained calls")
|
strategy("Chained calls")
|
||||||
.within(QUALIFIED_EXPRESSIONS)
|
.within(QUALIFIED_EXPRESSIONS)
|
||||||
.notForType(KtTokens.DOT, KtTokens.SAFE_ACCESS)
|
.notForType(KtTokens.DOT, KtTokens.SAFE_ACCESS)
|
||||||
.forElement { it.treeParent.firstChildNode != it }
|
.forElement { it.treeParent.firstChildNode != it }
|
||||||
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_FOR_CHAINED_CALLS),
|
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_FOR_CHAINED_CALLS),
|
||||||
|
|
||||||
strategy("Colon of delegation list")
|
strategy("Colon of delegation list")
|
||||||
.within(KtNodeTypes.CLASS, KtNodeTypes.OBJECT_DECLARATION)
|
.within(KtNodeTypes.CLASS, KtNodeTypes.OBJECT_DECLARATION)
|
||||||
.forType(KtTokens.COLON)
|
.forType(KtTokens.COLON)
|
||||||
.set(Indent.getNormalIndent(false)),
|
.set(Indent.getNormalIndent(false)),
|
||||||
|
|
||||||
strategy("Delegation list")
|
strategy("Delegation list")
|
||||||
.within(KtNodeTypes.SUPER_TYPE_LIST, KtNodeTypes.INITIALIZER_LIST)
|
.within(KtNodeTypes.SUPER_TYPE_LIST, KtNodeTypes.INITIALIZER_LIST)
|
||||||
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_IN_SUPERTYPE_LISTS, indentFirst = true),
|
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_IN_SUPERTYPE_LISTS, indentFirst = true),
|
||||||
|
|
||||||
strategy("Indices")
|
strategy("Indices")
|
||||||
.within(KtNodeTypes.INDICES)
|
.within(KtNodeTypes.INDICES)
|
||||||
.set(Indent.getContinuationIndent(false)),
|
.set(Indent.getContinuationIndent(false)),
|
||||||
|
|
||||||
strategy("Binary expressions")
|
strategy("Binary expressions")
|
||||||
.within(BINARY_EXPRESSIONS)
|
.within(BINARY_EXPRESSIONS)
|
||||||
.forElement { node -> !node.suppressBinaryExpressionIndent() }
|
.forElement { node -> !node.suppressBinaryExpressionIndent() }
|
||||||
.set(Indent.getContinuationWithoutFirstIndent(false)),
|
.set(Indent.getContinuationWithoutFirstIndent(false)),
|
||||||
|
|
||||||
strategy("Parenthesized expression")
|
strategy("Parenthesized expression")
|
||||||
.within(KtNodeTypes.PARENTHESIZED)
|
.within(KtNodeTypes.PARENTHESIZED)
|
||||||
.set(Indent.getContinuationWithoutFirstIndent(false)),
|
.set(Indent.getContinuationWithoutFirstIndent(false)),
|
||||||
|
|
||||||
strategy("Opening parenthesis for conditions")
|
strategy("Opening parenthesis for conditions")
|
||||||
.forType(LPAR)
|
.forType(LPAR)
|
||||||
.within(KtNodeTypes.IF, KtNodeTypes.WHEN_ENTRY, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE)
|
.within(KtNodeTypes.IF, KtNodeTypes.WHEN_ENTRY, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE)
|
||||||
.set(Indent.getContinuationWithoutFirstIndent(true)),
|
.set(Indent.getContinuationWithoutFirstIndent(true)),
|
||||||
|
|
||||||
strategy("Closing parenthesis for conditions")
|
strategy("Closing parenthesis for conditions")
|
||||||
.forType(RPAR)
|
.forType(RPAR)
|
||||||
.forElement { node -> !hasErrorElementBefore(node) }
|
.forElement { node -> !hasErrorElementBefore(node) }
|
||||||
.within(KtNodeTypes.IF, KtNodeTypes.WHEN_ENTRY, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE)
|
.within(KtNodeTypes.IF, KtNodeTypes.WHEN_ENTRY, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE)
|
||||||
.set(Indent.getNoneIndent()),
|
.set(Indent.getNoneIndent()),
|
||||||
|
|
||||||
strategy("Closing parenthesis for incomplete conditions")
|
strategy("Closing parenthesis for incomplete conditions")
|
||||||
.forType(RPAR)
|
.forType(RPAR)
|
||||||
.forElement { node -> hasErrorElementBefore(node) }
|
.forElement { node -> hasErrorElementBefore(node) }
|
||||||
.within(KtNodeTypes.IF, KtNodeTypes.WHEN_ENTRY, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE)
|
.within(KtNodeTypes.IF, KtNodeTypes.WHEN_ENTRY, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE)
|
||||||
.set(Indent.getContinuationWithoutFirstIndent()),
|
.set(Indent.getContinuationWithoutFirstIndent()),
|
||||||
|
|
||||||
strategy("KDoc comment indent")
|
strategy("KDoc comment indent")
|
||||||
.within(KDOC_CONTENT)
|
.within(KDOC_CONTENT)
|
||||||
.forType(KDocTokens.LEADING_ASTERISK, KDocTokens.END)
|
.forType(KDocTokens.LEADING_ASTERISK, KDocTokens.END)
|
||||||
.set(Indent.getSpaceIndent(KDOC_COMMENT_INDENT)),
|
.set(Indent.getSpaceIndent(KDOC_COMMENT_INDENT)),
|
||||||
|
|
||||||
strategy("Block in when entry")
|
strategy("Block in when entry")
|
||||||
.within(KtNodeTypes.WHEN_ENTRY)
|
.within(KtNodeTypes.WHEN_ENTRY)
|
||||||
.notForType(KtNodeTypes.BLOCK, KtNodeTypes.WHEN_CONDITION_EXPRESSION, KtNodeTypes.WHEN_CONDITION_IN_RANGE, KtNodeTypes.WHEN_CONDITION_IS_PATTERN, ELSE_KEYWORD, ARROW)
|
.notForType(
|
||||||
.set(Indent.getNormalIndent()),
|
KtNodeTypes.BLOCK,
|
||||||
|
KtNodeTypes.WHEN_CONDITION_EXPRESSION,
|
||||||
|
KtNodeTypes.WHEN_CONDITION_IN_RANGE,
|
||||||
|
KtNodeTypes.WHEN_CONDITION_IS_PATTERN,
|
||||||
|
ELSE_KEYWORD,
|
||||||
|
ARROW
|
||||||
|
)
|
||||||
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
strategy("Parameter list")
|
strategy("Parameter list")
|
||||||
.within(KtNodeTypes.VALUE_PARAMETER_LIST)
|
.within(KtNodeTypes.VALUE_PARAMETER_LIST)
|
||||||
.forElement { it.elementType == KtNodeTypes.VALUE_PARAMETER && it.psi.prevSibling != null }
|
.forElement { it.elementType == KtNodeTypes.VALUE_PARAMETER && it.psi.prevSibling != null }
|
||||||
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_IN_PARAMETER_LISTS, indentFirst = true),
|
.continuationIf(KotlinCodeStyleSettings::CONTINUATION_INDENT_IN_PARAMETER_LISTS, indentFirst = true),
|
||||||
|
|
||||||
strategy("Where clause")
|
strategy("Where clause")
|
||||||
.within(KtNodeTypes.CLASS, KtNodeTypes.FUN, KtNodeTypes.PROPERTY)
|
.within(KtNodeTypes.CLASS, KtNodeTypes.FUN, KtNodeTypes.PROPERTY)
|
||||||
.forType(KtTokens.WHERE_KEYWORD)
|
.forType(KtTokens.WHERE_KEYWORD)
|
||||||
.set(Indent.getContinuationIndent()),
|
.set(Indent.getContinuationIndent()),
|
||||||
|
|
||||||
strategy("Array literals")
|
strategy("Array literals")
|
||||||
.within(KtNodeTypes.COLLECTION_LITERAL_EXPRESSION)
|
.within(KtNodeTypes.COLLECTION_LITERAL_EXPRESSION)
|
||||||
.notForType(LBRACKET, RBRACKET)
|
.notForType(LBRACKET, RBRACKET)
|
||||||
.set(Indent.getNormalIndent()),
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
strategy("Type aliases")
|
strategy("Type aliases")
|
||||||
.within(KtNodeTypes.TYPEALIAS)
|
.within(KtNodeTypes.TYPEALIAS)
|
||||||
.notForType(KtTokens.TYPE_ALIAS_KEYWORD, KtTokens.EOL_COMMENT, KtNodeTypes.MODIFIER_LIST)
|
.notForType(KtTokens.TYPE_ALIAS_KEYWORD, KtTokens.EOL_COMMENT, KtNodeTypes.MODIFIER_LIST)
|
||||||
.set(Indent.getContinuationIndent())
|
.set(Indent.getContinuationIndent())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
private fun getOperationType(node: ASTNode): IElementType? = node.findChildByType(KtNodeTypes.OPERATION_REFERENCE)?.firstChildNode?.elementType
|
private fun getOperationType(node: ASTNode): IElementType? =
|
||||||
|
node.findChildByType(KtNodeTypes.OPERATION_REFERENCE)?.firstChildNode?.elementType
|
||||||
|
|
||||||
fun hasErrorElementBefore(node: ASTNode): Boolean {
|
fun hasErrorElementBefore(node: ASTNode): Boolean {
|
||||||
val prevSibling = getPrevWithoutWhitespace(node) ?: return false
|
val prevSibling = getPrevWithoutWhitespace(node) ?: return false
|
||||||
@@ -748,8 +765,9 @@ private fun ASTNode.suppressBinaryExpressionIndent(): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getAlignmentForChildInParenthesis(
|
private fun getAlignmentForChildInParenthesis(
|
||||||
shouldAlignChild: Boolean, parameter: IElementType, delimiter: IElementType,
|
shouldAlignChild: Boolean, parameter: IElementType, delimiter: IElementType,
|
||||||
shouldAlignParenthesis: Boolean, openBracket: IElementType, closeBracket: IElementType): CommonAlignmentStrategy {
|
shouldAlignParenthesis: Boolean, openBracket: IElementType, closeBracket: IElementType
|
||||||
|
): CommonAlignmentStrategy {
|
||||||
val parameterAlignment = if (shouldAlignChild) Alignment.createAlignment() else null
|
val parameterAlignment = if (shouldAlignChild) Alignment.createAlignment() else null
|
||||||
val bracketsAlignment = if (shouldAlignParenthesis) Alignment.createAlignment() else null
|
val bracketsAlignment = if (shouldAlignParenthesis) Alignment.createAlignment() else null
|
||||||
|
|
||||||
@@ -802,8 +820,8 @@ private fun getWrappingStrategyForItemList(wrapType: Int, itemTypes: TokenSet, w
|
|||||||
val thisType = childElement.elementType
|
val thisType = childElement.elementType
|
||||||
val prevType = getPrevWithoutWhitespace(childElement)?.elementType
|
val prevType = getPrevWithoutWhitespace(childElement)?.elementType
|
||||||
return if (thisType in itemTypes || prevType in itemTypes &&
|
return if (thisType in itemTypes || prevType in itemTypes &&
|
||||||
thisType != KtTokens.EOL_COMMENT && prevType != KtTokens.EOL_COMMENT
|
thisType != KtTokens.EOL_COMMENT && prevType != KtTokens.EOL_COMMENT
|
||||||
)
|
)
|
||||||
itemWrap
|
itemWrap
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|||||||
Reference in New Issue
Block a user