Skip to content

Commit

Permalink
bugfix/indentation-inside-string-templates(#758)
Browse files Browse the repository at this point in the history
### What's done:
  * New bug with warn (fix work fine)
  • Loading branch information
aktsay6 committed Feb 11, 2021
1 parent ed19ffd commit e120aa4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.pinterest.ktlint.core.ast.ElementType.FILE
import com.pinterest.ktlint.core.ast.ElementType.LBRACE
import com.pinterest.ktlint.core.ast.ElementType.LBRACKET
import com.pinterest.ktlint.core.ast.ElementType.LITERAL_STRING_TEMPLATE_ENTRY
import com.pinterest.ktlint.core.ast.ElementType.LONG_STRING_TEMPLATE_ENTRY
import com.pinterest.ktlint.core.ast.ElementType.LONG_TEMPLATE_ENTRY_END
import com.pinterest.ktlint.core.ast.ElementType.LONG_TEMPLATE_ENTRY_START
import com.pinterest.ktlint.core.ast.ElementType.LPAR
Expand All @@ -44,6 +45,7 @@ import com.pinterest.ktlint.core.ast.ElementType.STRING_TEMPLATE
import com.pinterest.ktlint.core.ast.ElementType.THEN
import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE
import com.pinterest.ktlint.core.ast.visit
import org.cqfn.diktat.ruleset.utils.hasParent
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement
Expand All @@ -58,6 +60,7 @@ import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import kotlin.math.abs

/**
* Rule that checks indentation. The following general rules are checked:
Expand Down Expand Up @@ -179,10 +182,15 @@ class IndentationRule(configRules: List<RulesConfig>) : DiktatRule("indentation"
}

val expectedIndent = checkResult?.expectedIndent ?: indentError.expected
if (checkResult?.adjustNext == true) {
if (checkResult?.adjustNext == true && !astNode.hasParent(LONG_STRING_TEMPLATE_ENTRY)) {
val exceptionInitiatorNode = astNode.getExceptionalIndentInitiator()
context.addException(exceptionInitiatorNode, expectedIndent - indentError.expected, checkResult.includeLastChild)
}

if (astNode.treeParent.elementType == LONG_STRING_TEMPLATE_ENTRY && indentError.expected != indentError.actual) {
context.addException(astNode.treeParent, abs(indentError.expected - indentError.actual), false)
}

if (checkResult?.isCorrect != true && expectedIndent != indentError.actual) {
WRONG_INDENTATION.warnAndFix(configRules, emitWarn, isFixMode, "expected $expectedIndent but was ${indentError.actual}",
whiteSpace.startOffset + whiteSpace.text.lastIndexOf('\n') + 1, whiteSpace.node) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.pinterest.ktlint.core.ast.ElementType.LPAR
import com.pinterest.ktlint.core.ast.ElementType.OPERATION_REFERENCE
import com.pinterest.ktlint.core.ast.ElementType.REFERENCE_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.SAFE_ACCESS
import com.pinterest.ktlint.core.ast.ElementType.STRING_TEMPLATE
import com.pinterest.ktlint.core.ast.ElementType.SUPER_TYPE_LIST
import com.pinterest.ktlint.core.ast.ElementType.THEN
import com.pinterest.ktlint.core.ast.ElementType.VALUE_ARGUMENT
Expand All @@ -38,6 +39,8 @@ 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.nextCodeSibling
import com.pinterest.ktlint.core.ast.prevSibling
import org.cqfn.diktat.ruleset.utils.hasParameters
import org.cqfn.diktat.ruleset.utils.hasParent
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace
Expand Down Expand Up @@ -195,6 +198,9 @@ internal class DotCallChecker(config: IndentationConfig) : CustomIndentationChec
return false
}

private fun ASTNode.isFromStringTemplate(): Boolean =
hasParent(LONG_STRING_TEMPLATE_ENTRY)

@Suppress("ComplexMethod")
override fun checkNode(whiteSpace: PsiWhiteSpace, indentError: IndentationError): CheckResult? {
whiteSpace.nextSibling.node
Expand All @@ -205,6 +211,12 @@ internal class DotCallChecker(config: IndentationConfig) : CustomIndentationChec
} || nextNode.isCommentBeforeDot()
}
?.let {
if (it.isFromStringTemplate()) {
val template = it.parents().takeWhile { it.elementType != STRING_TEMPLATE }.last()
return CheckResult.from(indentError.actual, indentError.expected +
(if (configuration.extendedIndentBeforeDot) 2 else 1) * configuration.indentationSize, true)
}

// we need to get indent before the first expression in calls chain
return CheckResult.from(indentError.actual, (whiteSpace.run {
parents.takeWhile { it is KtDotQualifiedExpression || it is KtSafeQualifiedExpression }.lastOrNull() ?: this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ class IndentationRuleWarnTest : LintTestBase(::IndentationRule) {
@Tag(WarningNames.WRONG_INDENTATION)
fun `should trigger on string templates starting with new line`() {
lintMethod(
"""
"""
|fun foo(some: String) {
| fun bar() {
| val a = "${'$'}{
Expand All @@ -624,9 +624,9 @@ class IndentationRuleWarnTest : LintTestBase(::IndentationRule) {
|}
|
""".trimMargin(),
LintError(4, 1, ruleId, warnText(12, 8), true),
LintError(5, 1, ruleId, warnText(16, 12), true),
LintError(6, 1, ruleId, warnText(16, 12), true)
LintError(4, 1, ruleId, warnText(12, 8), true),
LintError(5, 1, ruleId, warnText(16, 12), true),
LintError(6, 1, ruleId, warnText(16, 12), true)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ data class Example(val field1: Type1,
}"

val b = "${baz().foo()}"

val c = "${
expression
.foo()
.bar()
}"
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,11 @@ fun foo(
}"

val b = "${baz().foo()}"

val c = "${
expression
.foo()
.bar()
}"
}
}

0 comments on commit e120aa4

Please sign in to comment.