Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#315 Configurable indentation size. #316

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
*/
class IndentationRule(private val configRules: List<RulesConfig>) : Rule("indentation") {
companion object {
const val INDENT_SIZE = 4
private val increasingTokens = listOf(LPAR, LBRACE, LBRACKET)
private val decreasingTokens = listOf(RPAR, RBRACE, RBRACKET)
}
Expand Down Expand Up @@ -100,7 +99,7 @@ class IndentationRule(private val configRules: List<RulesConfig>) : Rule("indent
.apply { if (isEmpty()) return true }
.forEach {
WRONG_INDENTATION.warnAndFix(configRules, emitWarn, isFixMode, "tabs are not allowed for indentation", it.startOffset + it.text.indexOf('\t'), it) {
(it as LeafPsiElement).replaceWithText(it.text.replace("\t", " ".repeat(INDENT_SIZE)))
(it as LeafPsiElement).replaceWithText(it.text.replace("\t", " ".repeat(configuration.indentationSize)))
}
}
return isFixMode // true if we changed all tabs to spaces
Expand Down Expand Up @@ -128,7 +127,7 @@ class IndentationRule(private val configRules: List<RulesConfig>) : Rule("indent
* Traverses the tree, keeping track of regular and exceptional indentations
*/
private fun checkIndentation(node: ASTNode) {
val context = IndentContext()
val context = IndentContext(configuration)
node.visit { astNode ->
context.checkAndReset(astNode)
if (astNode.elementType in increasingTokens) {
Expand Down Expand Up @@ -176,16 +175,16 @@ class IndentationRule(private val configRules: List<RulesConfig>) : Rule("indent
/**
* Class that contains state needed to calculate indent and keep track of exceptional indents
*/
private class IndentContext {
private class IndentContext(private val config: IndentationConfig) {
private var regularIndent = 0
private val exceptionalIndents = mutableListOf<ExceptionalIndent>()

fun inc() {
regularIndent += INDENT_SIZE
regularIndent += config.indentationSize
}

fun dec() {
regularIndent -= INDENT_SIZE
regularIndent -= config.indentationSize
}

fun indent() = regularIndent + exceptionalIndents.sumBy { it.indent }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER_LIST
import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE
import com.pinterest.ktlint.core.ast.prevSibling
import org.cqfn.diktat.ruleset.rules.files.IndentationError
import org.cqfn.diktat.ruleset.rules.files.IndentationRule.Companion.INDENT_SIZE
import org.cqfn.diktat.ruleset.rules.files.lastIndent
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace
Expand All @@ -44,7 +43,7 @@ internal class AssignmentOperatorChecker(configuration: IndentationConfig) : Cus
val prevNode = whiteSpace.prevSibling.node
if (prevNode.elementType == EQ && prevNode.treeNext.let { it.elementType == WHITE_SPACE && it.textContains('\n') }) {
return CheckResult.from(indentError.actual, (whiteSpace.parentIndent()
?: indentError.expected) + INDENT_SIZE, true)
?: indentError.expected) + configuration.indentationSize, true)
}
return null
}
Expand All @@ -69,7 +68,7 @@ internal class ValueParameterListChecker(configuration: IndentationConfig) : Cus
// fixme: probably there is a better way to find column number
parameterList.parents().last().text.substringBefore(parameterAfterLpar.text).lines().last().count()
} else if (parameterAfterLpar == null && configuration.extendedIndentOfParameters) {
indentError.expected + INDENT_SIZE
indentError.expected + configuration.indentationSize
} else {
indentError.expected
}
Expand All @@ -87,7 +86,7 @@ internal class ExpressionIndentationChecker(configuration: IndentationConfig) :
override fun checkNode(whiteSpace: PsiWhiteSpace, indentError: IndentationError): CheckResult? {
if (whiteSpace.parent.node.elementType == BINARY_EXPRESSION && whiteSpace.prevSibling.node.elementType == OPERATION_REFERENCE) {
val expectedIndent = (whiteSpace.parentIndent() ?: indentError.expected) +
(if (configuration.extendedIndentAfterOperators) 2 else 1) * INDENT_SIZE
(if (configuration.extendedIndentAfterOperators) 2 else 1) * configuration.indentationSize
return CheckResult.from(indentError.actual, expectedIndent)
}
return null
Expand Down Expand Up @@ -117,26 +116,26 @@ internal class SuperTypeListChecker(config: IndentationConfig) : CustomIndentati
if (whiteSpace.nextSibling.node.elementType == SUPER_TYPE_LIST) {
val hasNewlineBeforeColon = whiteSpace.node.prevSibling { it.elementType == COLON }!!
.treePrev.takeIf { it.elementType == WHITE_SPACE }?.textContains('\n') ?: false
val expectedIndent = indentError.expected + (if (hasNewlineBeforeColon) 2 else 1) * INDENT_SIZE
val expectedIndent = indentError.expected + (if (hasNewlineBeforeColon) 2 else 1) * configuration.indentationSize
return CheckResult.from(indentError.actual, expectedIndent)
} else if (whiteSpace.parent.node.elementType == SUPER_TYPE_LIST) {
val expectedIndent = whiteSpace.parentIndent() ?: (indentError.expected + INDENT_SIZE)
val expectedIndent = whiteSpace.parentIndent() ?: (indentError.expected + configuration.indentationSize)
return CheckResult.from(indentError.actual, expectedIndent)
}
return null
}
}

/**
* This checker performs the following check: When dot call start on a new line, it should be indented by [INDENT_SIZE]
* This checker performs the following check: When dot call start on a new line, it should be indented by [IndentationConfig.indentationSize]
*/
internal class DotCallChecker(config: IndentationConfig) : CustomIndentationChecker(config) {
override fun checkNode(whiteSpace: PsiWhiteSpace, indentError: IndentationError): CheckResult? {
whiteSpace.nextSibling.node.takeIf {
it.elementType in listOf(DOT, SAFE_ACCESS) && it.treeNext.elementType in listOf(CALL_EXPRESSION, REFERENCE_EXPRESSION)
}?.let {
return CheckResult.from(indentError.actual, (whiteSpace.parentIndent()
?: indentError.expected) + INDENT_SIZE, true)
?: indentError.expected) + configuration.indentationSize, true)
}
return null
}
Expand All @@ -157,7 +156,7 @@ internal class ConditionalsAndLoopsWithoutBracesChecker(config: IndentationConfi
.takeIf { it }
?.let {
CheckResult.from(indentError.actual, (whiteSpace.parentIndent()
?: indentError.expected) + INDENT_SIZE, false)
?: indentError.expected) + configuration.indentationSize, false)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ internal class IndentationConfig(config: Map<String, String>) : RuleConfiguratio
* If true, if expression is split by newline after operator like +/-/`*`, then the next line is indented with two indentations instead of one
*/
val extendedIndentAfterOperators = config["extendedIndentAfterOperators"]?.toBoolean() ?: true

/**
* The indentation size for each file
*/
val indentationSize = config["indentationSize"]?.toInt() ?: 4
portlek marked this conversation as resolved.
Show resolved Hide resolved
}