-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Do not use !isEmpty methods from the collections – need to use isNotE…
…mpty instead (#704) * feature/check-isEmpty-method(#692) ### What's done: * Added new rule * Added warn tests * Added fix tests
- Loading branch information
Showing
15 changed files
with
277 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/CheckInverseMethodRule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package org.cqfn.diktat.ruleset.rules | ||
|
||
import org.cqfn.diktat.common.config.rules.RulesConfig | ||
import org.cqfn.diktat.ruleset.constants.EmitType | ||
import org.cqfn.diktat.ruleset.constants.Warnings.INVERSE_FUNCTION_PREFERRED | ||
|
||
import com.pinterest.ktlint.core.Rule | ||
import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT | ||
import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION | ||
import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER | ||
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.RPAR | ||
import com.pinterest.ktlint.core.ast.ElementType.VALUE_ARGUMENT_LIST | ||
import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE | ||
import org.jetbrains.kotlin.com.intellij.lang.ASTNode | ||
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.CompositeElement | ||
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement | ||
import org.jetbrains.kotlin.psi.psiUtil.siblings | ||
|
||
/** | ||
* This rule checks if inverse method can be used. | ||
* For example if there is !isEmpty() on collection call that it changes it to isNotEmpty() | ||
*/ | ||
class CheckInverseMethodRule(private val configRules: List<RulesConfig>) : Rule("inverse-method") { | ||
private var isFixMode: Boolean = false | ||
private lateinit var emitWarn: EmitType | ||
|
||
override fun visit(node: ASTNode, | ||
autoCorrect: Boolean, | ||
emit: EmitType) { | ||
emitWarn = emit | ||
isFixMode = autoCorrect | ||
|
||
if (node.elementType == CALL_EXPRESSION && node.text in methodMap.keys) { | ||
checkCallExpressionName(node) | ||
} | ||
} | ||
|
||
private fun checkCallExpressionName(node: ASTNode) { | ||
val operationRef = node | ||
.treeParent | ||
.siblings(forward = false) | ||
.takeWhile { it.elementType in intermediateTokens } | ||
.firstOrNull { it.elementType == OPERATION_REFERENCE} | ||
if (operationRef?.text == "!") { | ||
INVERSE_FUNCTION_PREFERRED.warnAndFix(configRules, emitWarn, isFixMode, "${methodMap[node.text]} instead of !${node.text}", node.startOffset, node) { | ||
val callExpression = CompositeElement(CALL_EXPRESSION) | ||
val referenceExp = CompositeElement(REFERENCE_EXPRESSION) | ||
val argList = CompositeElement(VALUE_ARGUMENT_LIST) | ||
node.treeParent.addChild(callExpression, node) | ||
callExpression.addChild(referenceExp) | ||
callExpression.addChild(argList) | ||
referenceExp.addChild(LeafPsiElement(IDENTIFIER, "${methodMap[node.text]}".dropLast(2))) | ||
argList.addChild(LeafPsiElement(LPAR, "(")) | ||
argList.addChild(LeafPsiElement(RPAR, ")")) | ||
node.treeParent.treeParent.removeChild(node.treeParent.treePrev) // removing OPERATION_EXPRESSION - ! | ||
node.treeParent.removeChild(node) | ||
} | ||
} | ||
} | ||
|
||
companion object { | ||
val methodMap = mapOf( | ||
"isEmpty()" to "isNotEmpty()", | ||
"isBlank()" to "isNotBlank()", | ||
"isNotEmpty()" to "isEmpty()", | ||
"isNotBlank()" to "isBlank()" | ||
) | ||
val intermediateTokens = listOf(WHITE_SPACE, OPERATION_REFERENCE, BLOCK_COMMENT) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
...t-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleFixTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package org.cqfn.diktat.ruleset.chapter5 | ||
|
||
import org.cqfn.diktat.ruleset.rules.CheckInverseMethodRule | ||
import org.cqfn.diktat.util.FixTestBase | ||
|
||
import generated.WarningNames.INVERSE_FUNCTION_PREFERRED | ||
import org.junit.jupiter.api.Tag | ||
import org.junit.jupiter.api.Test | ||
|
||
class CheckInverseMethodRuleFixTest : FixTestBase("test/paragraph5/method_call_names", ::CheckInverseMethodRule) { | ||
@Test | ||
@Tag(INVERSE_FUNCTION_PREFERRED) | ||
fun `should fix method calls`() { | ||
fixAndCompare("ReplaceMethodCallNamesExpected.kt", "ReplaceMethodCallNamesTest.kt") | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
...-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/CheckInverseMethodRuleWarnTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package org.cqfn.diktat.ruleset.chapter5 | ||
|
||
import org.cqfn.diktat.ruleset.constants.Warnings | ||
import org.cqfn.diktat.ruleset.rules.CheckInverseMethodRule | ||
import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID | ||
import org.cqfn.diktat.util.LintTestBase | ||
|
||
import com.pinterest.ktlint.core.LintError | ||
import generated.WarningNames.INVERSE_FUNCTION_PREFERRED | ||
import org.junit.jupiter.api.Tag | ||
import org.junit.jupiter.api.Test | ||
|
||
class CheckInverseMethodRuleWarnTest : LintTestBase(::CheckInverseMethodRule) { | ||
private val ruleId = "$DIKTAT_RULE_SET_ID:inverse-method" | ||
|
||
@Test | ||
@Tag(INVERSE_FUNCTION_PREFERRED) | ||
fun `should not raise warning`() { | ||
lintMethod( | ||
""" | ||
|fun some() { | ||
| if (list.isEmpty()) { | ||
| // some cool logic | ||
| } | ||
|} | ||
""".trimMargin() | ||
) | ||
} | ||
|
||
@Test | ||
@Tag(INVERSE_FUNCTION_PREFERRED) | ||
fun `should raise warning`() { | ||
lintMethod( | ||
""" | ||
|fun some() { | ||
| if (!list.isEmpty()) { | ||
| // some cool logic | ||
| } | ||
|} | ||
""".trimMargin(), | ||
LintError(2, 14, ruleId, "${Warnings.INVERSE_FUNCTION_PREFERRED.warnText()} isNotEmpty() instead of !isEmpty()", true) | ||
) | ||
} | ||
|
||
@Test | ||
@Tag(INVERSE_FUNCTION_PREFERRED) | ||
fun `should consider white spaces between ! and call expression`() { | ||
lintMethod( | ||
""" | ||
|fun some() { | ||
| if (! list.isEmpty()) { | ||
| // some cool logic | ||
| } | ||
|} | ||
""".trimMargin(), | ||
LintError(2, 16, ruleId, "${Warnings.INVERSE_FUNCTION_PREFERRED.warnText()} isNotEmpty() instead of !isEmpty()", true) | ||
) | ||
} | ||
|
||
@Test | ||
@Tag(INVERSE_FUNCTION_PREFERRED) | ||
fun `should consider comments between ! and call expression`() { | ||
lintMethod( | ||
""" | ||
|fun some() { | ||
| if (! /*cool comment*/ list.isEmpty()) { | ||
| // some cool logic | ||
| } | ||
|} | ||
""".trimMargin(), | ||
LintError(2, 32, ruleId, "${Warnings.INVERSE_FUNCTION_PREFERRED.warnText()} isNotEmpty() instead of !isEmpty()", true) | ||
) | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
...es/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesExpected.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package test.chapter6.method_call_names | ||
|
||
fun coolFunction() { | ||
val list = listOf(1, 2, 3) | ||
val testStr = "" | ||
|
||
if (list.isEmpty()) { } | ||
|
||
if (list.isNotEmpty()) { } | ||
|
||
if (list.isNotEmpty()) { } | ||
|
||
if (list.isEmpty()) { } | ||
|
||
if (testStr.isBlank()) { } | ||
|
||
if (testStr.isNotBlank()) { } | ||
|
||
if (testStr.isNotBlank()) { } | ||
|
||
if (testStr.isBlank()) { } | ||
|
||
if (list.isNotEmpty() && testStr.isBlank()) { } | ||
} | ||
|
25 changes: 25 additions & 0 deletions
25
...-rules/src/test/resources/test/paragraph5/method_call_names/ReplaceMethodCallNamesTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package test.chapter6.method_call_names | ||
|
||
fun coolFunction() { | ||
val list = listOf(1, 2, 3) | ||
val testStr = "" | ||
|
||
if (list.isEmpty()) { } | ||
|
||
if (list.isNotEmpty()) { } | ||
|
||
if (!list.isEmpty()) { } | ||
|
||
if (!list.isNotEmpty()) { } | ||
|
||
if (testStr.isBlank()) { } | ||
|
||
if (testStr.isNotBlank()) { } | ||
|
||
if (!testStr.isBlank()) { } | ||
|
||
if (!testStr.isNotBlank()) { } | ||
|
||
if (!list.isEmpty() && !testStr.isNotBlank()) { } | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
241f45e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to retrieve PDD puzzles from the code base and submit them to GitHub. If you think that it's a bug on our side, please submit it to yegor256/0pdd:
Please, copy and paste this stack trace to GitHub: