Skip to content

Commit

Permalink
Bugfix for fi mode of AVOID_NULL_CHECK
Browse files Browse the repository at this point in the history
### What's done:
 * Added a check for assignment operator when deciding if to put run block or not
 * Added tests
(#1293)
  • Loading branch information
sanyavertolet committed Oct 27, 2022
1 parent c04695e commit 8bed41d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.psi.psiUtil.blockExpressionsOrSingle

/**
Expand Down Expand Up @@ -119,9 +120,10 @@ class NullChecksRule(configRules: List<RulesConfig>) : DiktatRule(
}

@Suppress("UnsafeCallOnNullableType", "TOO_LONG_FUNCTION")
private fun fixNullInIfCondition(condition: ASTNode,
binaryExpression: KtBinaryExpression,
isEqualToNull: Boolean
private fun fixNullInIfCondition(
condition: ASTNode,
binaryExpression: KtBinaryExpression,
isEqualToNull: Boolean
) {
val variableName = binaryExpression.left!!.text
val thenFromExistingCode = condition.extractLinesFromBlock(THEN)
Expand All @@ -138,13 +140,24 @@ class NullChecksRule(configRules: List<RulesConfig>) : DiktatRule(
} else {
elseFromExistingCode
}
val numberOfStatementsInElseBlock = if (isEqualToNull) {
(condition.treeParent.psi as KtIfExpression).then?.blockExpressionsOrSingle()?.count() ?: 0
} else {
(condition.treeParent.psi as KtIfExpression).`else`?.blockExpressionsOrSingle()?.count() ?: 0
}

val elseEditedCodeLines = getEditedElseCodeLines(elseCodeLines, numberOfStatementsInElseBlock)
val (numberOfStatementsInElseBlock, isAssignmentInNewElseBlock) = (condition.treeParent.psi as KtIfExpression)
.let {
if (isEqualToNull) {
it.then
} else {
it.`else`
}
}
?.blockExpressionsOrSingle()
?.let { elements ->
elements.count() to elements.any {
element -> KtPsiUtil.isAssignment(element)
}
}
?: Pair(0, false)

val elseEditedCodeLines = getEditedElseCodeLines(elseCodeLines, numberOfStatementsInElseBlock, isAssignmentInNewElseBlock)
val thenEditedCodeLines = getEditedThenCodeLines(variableName, thenCodeLines, elseEditedCodeLines)

val text = "$thenEditedCodeLines $elseEditedCodeLines"
Expand All @@ -153,11 +166,15 @@ class NullChecksRule(configRules: List<RulesConfig>) : DiktatRule(
ifNode.treeParent.replaceChild(ifNode, tree)
}

private fun getEditedElseCodeLines(elseCodeLines: List<String>?, numberOfStatementsInElseBlock: Int): String = when {
private fun getEditedElseCodeLines(
elseCodeLines: List<String>?,
numberOfStatementsInElseBlock: Int,
isAssignment: Boolean,
): String = when {
// else { "null"/empty } -> ""
elseCodeLines == null || elseCodeLines.singleOrNull() == "null" -> ""
// else { bar() } -> ?: bar()
numberOfStatementsInElseBlock == 1 && elseCodeLines.singleOrNull()?.hasAssignment() != true -> "?: ${elseCodeLines.joinToString(postfix = "\n", separator = "\n")}"
numberOfStatementsInElseBlock == 1 && !isAssignment -> "?: ${elseCodeLines.joinToString(postfix = "\n", separator = "\n")}"
// else { ... } -> ?: run { ... }
else -> getDefaultCaseElseCodeLines(elseCodeLines)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ internal const val SPACE = ' '

internal const val TAB = '\t'

private const val REGEX_FOR_ASSIGNMENT_DETECTION = "[^=]+=[^=]+"

@Suppress("VARIABLE_NAME_INCORRECT_FORMAT")
val JAVA = arrayOf("abstract", "assert", "boolean",
"break", "byte", "case", "catch", "char", "class", "const",
Expand All @@ -39,11 +37,6 @@ val KOTLIN = KtTokens.KEYWORDS
*/
val loggerPropertyRegex = "(?iu)^log(?:ger)?$".toRegex()

/**
* @return true if this String includes assignment operator, false otherwise
*/
fun String.hasAssignment(): Boolean = contains(REGEX_FOR_ASSIGNMENT_DETECTION.toRegex())

/**
* @return whether [this] string represents a Java keyword
*/
Expand Down

0 comments on commit 8bed41d

Please sign in to comment.