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

Suppress in individual files #255

Merged
merged 33 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
bf4f2e5
Suppress-in-individual-files
aktsay6 Sep 8, 2020
2412b4b
feature/suppress-in-individual-files
aktsay6 Sep 8, 2020
3051dcc
feature/suppress-in-individual-files
aktsay6 Sep 8, 2020
7e03ce1
Merge remote-tracking branch 'origin/feature/suppress-in-individual-f…
aktsay6 Sep 8, 2020
c13f71b
Merge branch 'master' into feature/suppress-in-individual-files
aktsay6 Sep 8, 2020
a896a3c
feature/suppress-in-individual-files
aktsay6 Sep 8, 2020
24bd86f
feature/suppress-in-individual-files
aktsay6 Sep 8, 2020
eb027bc
feature/suppress-in-individual-files
aktsay6 Sep 8, 2020
601200c
feature/suppress-in-individual-files
aktsay6 Sep 8, 2020
ef424ad
Merge branch 'master' into feature/suppress-in-individual-files
aktsay6 Sep 10, 2020
2ef5b69
feature/suppress-in-individual-files
aktsay6 Sep 10, 2020
0c1e271
Merge branch 'master' into feature/suppress-in-individual-files
aktsay6 Sep 10, 2020
77673dd
Merge branch 'master' into feature/suppress-in-individual-files
aktsay6 Sep 10, 2020
c852840
feature/suppress-in-individual-files
aktsay6 Sep 10, 2020
dabf5c9
Merge remote-tracking branch 'origin/master' into feature/suppress-in…
aktsay6 Sep 10, 2020
15bb1cc
feature/suppress-in-individual-files
aktsay6 Sep 10, 2020
79c8bbc
Merge branch 'master' into feature/suppress-in-individual-files
aktsay6 Sep 10, 2020
325bb92
feature/suppress-in-individual-files
aktsay6 Sep 10, 2020
9a3f9d3
feature/suppress-in-individual-files
aktsay6 Sep 11, 2020
7aaf105
Merge remote-tracking branch 'origin/master' into feature/suppress-in…
aktsay6 Sep 11, 2020
81f0a33
feature/suppress-in-individual-files
aktsay6 Sep 11, 2020
b872c88
Merge remote-tracking branch 'origin/master' into feature/suppress-in…
aktsay6 Sep 14, 2020
3d4b8f8
feature/suppress-in-individual-files
aktsay6 Sep 14, 2020
d388db0
feature/suppress-in-individual-files
aktsay6 Sep 14, 2020
cd1cd81
feature/suppress-in-individual-files
aktsay6 Sep 14, 2020
7b8ebe3
feature/suppress-in-individual-files
aktsay6 Sep 14, 2020
b22c816
Merge remote-tracking branch 'origin/master' into feature/suppress-in…
aktsay6 Sep 14, 2020
2cc8ec3
Merge branch 'master' into feature/suppress-in-individual-files
aktsay6 Sep 15, 2020
35f1704
Merge branch 'master' into feature/suppress-in-individual-files
aktsay6 Sep 15, 2020
4e07ce2
feature/suppress-in-individual-files
aktsay6 Sep 15, 2020
826b47f
feature/suppress-in-individual-files
aktsay6 Sep 15, 2020
6a1c119
feature/suppress-in-individual-files
aktsay6 Sep 15, 2020
0a40734
feature/suppress-in-individual-files
aktsay6 Sep 15, 2020
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
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,19 @@ Note, that you can specify and put `diktat-analysis.yml` that contains configura
See default configuration in [diktat-analysis.yml](diktat-rules/src/main/resources/diktat-analysis.yml) \
Also see [the list of all rules supported by diKTat](info/available-rules.md).

## Suppress warnings on individual code blocks
In addition to enabling/disabling warning globally via config file, you can suppress warnings by adding `@Suppress` annotation on individual code blocks

For example:

``` kotlin
@Suppress("FUNCTION_NAME_INCORRECT_CASE")
class SomeClass {
fun methODTREE(): String {

}
}
```
## How to contribute?

Main components are:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package org.cqfn.diktat.ruleset.constants
import org.cqfn.diktat.common.config.rules.Rule
petertrr marked this conversation as resolved.
Show resolved Hide resolved
import org.cqfn.diktat.common.config.rules.RulesConfig
import org.cqfn.diktat.common.config.rules.isRuleEnabled
import org.cqfn.diktat.ruleset.utils.hasSuppress
import org.jetbrains.kotlin.com.intellij.lang.ASTNode

/**
* This class represent individual inspections of diktat code style.
Expand Down Expand Up @@ -104,27 +106,31 @@ enum class Warnings(private val canBeAutoCorrected: Boolean, private val warn: S
isFixMode: Boolean,
freeText: String,
offset: Int,
node: ASTNode,
canBeAutoCorrected: Boolean = this.canBeAutoCorrected,
autoFix: () -> Unit) {
warn(configRules, emit, canBeAutoCorrected, freeText, offset)
fix(configRules, autoFix, isFixMode)
warn(configRules, emit, canBeAutoCorrected, freeText, offset, node)
fix(configRules, autoFix, isFixMode, node)
}

@Suppress("LongParameterList")
fun warn(configs: List<RulesConfig>,
emit: ((offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit),
autoCorrected: Boolean,
freeText: String,
offset: Int) {
if (configs.isRuleEnabled(this)) {
offset: Int,
node: ASTNode) {

if (configs.isRuleEnabled(this) && !node.hasSuppress(name)) {
emit(offset,
"${this.warnText()} $freeText",
autoCorrected
)
}
}

private inline fun fix(configs: List<RulesConfig>, autoFix: () -> Unit, isFix: Boolean) {
if (configs.isRuleEnabled(this) && isFix) {
private inline fun fix(configs: List<RulesConfig>, autoFix: () -> Unit, isFix: Boolean, node: ASTNode) {
if (configs.isRuleEnabled(this) && isFix && !node.hasSuppress(name)) {
autoFix()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class AnnotationNewLineRule(private val configRules: List<RulesConfig>) : Rule("

private fun deleteSpaces(node: ASTNode, rightSide: Boolean, leftSide: Boolean) {
Warnings.ANNOTATION_NEW_LINE.warnAndFix(configRules, emitWarn, isFixMode, "${node.text} not on a single line",
node.startOffset) {
node.startOffset, node) {
if (rightSide) {
if (node.treeNext?.isWhiteSpace() == true) {
node.removeChild(node.treeNext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class BlockStructureBraces(private val configRules: List<RulesConfig>) : Rule("b
val braceSpace = nodeBefore?.treePrev
if (braceSpace == null || checkBraceNode(braceSpace, true)) {
BRACES_BLOCK_STRUCTURE_ERROR.warnAndFix(configRules, emitWarn, isFixMode, "incorrect newline before opening brace",
(braceSpace ?: node).startOffset) {
(braceSpace ?: node).startOffset, node) {
if (braceSpace == null || braceSpace.elementType != WHITE_SPACE) {
node.addChild(PsiWhiteSpaceImpl(" "), nodeBefore)
} else {
Expand All @@ -173,7 +173,7 @@ class BlockStructureBraces(private val configRules: List<RulesConfig>) : Rule("b
node.findChildByType(beforeType) else node)?.findLBrace()?.treeNext ?: return
if (checkBraceNode(newNode)) {
BRACES_BLOCK_STRUCTURE_ERROR.warnAndFix(configRules, emitWarn, isFixMode, "incorrect same line after opening brace",
newNode.startOffset) {
newNode.startOffset, newNode) {
if (newNode.elementType != WHITE_SPACE) {
node.addChild(PsiWhiteSpaceImpl("\n"), newNode)
} else {
Expand All @@ -187,7 +187,7 @@ class BlockStructureBraces(private val configRules: List<RulesConfig>) : Rule("b
allMiddleSpace.forEach {
if (checkBraceNode(it, true)) {
BRACES_BLOCK_STRUCTURE_ERROR.warnAndFix(configRules, emitWarn, isFixMode, "incorrect new line after closing brace",
it.startOffset) {
it.startOffset, it) {
if (it.elementType != WHITE_SPACE) {
node.addChild(PsiWhiteSpaceImpl(" "), node.findChildByType(keyword))
} else {
Expand All @@ -203,7 +203,7 @@ class BlockStructureBraces(private val configRules: List<RulesConfig>) : Rule("b
val space = node.findChildByType(RBRACE)!!.treePrev
if (checkBraceNode(space))
BRACES_BLOCK_STRUCTURE_ERROR.warnAndFix(configRules, emitWarn, isFixMode, "no newline before closing brace",
(space.treeNext ?: node.findChildByType(RBRACE))!!.startOffset) {
(space.treeNext ?: node.findChildByType(RBRACE))!!.startOffset, node) {
if (space.elementType != WHITE_SPACE) {
node.addChild(PsiWhiteSpaceImpl("\n"), node.findChildByType(RBRACE))
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class BracesInConditionalsAndLoopsRule(private val configRules: List<RulesConfig

if (thenNode?.elementType != BLOCK) {
NO_BRACES_IN_CONDITIONALS_AND_LOOPS.warnAndFix(configRules, emitWarn, isFixMode, "IF",
(thenNode?.prevSibling { it.elementType == IF_KEYWORD } ?: node).startOffset) {
(thenNode?.prevSibling { it.elementType == IF_KEYWORD } ?: node).startOffset, node) {
if (thenNode != null) {
ifPsi.then!!.replaceWithBlock(indent)
if (elseNode != null) {
Expand All @@ -84,7 +84,7 @@ class BracesInConditionalsAndLoopsRule(private val configRules: List<RulesConfig

if (hasElseBranch && elseNode?.elementType != IF && elseNode?.elementType != BLOCK) {
NO_BRACES_IN_CONDITIONALS_AND_LOOPS.warnAndFix(configRules, emitWarn, isFixMode, "ELSE",
(elseNode?.treeParent?.prevSibling { it.elementType == ELSE_KEYWORD } ?: node).startOffset) {
(elseNode?.treeParent?.prevSibling { it.elementType == ELSE_KEYWORD } ?: node).startOffset, node) {
if (elseNode != null) {
ifPsi.`else`!!.replaceWithBlock(indent)
} else {
Expand All @@ -99,7 +99,7 @@ class BracesInConditionalsAndLoopsRule(private val configRules: List<RulesConfig
val loopBody = (node.psi as KtLoopExpression).body
val loopBodyNode = loopBody?.node
if (loopBodyNode == null || loopBodyNode.elementType != BLOCK) {
NO_BRACES_IN_CONDITIONALS_AND_LOOPS.warnAndFix(configRules, emitWarn, isFixMode, node.elementType.toString(), node.startOffset) {
NO_BRACES_IN_CONDITIONALS_AND_LOOPS.warnAndFix(configRules, emitWarn, isFixMode, node.elementType.toString(), node.startOffset, node) {
// fixme proper way to calculate indent? or get step size (instead of hardcoded 4)
val indent = node.prevSibling { it.elementType == WHITE_SPACE }!!.text.lines().last().count { it == ' ' }
if (loopBody != null) {
Expand All @@ -122,7 +122,7 @@ class BracesInConditionalsAndLoopsRule(private val configRules: List<RulesConfig
.map { it.expression as KtBlockExpression }
.filter { it.statements.size == 1 }
.forEach {
NO_BRACES_IN_CONDITIONALS_AND_LOOPS.warnAndFix(configRules, emitWarn, isFixMode, "WHEN", it.node.startOffset) {
NO_BRACES_IN_CONDITIONALS_AND_LOOPS.warnAndFix(configRules, emitWarn, isFixMode, "WHEN", it.node.startOffset, it.node) {
it.astReplace(it.firstStatement!!.node.psi)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class ClassLikeStructuresOrderRule(private val configRules: List<RulesConfig>) :
unusedClasses)

blocks.allBlockFlattened().reversed().handleIncorrectOrder(blocks::getSiblingBlocks) { astNode, beforeThisNode ->
WRONG_ORDER_IN_CLASS_LIKE_STRUCTURES.warnAndFix(configRules, emitWarn, isFixMode, astNode.elementType.toString() + ": " + astNode.text, astNode.startOffset) {
WRONG_ORDER_IN_CLASS_LIKE_STRUCTURES.warnAndFix(configRules, emitWarn, isFixMode, astNode.elementType.toString() + ": " + astNode.text, astNode.startOffset, astNode) {
val replacement = node.moveChildBefore(astNode, beforeThisNode, true)
replacement.oldNodes.forEachIndexed { idx, oldNode ->
blocks.allBlocks().find { oldNode in it }?.apply {
Expand All @@ -100,7 +100,7 @@ class ClassLikeStructuresOrderRule(private val configRules: List<RulesConfig>) :
val whiteSpaceBefore = previousProperty.nextSibling { it.elementType == WHITE_SPACE }!!
val nRequiredNewLines = if (commentOnThis == null) 1 else 2
if (whiteSpaceBefore.text.count { it == '\n' } != nRequiredNewLines)
BLANK_LINE_BETWEEN_PROPERTIES.warnAndFix(configRules, emitWarn, isFixMode, node.getIdentifierName()!!.text, node.startOffset) {
BLANK_LINE_BETWEEN_PROPERTIES.warnAndFix(configRules, emitWarn, isFixMode, node.getIdentifierName()!!.text, node.startOffset, node) {
whiteSpaceBefore.leaveExactlyNumNewLines(nRequiredNewLines)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class ConsecutiveSpacesRule(private val configRules: List<RulesConfig>) : Rule("
if (spaces > configuration.numberOfSpaces && !node.isWhiteSpaceWithNewline()
&& !node.hasEolComment()) {
TOO_MANY_CONSECUTIVE_SPACES.warnAndFix(configRules, emitWarn, isFixMode,
"found: $spaces. need to be: ${configuration.numberOfSpaces}", node.startOffset) {
"found: $spaces. need to be: ${configuration.numberOfSpaces}", node.startOffset, node) {
node.squeezeSpaces()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,22 @@ class EmptyBlock(private val configRules: List<RulesConfig>) : Rule("empty-block
if (node.isBlockEmpty()) {
if (!configuration.emptyBlockExist) {
EMPTY_BLOCK_STRUCTURE_ERROR.warn(configRules, emitWarn, isFixMode, "empty blocks are forbidden unless it is function with override keyword",
node.startOffset)
node.startOffset, node)
} else {
val space = node.findChildByType(RBRACE)!!.treePrev
if (configuration.emptyBlockNewline && !space.text.contains("\n")) {
EMPTY_BLOCK_STRUCTURE_ERROR.warnAndFix(configRules, emitWarn, isFixMode, "different style for empty block",
node.startOffset) {
node.startOffset, node) {
if (space.elementType == WHITE_SPACE) {
(space.treeNext as LeafPsiElement).replaceWithText("\n")
} else {
}
else {
node.addChild(PsiWhiteSpaceImpl("\n"), space.treeNext)
}
}
} else if (!configuration.emptyBlockNewline && space.text.contains("\n")) {
EMPTY_BLOCK_STRUCTURE_ERROR.warnAndFix(configRules, emitWarn, isFixMode, "different style for empty block",
node.startOffset) {
node.startOffset, node) {
node.removeChild(space)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class EnumsSeparated(private val configRules: List<RulesConfig>) : Rule("enum-se
enumEntries.forEach {
if (!it.treeNext.isWhiteSpaceWithNewline())
ENUMS_SEPARATED.warnAndFix(configRules, emitWarn, isFixMode, "enum entries must end with a line break",
it.startOffset) {
it.startOffset, it) {
it.appendNewlineMergingWhiteSpace(it.treeNext, it.treeNext)
}
}
Expand All @@ -72,19 +72,19 @@ class EnumsSeparated(private val configRules: List<RulesConfig>) : Rule("enum-se
private fun checkLastEnum(node: ASTNode) {
if (!node.hasChildOfType(SEMICOLON)) {
ENUMS_SEPARATED.warnAndFix(configRules, emitWarn, isFixMode, "enums must end with semicolon",
node.startOffset) {
node.startOffset, node) {
node.addChild(LeafPsiElement(SEMICOLON, ";"), null)
node.addChild(PsiWhiteSpaceImpl("\n"), node.findChildByType(SEMICOLON)!!)
}
} else if (!node.findChildByType(SEMICOLON)!!.treePrev.isWhiteSpaceWithNewline()) {
ENUMS_SEPARATED.warnAndFix(configRules, emitWarn, isFixMode, "semicolon must be on a new line",
node.startOffset) {
node.startOffset, node) {
node.appendNewlineMergingWhiteSpace(node.findChildByType(SEMICOLON)!!, node.findChildByType(SEMICOLON)!!)
}
}
if (!node.hasChildOfType(COMMA)) {
ENUMS_SEPARATED.warnAndFix(configRules, emitWarn, isFixMode, "last enum entry must end with a comma",
node.startOffset) {
node.startOffset, node) {
node.addChild(LeafPsiElement(COMMA, ","), node.findChildByType(SEMICOLON)!!.treePrev)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ class FileNaming(private val configRules: List<RulesConfig>) : Rule("file-naming

if (node.elementType == FILE) {
fileName = node.getUserData(KtLint.FILE_PATH_USER_DATA_KEY)!!
checkFileNaming()
checkFileNaming(node)
checkClassNameMatchesWithFile(node)
}
}

private fun checkFileNaming() {
private fun checkFileNaming(node: ASTNode) {
if (fileName != null) {
val (name, extension) = getFileParts()
if (!name.isPascalCase() || !VALID_EXTENSIONS.contains(extension)) {
FILE_NAME_INCORRECT.warnAndFix(configRules, emitWarn, isFixMode, "$name$extension", 0) {
FILE_NAME_INCORRECT.warnAndFix(configRules, emitWarn, isFixMode, "$name$extension", 0, node) {
// FixMe: we can add an autocorrect here in future, but is there any purpose to change file or class name?
}
}
Expand All @@ -65,7 +65,7 @@ class FileNaming(private val configRules: List<RulesConfig>) : Rule("file-naming
if (classes.size == 1) {
val className = classes[0].getFirstChildWithType(IDENTIFIER)!!.text
if (className != fileNameWithoutSuffix) {
FILE_NAME_MATCH_CLASS.warnAndFix(configRules, emitWarn, isFixMode, "$fileNameWithoutSuffix$fileNameSuffix vs $className", 0) {
FILE_NAME_MATCH_CLASS.warnAndFix(configRules, emitWarn, isFixMode, "$fileNameWithoutSuffix$fileNameSuffix vs $className", 0, fileLevelNode) {

// FixMe: we can add an autocorrect here in future, but is there any purpose to change file name?
}
Expand Down
Loading