From 9febc4ca56d64a6e738a0dde497639028275adfe Mon Sep 17 00:00:00 2001 From: kentr0w Date: Sat, 20 Feb 2021 14:48:23 +0300 Subject: [PATCH 01/14] Warnings ### What's done: Fixed all warnings --- CONTRIBUTING.md | 2 +- README.md | 4 +-- .../config/reader/JsonResourceConfigReader.kt | 3 ++ .../common/config/rules/RulesConfigReader.kt | 12 ++++---- diktat-gradle-plugin/README.md | 2 +- .../plugin/gradle/DiktatGradlePlugin.kt | 12 ++++++++ .../plugin/gradle/DiktatJavaExecTaskBase.kt | 5 +++- .../rules/chapter2/comments/CommentsRule.kt | 2 +- .../rules/chapter2/kdoc/CommentsFormatting.kt | 2 -- .../rules/chapter2/kdoc/KdocComments.kt | 14 ++++----- .../rules/chapter2/kdoc/KdocFormatting.kt | 26 ++++++++-------- .../rules/chapter2/kdoc/KdocMethods.kt | 2 -- .../chapter3/StringTemplateFormatRule.kt | 1 - .../rules/chapter3/files/NewlinesRule.kt | 10 +++---- .../rules/chapter4/ImmutableValNoVarRule.kt | 2 +- .../ruleset/rules/chapter4/NullChecksRule.kt | 8 ++--- .../calculations/AccurateCalculationsRule.kt | 2 -- .../rules/chapter5/LambdaLengthRule.kt | 4 +-- .../cqfn/diktat/ruleset/utils/AstNodeUtils.kt | 18 ----------- .../cqfn/diktat/ruleset/utils/KdocUtils.kt | 2 +- .../cqfn/diktat/ruleset/utils/KotlinParser.kt | 3 +- .../org/cqfn/diktat/ruleset/utils/PsiUtils.kt | 22 -------------- .../cqfn/diktat/ruleset/utils/StringUtils.kt | 6 ---- .../ruleset/utils/indentation/Checkers.kt | 4 +-- .../indentation/CustomIndentationChecker.kt | 2 +- .../kotlin/org/cqfn/diktat/util/TestUtils.kt | 3 +- .../framework/config/TestArgumentsReader.kt | 2 +- .../test/framework/config/TestConfigReader.kt | 2 +- .../framework/processing/FileComparator.kt | 2 +- .../processing/TestComparatorUnit.kt | 2 +- info/guide/diktat-coding-convention.md | 30 +++++++++---------- 31 files changed, 83 insertions(+), 128 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7029e242d..3d36207438 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -If you reading this - then you have decided to contribute to our project. Oh, poor you... +If you're reading this - then you have decided to contribute to our project. Oh, poor you... Rules are very simple: 1. Fork this repository to your own account 2. Make your changes and verify that tests pass (or wait that our CI/CD will do everything for you) diff --git a/README.md b/README.md index cd2a86aeab..ea6845e2bb 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ diktat { reporter = "custom:name:pathToJar" } ``` -Name parameter is the name of your reporter and as the last parameter you should specify path to jar, which contains your reporter. +Name parameter is the name of your reporter and as the last parameter you should specify a path to jar, which contains your reporter. [Example of the junit custom reporter.](https://github.com/kryanod/ktlint-junit-reporter) You can also specify an output. @@ -286,7 +286,7 @@ for example, a filename of file where the code is stored; 3) We added a bunch of visitors, checkers and fixers that will extended KTlint functionaliity with code style rules; 4) We have proposed a code style for Kotlin language. -Before you make a pull request, make sure the build is clean as we have lot of tests and other prechecks: +Before you make a pull request, make sure the build is clean as we have a lot of tests and other prechecks: ```bash $ mvn clean install diff --git a/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/reader/JsonResourceConfigReader.kt b/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/reader/JsonResourceConfigReader.kt index 5a3cba90a9..9d175d2677 100644 --- a/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/reader/JsonResourceConfigReader.kt +++ b/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/reader/JsonResourceConfigReader.kt @@ -57,6 +57,9 @@ abstract class JsonResourceConfigReader { protected abstract fun parseResource(fileStream: BufferedReader): T companion object { + /** + * A [Logger] that can be used + */ val log: Logger = LoggerFactory.getLogger(JsonResourceConfigReader::class.java) } } diff --git a/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/rules/RulesConfigReader.kt b/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/rules/RulesConfigReader.kt index 771e063597..01d7342bfb 100644 --- a/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/rules/RulesConfigReader.kt +++ b/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/rules/RulesConfigReader.kt @@ -19,6 +19,9 @@ import java.util.concurrent.atomic.AtomicInteger import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString +/** + * Name of common configuration + */ const val DIKTAT_COMMON = "DIKTAT_COMMON" /** @@ -49,7 +52,6 @@ data class RulesConfig( * @property config a map of strings with configuration options for a particular rule */ open class RuleConfiguration(protected val config: Map) -object EmptyConfiguration : RuleConfiguration(emptyMap()) /** * class returns the list of configurations that we have read from a yml: diktat-analysis.yml @@ -87,6 +89,9 @@ open class RulesConfigReader(override val classLoader: ClassLoader) : JsonResour } companion object { + /** + * A [Logger] that can be used + */ val log: Logger = LoggerFactory.getLogger(RulesConfigReader::class.java) } } @@ -130,11 +135,6 @@ data class CommonConfiguration(private val configuration: Map?) } } - /** - * False if configuration has been read from config file, true if defaults are used - */ - val isDefault = configuration == null - companion object { /** * Counter that helps not to raise multiple warnings about kotlin version diff --git a/diktat-gradle-plugin/README.md b/diktat-gradle-plugin/README.md index 0d62b8ad2d..7dde684c8a 100644 --- a/diktat-gradle-plugin/README.md +++ b/diktat-gradle-plugin/README.md @@ -2,7 +2,7 @@ Build of gradle plugin is performed by gradle, but is wrapped in maven build. The module's `pom.xml` isn't exactly accurate and doesn't include gradle-specific dependencies, that are automatically provided by gradle when applying the plugin. -To avoid versions duplication, diktat and ktlint versions are passed to gradle via properties when running gradle task from maven. +To avoid versions duplication, diktat and ktlint versions are passed to gradle via properties when running gradle task from a maven. These versions are then written in a file and then included in the plugin jar to determine dependencies for JavaExec. Gradle plugin marker pom, which is normally produced by `java-gradle-plugin` plugin during gradle build, diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt index 8223efec9d..d26933e7bf 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt @@ -44,9 +44,21 @@ class DiktatGradlePlugin : Plugin { } companion object { + /** + * Task to check diKTat + */ const val DIKTAT_CHECK_TASK = "diktatCheck" + /** + * DiKTat configuration + */ const val DIKTAT_CONFIGURATION = "diktat" + /** + * DiKTat extension + */ const val DIKTAT_EXTENSION = "diktat" + /** + * Task to run diKTat with fix + */ const val DIKTAT_FIX_TASK = "diktatFix" } } diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt index b705d03d0b..c2eb6cd2fd 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt @@ -25,7 +25,7 @@ import javax.inject.Inject * * Note: class being `open` is required for gradle to create a task. */ -open class DiktatJavaExecTaskBase @Inject constructor( +class DiktatJavaExecTaskBase @Inject constructor( gradleVersionString: String, diktatExtension: DiktatExtension, diktatConfiguration: Configuration, @@ -94,6 +94,9 @@ open class DiktatJavaExecTaskBase @Inject constructor( logger.debug("Setting JavaExec args to $args") } + /** + * Function to execute diKTat + */ @TaskAction override fun exec() { if (shouldRun) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/CommentsRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/CommentsRule.kt index 4b60e373ed..87bdf0a0a1 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/CommentsRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/CommentsRule.kt @@ -145,7 +145,7 @@ class CommentsRule(configRules: List) : DiktatRule( private val importOrPackageRegex = """^(import|package)?\s+([a-zA-Z.])+;*$""".toRegex() private val functionRegex = """^(public|private|protected)*\s*(override|abstract|actual|expect)*\s?fun\s+\w+(\(.*\))?(\s*:\s*\w+)?\s*[{=]${'$'}""".toRegex() private val rightBraceRegex = """^\s*}$""".toRegex() - private val requirePartOfCode = """val |var |=|(\{((.|\n)*)\})""".toRegex() + private val requirePartOfCode = """val |var |=|(\{((.|\n)*)})""".toRegex() private val codeFileStartCases = listOf(classRegex, importOrPackageRegex, functionRegex, rightBraceRegex) private val eolCommentStart = """// \S""".toRegex() } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/CommentsFormatting.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/CommentsFormatting.kt index d617286972..f00a8a1b0a 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/CommentsFormatting.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/CommentsFormatting.kt @@ -56,8 +56,6 @@ class CommentsFormatting(configRules: List) : DiktatRule( IF_ELSE_COMMENTS, WRONG_NEWLINES_AROUND_KDOC)) { /** * @param node - * @param autoCorrect - * @param emit */ override fun logic(node: ASTNode) { val configuration = CommentsFormattingConfiguration( diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt index 96842d2c7f..ec4c1ed5b9 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt @@ -51,8 +51,6 @@ class KdocComments(configRules: List) : DiktatRule( KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT, MISSING_KDOC_CLASS_ELEMENTS, MISSING_KDOC_TOP_LEVEL)) { /** * @param node - * @param autoCorrect - * @param emit */ override fun logic(node: ASTNode) { val config = configRules.getCommonConfiguration() @@ -76,13 +74,13 @@ class KdocComments(configRules: List) : DiktatRule( ?.findChildByType(KDOC) ?: return val propertiesInKdoc = kdocBeforeClass .kDocTags() - ?.filter { it.knownTag == KDocKnownTag.PROPERTY } + .filter { it.knownTag == KDocKnownTag.PROPERTY } val propertyNames = (node.psi as KtParameterList) .parameters .mapNotNull { it.nameIdentifier?.text } propertiesInKdoc - ?.filterNot { it.getSubjectName() == null || it.getSubjectName() in propertyNames } - ?.forEach { KDOC_EXTRA_PROPERTY.warn(configRules, emitWarn, isFixMode, it.text, it.node.startOffset, node) } + .filterNot { it.getSubjectName() == null || it.getSubjectName() in propertyNames } + .forEach { KDOC_EXTRA_PROPERTY.warn(configRules, emitWarn, isFixMode, it.text, it.node.startOffset, node) } } @Suppress("UnsafeCallOnNullableType", "ComplexMethod") @@ -126,7 +124,7 @@ class KdocComments(configRules: List) : DiktatRule( private fun checkBasicKdocBeforeClass(node: ASTNode, kdocBeforeClass: ASTNode) { val propertyInClassKdoc = kdocBeforeClass .kDocTags() - ?.firstOrNull { it.knownTag == KDocKnownTag.PROPERTY && it.getSubjectName() == node.findChildByType(IDENTIFIER)!!.text } + .firstOrNull { it.knownTag == KDocKnownTag.PROPERTY && it.getSubjectName() == node.findChildByType(IDENTIFIER)!!.text } if (propertyInClassKdoc == null && node.getFirstChildWithType(MODIFIER_LIST).isAccessibleOutside()) { KDOC_NO_CONSTRUCTOR_PROPERTY.warnAndFix(configRules, emitWarn, isFixMode, "add <${node.findChildByType(IDENTIFIER)!!.text}> to KDoc", node.startOffset, node) { @@ -142,12 +140,12 @@ class KdocComments(configRules: List) : DiktatRule( prevComment: ASTNode) { val propertyInClassKdoc = kdocBeforeClass .kDocTags() - ?.firstOrNull { it.knownTag == KDocKnownTag.PROPERTY && it.getSubjectName() == node.findChildByType(IDENTIFIER)!!.text } + .firstOrNull { it.knownTag == KDocKnownTag.PROPERTY && it.getSubjectName() == node.findChildByType(IDENTIFIER)!!.text } ?.node val propertyInLocalKdoc = if (prevComment.elementType == KDOC) { prevComment .kDocTags() - ?.firstOrNull { it.knownTag == KDocKnownTag.PROPERTY && it.getSubjectName() == node.findChildByType(IDENTIFIER)!!.text } + .firstOrNull { it.knownTag == KDocKnownTag.PROPERTY && it.getSubjectName() == node.findChildByType(IDENTIFIER)!!.text } ?.node } else { null diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt index 5d85013673..b53a4fc814 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt @@ -71,8 +71,6 @@ class KdocFormatting(configRules: List) : DiktatRule( /** * @param node - * @param autoCorrect - * @param emit */ override fun logic(node: ASTNode) { versionRegex ?: run { @@ -86,8 +84,8 @@ class KdocFormatting(configRules: List) : DiktatRule( checkNoDeprecatedTag(node) checkEmptyTags(node.kDocTags()) checkSpaceAfterTag(node.kDocTags()) - node.kDocBasicTags()?.let { checkEmptyLineBeforeBasicTags(it) } - node.kDocBasicTags()?.let { checkEmptyLinesBetweenBasicTags(it) } + node.kDocBasicTags().let { checkEmptyLineBeforeBasicTags(it) } + node.kDocBasicTags().let { checkEmptyLinesBetweenBasicTags(it) } checkBasicTagsOrder(node) checkNewLineAfterSpecialTags(node) checkAuthorAndDate(node) @@ -111,7 +109,7 @@ class KdocFormatting(configRules: List) : DiktatRule( @Suppress("UnsafeCallOnNullableType") private fun checkNoDeprecatedTag(node: ASTNode) { val kdocTags = node.kDocTags() - kdocTags?.find { it.name == "deprecated" } + kdocTags.find { it.name == "deprecated" } ?.let { kdocTag -> KDOC_NO_DEPRECATED_TAG.warnAndFix(configRules, emitWarn, isFixMode, kdocTag.text, kdocTag.node.startOffset, kdocTag.node) { val kdocSection = kdocTag.node.treeParent @@ -175,12 +173,12 @@ class KdocFormatting(configRules: List) : DiktatRule( val kdocTags = node.kDocTags() // distinct basic tags which are present in current KDoc, in proper order val basicTagsOrdered = basicTagsList.filter { basicTag -> - kdocTags?.find { it.knownTag == basicTag } != null + kdocTags.find { it.knownTag == basicTag } != null } // all basic tags from current KDoc - val basicTags = kdocTags?.filter { basicTagsOrdered.contains(it.knownTag) } + val basicTags = kdocTags.filter { basicTagsOrdered.contains(it.knownTag) } val isTagsInCorrectOrder = basicTags - ?.fold(mutableListOf()) { acc, kdocTag -> + .fold(mutableListOf()) { acc, kdocTag -> if (acc.size > 0 && acc.last().knownTag != kdocTag.knownTag) { acc.add(kdocTag) } else if (acc.size == 0) { @@ -188,10 +186,10 @@ class KdocFormatting(configRules: List) : DiktatRule( } acc } - ?.map { it.knownTag } - ?.equals(basicTagsOrdered) + .map { it.knownTag } + .equals(basicTagsOrdered) - if (kdocTags != null && !isTagsInCorrectOrder!!) { + if (!isTagsInCorrectOrder) { KDOC_WRONG_TAGS_ORDER.warnAndFix(configRules, emitWarn, isFixMode, basicTags.joinToString(", ") { "@${it.name}" }, basicTags .first() @@ -326,11 +324,11 @@ class KdocFormatting(configRules: List) : DiktatRule( private fun checkAuthorAndDate(node: ASTNode) { node.kDocTags() - ?.filter { + .filter { it.knownTag == KDocKnownTag.AUTHOR || it.knownTag == KDocKnownTag.SINCE && it.hasInvalidVersion() } - ?.forEach { + .forEach { KDOC_CONTAINS_DATE_OR_AUTHOR.warn(configRules, emitWarn, isFixMode, it.text.trim(), it.startOffset, it.node) } } @@ -342,7 +340,7 @@ class KdocFormatting(configRules: List) : DiktatRule( (treeNext == null || treeNext.elementType == WHITE_SPACE && treeNext.text.count { it == '\n' } == 1) } - private fun ASTNode.kDocBasicTags() = kDocTags()?.filter { basicTagsList.contains(it.knownTag) } + private fun ASTNode.kDocBasicTags() = kDocTags().filter { basicTagsList.contains(it.knownTag) } private fun ASTNode.previousAsterisk() = prevSibling { it.elementType == KDOC_LEADING_ASTERISK } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt index 7957f96b96..1a06daa124 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt @@ -72,8 +72,6 @@ class KdocMethods(configRules: List) : DiktatRule( KDOC_WITHOUT_THROWS_TAG, MISSING_KDOC_ON_FUNCTION)) { /** * @param node - * @param autoCorrect - * @param emit */ override fun logic(node: ASTNode) { if (node.elementType == FUN && node.getFirstChildWithType(MODIFIER_LIST).isAccessibleOutside() && !node.isOverridden()) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringTemplateFormatRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringTemplateFormatRule.kt index 40d5b607cf..736fcedc3b 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringTemplateFormatRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringTemplateFormatRule.kt @@ -1,7 +1,6 @@ package org.cqfn.diktat.ruleset.rules.chapter3 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.STRING_TEMPLATE_CURLY_BRACES import org.cqfn.diktat.ruleset.constants.Warnings.STRING_TEMPLATE_QUOTES import org.cqfn.diktat.ruleset.rules.DiktatRule diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt index bf98038dfe..f578d56601 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt @@ -489,15 +489,15 @@ class NewlinesRule(configRules: List) : DiktatRule( } val callsByNewLine: ListOfList = mutableListOf() var callsInOneNewLine: MutableList = mutableListOf() - this.forEach { node -> - if (node.treePrev.isFollowedByNewline() || node.treePrev.isWhiteSpaceWithNewline()) { + this.forEach { astNode -> + if (astNode.treePrev.isFollowedByNewline() || astNode.treePrev.isWhiteSpaceWithNewline()) { callsByNewLine.add(callsInOneNewLine) callsInOneNewLine = mutableListOf() - callsInOneNewLine.add(node) + callsInOneNewLine.add(astNode) } else { - callsInOneNewLine.add(node) + callsInOneNewLine.add(astNode) } - if (node.treePrev.elementType == POSTFIX_EXPRESSION && !node.treePrev.isFollowedByNewline() && configuration.maxCallsInOneLine == 1) { + if (astNode.treePrev.elementType == POSTFIX_EXPRESSION && !astNode.treePrev.isFollowedByNewline() && configuration.maxCallsInOneLine == 1) { return true } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/ImmutableValNoVarRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/ImmutableValNoVarRule.kt index 520772ed87..bbbb6a33c6 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/ImmutableValNoVarRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/ImmutableValNoVarRule.kt @@ -30,7 +30,7 @@ class ImmutableValNoVarRule(configRules: List) : DiktatRule( .findAllVariablesWithAssignments { it.name != null && it.isVar } .filter { it.value.isEmpty() } - varNoAssignments.forEach { (property, usages) -> + varNoAssignments.forEach { (_, _) -> // FixMe: raise another warning and fix the code (change to val) for variables without assignment } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/NullChecksRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/NullChecksRule.kt index 51ce63c06d..cc3023b156 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/NullChecksRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/NullChecksRule.kt @@ -67,13 +67,13 @@ class NullChecksRule(configRules: List) : DiktatRule( when (condition.operationToken) { // `==` and `===` comparison can be fixed with `?:` operator ElementType.EQEQ, ElementType.EQEQEQ -> - warnAndFixOnNullCheck(condition, true, + warnAndFixOnNullCheck(condition, "use '.let/.also/?:/e.t.c' instead of ${condition.text}") { fixNullInIfCondition(node, condition, true) } // `!==` and `!==` comparison can be fixed with `.let/also` operators ElementType.EXCLEQ, ElementType.EXCLEQEQEQ -> - warnAndFixOnNullCheck(condition, true, + warnAndFixOnNullCheck(condition, "use '.let/.also/?:/e.t.c' instead of ${condition.text}") { fixNullInIfCondition(node, condition, false) } @@ -140,7 +140,6 @@ class NullChecksRule(configRules: List) : DiktatRule( if (listOf(ElementType.EXCLEQ, ElementType.EXCLEQEQEQ).contains(condition.operationToken)) { warnAndFixOnNullCheck( condition, - true, "use 'requireNotNull' instead of require(${condition.text})" ) { val variableName = (binaryExprNode.psi as KtBinaryExpression).left!!.text @@ -185,7 +184,6 @@ class NullChecksRule(configRules: List) : DiktatRule( private fun warnAndFixOnNullCheck( condition: KtBinaryExpression, - canBeAutoFixed: Boolean, freeText: String, autofix: () -> Unit) { AVOID_NULL_CHECKS.warnAndFix( @@ -195,7 +193,7 @@ class NullChecksRule(configRules: List) : DiktatRule( freeText, condition.node.startOffset, condition.node, - canBeAutoFixed, + true, ) { autofix() } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/calculations/AccurateCalculationsRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/calculations/AccurateCalculationsRule.kt index fb32b85809..1fc69c2de1 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/calculations/AccurateCalculationsRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/calculations/AccurateCalculationsRule.kt @@ -110,8 +110,6 @@ class AccurateCalculationsRule(configRules: List) : DiktatRule( /** * @param node - * @param autoCorrect - * @param emit */ override fun logic(node: ASTNode) { when (val psi = node.psi) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaLengthRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaLengthRule.kt index 77fe03e357..f4a45ab4bc 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaLengthRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaLengthRule.kt @@ -33,9 +33,9 @@ class LambdaLengthRule(configRules: List) : DiktatRule( val copyNode = node.clone() as ASTNode val sizeLambda = countCodeLines(copyNode) if (sizeLambda > configuration.maxLambdaLength) { - copyNode.findAllNodesWithCondition({ it.elementType == ElementType.LAMBDA_EXPRESSION }).forEachIndexed { index, node -> + copyNode.findAllNodesWithCondition({ it.elementType == ElementType.LAMBDA_EXPRESSION }).forEachIndexed { index, astNode -> if (index > 0) { - node.treeParent.removeChild(node) + astNode.treeParent.removeChild(astNode) } } val isIt = copyNode.findAllNodesWithSpecificType(ElementType.REFERENCE_EXPRESSION).map { re -> re.text }.contains("it") diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt index a7a52b8a82..bc376a3155 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt @@ -27,7 +27,6 @@ import com.pinterest.ktlint.core.ast.ElementType.KDOC import com.pinterest.ktlint.core.ast.ElementType.LATEINIT_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.LBRACE import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST -import com.pinterest.ktlint.core.ast.ElementType.OPERATION_REFERENCE import com.pinterest.ktlint.core.ast.ElementType.OVERRIDE_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.PRIVATE_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.PROTECTED_KEYWORD @@ -41,7 +40,6 @@ import com.pinterest.ktlint.core.ast.lineNumber import com.pinterest.ktlint.core.ast.parent import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.TokenType -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.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl import org.jetbrains.kotlin.com.intellij.psi.tree.IElementType @@ -516,15 +514,6 @@ fun ASTNode.hasSuppress(warningName: String) = parent({ node -> fun ASTNode.isOverridden(): Boolean = findChildByType(MODIFIER_LIST)?.findChildByType(OVERRIDE_KEYWORD) != null -/** - * creation of operation reference in a node - */ -fun ASTNode.createOperationReference(elementType: IElementType, text: String) { - val operationReference = CompositeElement(OPERATION_REFERENCE) - this.addChild(operationReference, null) - operationReference.addChild(LeafPsiElement(elementType, text), null) -} - /** * removing all newlines in WHITE_SPACE node and replacing it to a one newline saving the initial indenting format */ @@ -720,13 +709,6 @@ fun ASTNode.hasTestAnnotation() = findChildByType(MODIFIER_LIST) ?.any { it.findLeafWithSpecificType(ElementType.IDENTIFIER)?.text == "Test" } ?: false -/** - * Returns the first line of this node's text if it is single, or the first line followed by [suffix] if there are more than one. - * - * @param suffix a suffix to append if there are more than one lines of text - */ -fun ASTNode.firstLineOfText(suffix: String = "") = text.lines().run { singleOrNull() ?: (first() + suffix) } - /** * Return the number in the file of the last line of this node's text */ diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KdocUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KdocUtils.kt index a64b3dcd70..37ba57eb2a 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KdocUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KdocUtils.kt @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag /** * @return a list of [KDocTag]s from this KDoc node */ -fun ASTNode.kDocTags(): List? { +fun ASTNode.kDocTags(): List { require(this.elementType == ElementType.KDOC) { "kDoc tags can be retrieved only from KDOC node" } return this.getAllChildrenWithType(KDOC_SECTION).flatMap { sectionNode -> sectionNode.getAllChildrenWithType(ElementType.KDOC_TAG) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KotlinParser.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KotlinParser.kt index 3a994703f7..014e11e6a2 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KotlinParser.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KotlinParser.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.mock.MockProject -import org.jetbrains.kotlin.com.intellij.openapi.Disposable import org.jetbrains.kotlin.com.intellij.openapi.project.Project import org.jetbrains.kotlin.com.intellij.openapi.util.UserDataHolderBase import org.jetbrains.kotlin.com.intellij.pom.PomModel @@ -50,7 +49,7 @@ class KotlinParser { } } // I don't really understand what's going on here, but thanks to this, you can use this node in the future val project = KotlinCoreEnvironment.createForProduction( - Disposable { }, + { }, compilerConfiguration, EnvironmentConfigFiles.JVM_CONFIG_FILES ).project // create project diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/PsiUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/PsiUtils.kt index e1443c7955..3bccf34d70 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/PsiUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/PsiUtils.kt @@ -4,8 +4,6 @@ package org.cqfn.diktat.ruleset.utils -import com.pinterest.ktlint.core.ast.ElementType -import org.jetbrains.kotlin.com.intellij.psi.PsiElement import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtCallExpression @@ -59,26 +57,6 @@ fun KtProperty.getDeclarationScope() = .let { if (it is KtTryExpression) it.tryBlock else it } as KtBlockExpression? -/** - * Checks if this [PsiElement] is an ancestor of [block]. - * Nodes like `IF`, `TRY` are parents of `ELSE`, `CATCH`, but their scopes are not intersecting, and false is returned in this case. - * - * @param block - * @return boolean result - */ -fun PsiElement.isContainingScope(block: KtBlockExpression): Boolean { - when (block.parent.node.elementType) { - ElementType.ELSE -> getParentOfType(true) - ElementType.CATCH -> getParentOfType(true) - else -> null - }.let { - if (this == it) { - return false - } - } - return isAncestor(block, false) -} - /** * Method that tries to find a local property declaration with the same name as current [KtNameReferenceExpression] element * diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringUtils.kt index 022d1c7913..35b4507ed9 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringUtils.kt @@ -58,12 +58,6 @@ fun String.containsOneLetterOrZero(): Boolean { return count == 1 || count == 0 } -/** - * @param sub a substring to search - * @return count of ocurrences - */ -fun String.countSubStringOccurrences(sub: String) = this.split(sub).size - 1 - /** * Splits [this] string by file path separator * diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/indentation/Checkers.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/indentation/Checkers.kt index 35b62e78aa..f1b1bc328e 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/indentation/Checkers.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/indentation/Checkers.kt @@ -1,5 +1,5 @@ /** - * Implementations of [CustomIndentationChecker] for [IndentationRule] + * Implementations of CustomIndentationChecker for IndentationRule */ package org.cqfn.diktat.ruleset.utils.indentation @@ -30,7 +30,6 @@ 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 @@ -211,7 +210,6 @@ internal class DotCallChecker(config: IndentationConfig) : CustomIndentationChec } ?.let { node -> if (node.isFromStringTemplate()) { - val template = node.parents().takeWhile { it.elementType != STRING_TEMPLATE }.last() return CheckResult.from(indentError.actual, indentError.expected + (if (configuration.extendedIndentBeforeDot) 2 else 1) * configuration.indentationSize, true) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/indentation/CustomIndentationChecker.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/indentation/CustomIndentationChecker.kt index ffa018cca5..1cd102afa8 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/indentation/CustomIndentationChecker.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/indentation/CustomIndentationChecker.kt @@ -1,5 +1,5 @@ /** - * Utility classes for [IndentationRule] + * Utility classes for IndentationRule */ package org.cqfn.diktat.ruleset.utils.indentation diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/TestUtils.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/TestUtils.kt index cc0dfb7675..93b8b9ab88 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/TestUtils.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/TestUtils.kt @@ -16,7 +16,6 @@ import com.pinterest.ktlint.core.RuleSetProvider import org.assertj.core.api.Assertions import org.assertj.core.api.SoftAssertions import org.jetbrains.kotlin.com.intellij.lang.ASTNode -import org.jetbrains.kotlin.konan.file.File import java.util.concurrent.atomic.AtomicInteger @@ -118,7 +117,7 @@ internal fun applyToCode(code: String, } }) ), - cb = { _, _ -> Unit } + cb = { _, _ -> } ) ) Assertions diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestArgumentsReader.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestArgumentsReader.kt index c4222f6dd1..6e387548b7 100644 --- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestArgumentsReader.kt +++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestArgumentsReader.kt @@ -86,7 +86,7 @@ class TestArgumentsReader( @Throws(IOException::class) override fun parseResource(fileStream: BufferedReader): List { val jsonValue = fileStream.lines().collect(Collectors.joining()) - return Json.decodeFromString>(jsonValue) + return Json.decodeFromString(jsonValue) } companion object { diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfigReader.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfigReader.kt index 1ca166c75e..b196a0032d 100644 --- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfigReader.kt +++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfigReader.kt @@ -26,6 +26,6 @@ class TestConfigReader(configFilePath: String, override val classLoader: ClassLo @Throws(IOException::class) override fun parseResource(fileStream: BufferedReader): TestConfig { val jsonValue: String = fileStream.lines().collect(Collectors.joining()) - return Json.decodeFromString(jsonValue) + return Json.decodeFromString(jsonValue) } } diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/FileComparator.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/FileComparator.kt index b9664181bb..c8e42f6e4f 100644 --- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/FileComparator.kt +++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/FileComparator.kt @@ -77,7 +77,7 @@ class FileComparator { * @param fileName - file where to write these list to, separated with newlines * @return a list of lines from the file */ - fun readFile(fileName: String): List { + private fun readFile(fileName: String): List { var list: List = ArrayList() try { Files.newBufferedReader(Paths.get(fileName)).use { list = it.lines().collect(Collectors.toList()) } diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestComparatorUnit.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestComparatorUnit.kt index 67bbd67f5e..b1dc4e4048 100644 --- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestComparatorUnit.kt +++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestComparatorUnit.kt @@ -51,7 +51,7 @@ class TestComparatorUnit(private val resourceFilePath: String, * @param fileName * @return file content as a list of lines */ - fun readFile(fileName: String): List { + private fun readFile(fileName: String): List { var list: List = ArrayList() try { Files.newBufferedReader(Paths.get(fileName)).use { list = it.lines().collect(Collectors.toList()) } diff --git a/info/guide/diktat-coding-convention.md b/info/guide/diktat-coding-convention.md index 124b14ff2e..4c256b484c 100644 --- a/info/guide/diktat-coding-convention.md +++ b/info/guide/diktat-coding-convention.md @@ -172,13 +172,13 @@ Also, we need to consider the following factors when programming on Kotlin: **Invalid Example** — not recommended examples of rules and recommendations. -Unless otherwise stated, this specification applies to versions 1.3 and later of Kotlin. +Unless otherwise stated, this specification applies to version 1.3 and later of Kotlin. ### Exceptions Even though exceptions may exist, it is essential to understand why rules and recommendations are needed. -Depending on a project situation or personal habits, you can break some of the rules. However, remember that one exception may lead to many and eventually can destroy code consistency. As such, there should be very few exceptions. +Depending on a project situation or personal habits, you can break some rules. However, remember that one exception may lead to many and eventually can destroy code consistency. As such, there should be very few exceptions. When modifying open-source code or third-party code, you can choose to use the code style from this open-source project (instead of using the existing specifications) to maintain consistency. Software that is directly based on the Android native operating system interface, such as the Android Framework, remains consistent with the Android style. # 1. Naming @@ -313,7 +313,7 @@ Note: The calling property access syntax is preferred to call getter directly. I b) `is` + boolean variable name() -c) `set` + field/attribute name(). However, note that the syntax and code generation for Kotlin are completely the same as those described for the getters in point a. +c) `set` + field/attribute name(). However, note that the syntax and code generation for Kotlin are completely the same as those described for the getters in point. d) `has` + Noun / adjective () @@ -349,7 +349,7 @@ fun addKeyListener(Listener) ### 1.5 Constants This section describes the general rules for naming constraints. ### 1.5.1 Using UPPER case and underscore characters in a constraint name -Constant names should be in UPPER case, words separated by underscore. The general constant naming conventions are listed below: +Constant names should be in UPPER case, words separated by a underscore. The general constant naming conventions are listed below: 1. Constants are attributes created with the `const` keyword or top-level/`val` local variables of an object that holds immutable data. In most cases, constants can be identified as a `const val` property from the `object`/`companion object`/file top level. These variables contain fixed constant values that typically should never be changed by programmers. This includes basic types, strings, immutable types, and immutable collections of immutable types. The value is not constant for the object, which state can be changed. 2. Constant names should contain only uppercase letters separated by an underscores. They should have a val or const val modifier to make them final explicitly. In most cases, if you need to specify a constant value, then you need to create it with the "const val" modifier. Note that not all `val` variables are constants. 3. Objects with immutable content, such as `Logger` and `Lock`, can be in uppercase as constants or have camel case as regular variables. @@ -561,7 +561,7 @@ Therefore, Kdoc should contain the following: Kdoc should not contain: - Empty descriptions in tag blocks. It is better not to write Kdoc than waste code line space. - There should be no empty lines between the method/class declaration and the end of Kdoc (`*/` symbols). -- `@author` tag. It doesn't matter who originally created a class when you can use `git blame` or VCS of your choice to look through the changes history. +- `@author` tag. It doesn't matter who originally created a class when you can use `git blame` or VCS of your choice to look through the change history. Important notes: - KDoc does not support the `@deprecated` tag. Instead, use the `@Deprecated` annotation. - The `@since` tag should be used for versions only. Do not use dates in `@since` tag, it's confusing and less accurate. @@ -613,7 +613,7 @@ Chinese version: `版权所有 (c) 华为技术有限公司 2012-2020` \ English version: `Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved.` `2012` and `2020` are the years the file was first created and the current year, respectively. -Do not place **release notes** in header, use VCS to keep track of changes in file. Notable changes can be marked in individual KDocs using `@since` tag with version. +Do not place **release notes** in a header, use VCS to keep track of changes in a file. Notable changes can be marked in individual KDocs using `@since` tag with version. Invalid example: ```kotlin @@ -871,7 +871,7 @@ when (node.elementType) { CLASS -> checkClassElements(node) } ``` -**Exception:** The only exception is ternary operator in Kotlin (a single line `if () <> else <>` ) +**Exception:** The only exception is a ternary operator in Kotlin (a single line `if () <> else <>` ) **Invalid example:** @@ -968,7 +968,7 @@ someObject .filter() ``` - The code block is placed immediately after the opening parenthesis. -- The code block is placed immediately after an arrow in lambda: +- The code block is placed immediately after an arrow in a lambda: ```kotlin arg.map { value -> @@ -1218,7 +1218,7 @@ fun foo( If and only if the first parameter is on the same line as an opening parenthesis, all parameters can be horizontally aligned by the first parameter. Otherwise, there should be a line break after an opening parenthesis. -Kotlin 1.4 introduced a trailing comma as an optional feature, so it is generally recommended to place all parameters on a separate line +Kotlin 1.4 introduced a trailing comma as an optional feature, so it is generally recommended placing all parameters on a separate line and append [trailing comma](https://kotlinlang.org/docs/reference/whatsnew14.html#trailing-comma). It makes the resolving of merge conflicts easier. @@ -1324,7 +1324,7 @@ Follow the recommendations below for using space to separate keywords: 6. There should be *only one space* between the identifier and its type: `list: List` If the type is nullable, there should be no space before `?`. -7. When using `[]` operator (`get/set`) there should be **no** spaces between identifier and `[` : `someList[0]`. +7. When using `[]` operator (`get/set`) there should be **no** spaces between an identifier and `[` : `someList[0]`. 8. There should be no space between a method or constructor name (both at declaration and at call site) and a parenthesis: `foo() {}`. Note that this sub-rule is related only to spaces; the rules for whitespaces are described in [see 3.6.2](#r3.6.2). @@ -2159,8 +2159,8 @@ class YourClass(var name: String) { ``` The `init` block was not added to Kotlin to help you initialize your properties; it is needed for more complex tasks. -Therefore if the `init` block contains only assignments of variables - move it directly to properties to be correctly initialized near the declaration. -In some cases, this rule can be in clash with [6.1.1](#r6.1.1), but that should not stop you. +Therefore, if the `init` block contains only assignments of variables - move it directly to properties to be correctly initialized near the declaration. +In some cases, this rule can be in a clash with [6.1.1](#r6.1.1), but that should not stop you. **Invalid example**: ```kotlin @@ -2227,7 +2227,7 @@ class NotAbstract { #### 6.1.7 When using the "implicit backing property" scheme, the name of real and back property should be the same Kotlin has a mechanism of [backing properties](https://kotlinlang.org/docs/reference/properties.html#backing-properties). -In some cases, implicit backing is not enough and it should be done explicitly: +In some cases, implicit backing is not enough, and it should be done explicitly: ```kotlin private var _table: Map? = null val table: Map @@ -2259,10 +2259,10 @@ class A { } ``` -From the callee code, these methods look like access to this property: `A().isEmpty = true` for setter and `A().isEmpty` for getter. +From the callee code, these methods look like access to this property: `A().isEmpty = true` for a setter and `A().isEmpty` for a getter. However, when `get` and `set` are overridden, it isn't very clear for a developer who uses this particular class. -The developer expects to get the property value but receives some unknown value and some extra side-effect hidden by the custom getter/setter. +The developer expects to get the property value but receives some unknown value and some extra side effect hidden by the custom getter/setter. Use extra functions instead to avoid confusion. From e9aaee8eb96f02c5bc07e1c8e2b0a4483ac6a001 Mon Sep 17 00:00:00 2001 From: kentr0w Date: Wed, 28 Apr 2021 16:23:28 +0300 Subject: [PATCH 02/14] Warnings ### What's done: Fixed after review Merged Fixed more warnings --- .../plugin/gradle/DiktatJavaExecTaskBase.kt | 2 +- diktat-rules/pom.xml | 5 ++++ .../cqfn/diktat/ruleset/constants/Warnings.kt | 2 +- .../cqfn/diktat/ruleset/dummy/DummyWarning.kt | 1 + .../diktat/ruleset/generation/Generation.kt | 4 +-- .../cqfn/diktat/ruleset/rules/DiktatRule.kt | 2 +- .../rules/chapter1/IdentifierNaming.kt | 17 +++++------- .../rules/chapter2/kdoc/KdocFormatting.kt | 7 +++-- .../ruleset/rules/chapter3/MagicNumberRule.kt | 1 - .../rules/chapter3/StringConcatenationRule.kt | 1 - .../rules/chapter3/files/FileStructureRule.kt | 3 +-- .../cqfn/diktat/ruleset/utils/AstNodeUtils.kt | 4 +-- .../diktat/ruleset/utils/StringCaseUtils.kt | 26 +++++++++++-------- .../ruleset/chapter2/HeaderCommentRuleTest.kt | 1 - .../ClassLikeStructuresOrderRuleWarnTest.kt | 1 - .../ruleset/chapter3/EmptyBlockWarnTest.kt | 2 -- .../ruleset/chapter3/FileStructureRuleTest.kt | 2 +- .../diktat/ruleset/utils/AstNodeUtilsTest.kt | 2 +- .../ruleset/utils/AvailableRulesDocTest.kt | 2 +- .../ruleset/utils/RulesConfigYamlTest.kt | 2 ++ .../org/cqfn/diktat/util/FixTestBase.kt | 2 +- .../test/framework/common/StreamGobbler.java | 6 ++--- .../test/framework/config/TestConfig.kt | 1 + .../framework/processing/TestCheckWarn.kt | 2 +- .../test/framework/processing/TestMixed.kt | 2 +- info/guide/diktat-coding-convention.md | 4 +-- info/guide/guide-chapter-1.md | 2 +- 27 files changed, 54 insertions(+), 52 deletions(-) diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt index fa47148df1..51396c81bf 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt @@ -25,7 +25,7 @@ import javax.inject.Inject * * Note: class being `open` is required for gradle to create a task. */ -class DiktatJavaExecTaskBase @Inject constructor( +open class DiktatJavaExecTaskBase @Inject constructor( gradleVersionString: String, diktatExtension: DiktatExtension, diktatConfiguration: Configuration, diff --git a/diktat-rules/pom.xml b/diktat-rules/pom.xml index 7caf9fa3b2..7546beb87e 100644 --- a/diktat-rules/pom.xml +++ b/diktat-rules/pom.xml @@ -119,6 +119,11 @@ + + + -Xinline-classes + + diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt index b55ae05d2e..2c8f4a8cd5 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Warnings.kt @@ -28,7 +28,7 @@ typealias ListOfPairs = MutableList> "WRONG_NEWLINES" ) enum class Warnings( - val canBeAutoCorrected: Boolean, + private val canBeAutoCorrected: Boolean, val ruleId: String, private val warn: String) : Rule { // ======== dummy test warning ====== diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/dummy/DummyWarning.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/dummy/DummyWarning.kt index d7bb77507b..d1383a5446 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/dummy/DummyWarning.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/dummy/DummyWarning.kt @@ -17,6 +17,7 @@ class DummyWarning(configRules: List) : DiktatRule( Warnings.FILE_NAME_MATCH_CLASS ) ) { + @Suppress("UNUSED") private lateinit var filePath: String @Suppress("EmptyFunctionBlock") diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/generation/Generation.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/generation/Generation.kt index 62282fb6c9..56d46346f9 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/generation/Generation.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/generation/Generation.kt @@ -64,8 +64,8 @@ private fun validateYear() { val files = File("diktat-rules/src/test/resources/test/paragraph2/header") files .listFiles() - .filterNot { it.name.contains("CopyrightDifferentYearTest.kt") } - .forEach { file -> + ?.filterNot { it.name.contains("CopyrightDifferentYearTest.kt") } + ?.forEach { file -> val tempFile = createTempFile().toFile() tempFile.printWriter().use { writer -> file.forEachLine { line -> diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt index e5fbf97058..f7b6030655 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt @@ -21,7 +21,7 @@ private typealias DiktatConfigRule = org.cqfn.diktat.common.config.rules.Rule @Suppress("TooGenericExceptionCaught") abstract class DiktatRule(id: String, val configRules: List, - val inspections: List) : Rule(id) { + private val inspections: List) : Rule(id) { /** * Default value is false */ diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt index 65c54a71d9..307babd4c2 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt @@ -50,7 +50,6 @@ import com.pinterest.ktlint.core.ast.ElementType.DESTRUCTURING_DECLARATION import com.pinterest.ktlint.core.ast.ElementType.DESTRUCTURING_DECLARATION_ENTRY import com.pinterest.ktlint.core.ast.ElementType.FILE import com.pinterest.ktlint.core.ast.ElementType.FUNCTION_TYPE -import com.pinterest.ktlint.core.ast.ElementType.PROPERTY import com.pinterest.ktlint.core.ast.ElementType.REFERENCE_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.TYPE_PARAMETER import com.pinterest.ktlint.core.ast.ElementType.TYPE_REFERENCE @@ -163,7 +162,7 @@ class IdentifierNaming(configRules: List) : DiktatRule( var namesOfVariables = extractVariableIdentifiers(node) // Only local private properties will be autofix in order not to break code if there are usages in other files. // Destructuring declarations are only allowed for local variables/values, so we don't need to calculate `isFix` for every node in `namesOfVariables` - val isFix = isFixMode && if (node.elementType == PROPERTY) (node.psi as KtProperty).run { isLocal || isPrivate() } else true + val isFix = isFixMode && if (node.elementType == ElementType.PROPERTY) (node.psi as KtProperty).run { isLocal || isPrivate() } else true namesOfVariables .forEach { variableName -> // variable should not contain only one letter in it's name. This is a bad example: b512 @@ -242,15 +241,13 @@ class IdentifierNaming(configRules: List) : DiktatRule( @Suppress("UnsafeCallOnNullableType") private fun extractVariableIdentifiers(node: ASTNode): List { val destructingDeclaration = node.getFirstChildWithType(DESTRUCTURING_DECLARATION) - val result = if (destructingDeclaration != null) { - destructingDeclaration.getAllChildrenWithType(DESTRUCTURING_DECLARATION_ENTRY) - .map { it.getIdentifierName()!! } - } else if (node.parents().count() > 1 && node.treeParent.elementType == VALUE_PARAMETER_LIST && + val result = destructingDeclaration?.getAllChildrenWithType(DESTRUCTURING_DECLARATION_ENTRY)?.map { it.getIdentifierName()!! } + ?: if (node.parents().count() > 1 && node.treeParent.elementType == VALUE_PARAMETER_LIST && node.treeParent.treeParent.elementType == FUNCTION_TYPE) { - listOfNotNull(node.getIdentifierName()) - } else { - listOf(node.getIdentifierName()!!) - } + listOfNotNull(node.getIdentifierName()) + } else { + listOf(node.getIdentifierName()!!) + } // no need to do checks if variables are in a special list with exceptions return result.filterNot { oneCharIdentifiers.contains(it.text) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt index b53a4fc814..0fabddb676 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt @@ -84,8 +84,8 @@ class KdocFormatting(configRules: List) : DiktatRule( checkNoDeprecatedTag(node) checkEmptyTags(node.kDocTags()) checkSpaceAfterTag(node.kDocTags()) - node.kDocBasicTags().let { checkEmptyLineBeforeBasicTags(it) } - node.kDocBasicTags().let { checkEmptyLinesBetweenBasicTags(it) } + checkEmptyLineBeforeBasicTags(node.kDocBasicTags()) + checkEmptyLinesBetweenBasicTags(node.kDocBasicTags()) checkBasicTagsOrder(node) checkNewLineAfterSpecialTags(node) checkAuthorAndDate(node) @@ -186,8 +186,7 @@ class KdocFormatting(configRules: List) : DiktatRule( } acc } - .map { it.knownTag } - .equals(basicTagsOrdered) + .map { it.knownTag } == basicTagsOrdered if (!isTagsInCorrectOrder) { KDOC_WRONG_TAGS_ORDER.warnAndFix(configRules, emitWarn, isFixMode, diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt index c53573e5d9..cf6174d2a0 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt @@ -8,7 +8,6 @@ import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION -import com.pinterest.ktlint.core.ast.ElementType.CONST_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.ENUM_ENTRY import com.pinterest.ktlint.core.ast.ElementType.FLOAT_CONSTANT import com.pinterest.ktlint.core.ast.ElementType.FUN diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringConcatenationRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringConcatenationRule.kt index 25b7b34881..72b87de096 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringConcatenationRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringConcatenationRule.kt @@ -6,7 +6,6 @@ import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION -import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.DOT_QUALIFIED_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.OPERATION_REFERENCE import com.pinterest.ktlint.core.ast.ElementType.PLUS diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt index f1c70a54dc..82b4bad358 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt @@ -67,8 +67,7 @@ class FileStructureRule(configRules: List) : DiktatRule( } private val standardImportsAsName = StandardPlatforms .values() - .map { it to it.packages } - .toMap() + .associate { it to it.packages } .mapValues { (_, value) -> value.map { it.split(PACKAGE_SEPARATOR).map(Name::identifier) } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt index c31eadfa36..591c58dfee 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt @@ -87,7 +87,7 @@ fun ASTNode.isTextLengthInRange(range: IntRange): Boolean = this.textLength in r /** * getting first child name with IDENTIFIER type * - * @return node with type [IDENTIFIER] or null if it is not present + * @return node with type [ElementType.IDENTIFIER] or null if it is not present */ fun ASTNode.getIdentifierName(): ASTNode? = this.getFirstChildWithType(ElementType.IDENTIFIER) @@ -648,7 +648,7 @@ fun ASTNode.areChildrenBeforeChild(children: List, beforeChild: ASTNode @Suppress("UnsafeCallOnNullableType") fun ASTNode.areChildrenBeforeGroup(children: List, group: List): Boolean { require(children.isNotEmpty() && group.isNotEmpty()) { "no sense to operate on empty lists" } - return children.map { getChildren(null).indexOf(it) }.maxOrNull()!! < group.map { getChildren(null).indexOf(it) }.minOrNull()!! + return children.maxOf { getChildren(null).indexOf(it) } < group.minOf { getChildren(null).indexOf(it) } } /** diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringCaseUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringCaseUtils.kt index 549ee9dc0f..db49b93a05 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringCaseUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/StringCaseUtils.kt @@ -167,17 +167,21 @@ private fun convertUnknownCaseToCamel(str: String, isFirstLetterCapital: Boolean isPreviousLetterUnderscore = false result.toString() } else { - val result = if (char == '_') { - isPreviousLetterUnderscore = true - "" - } else if (isPreviousLetterUnderscore) { - isPreviousLetterCapital = true - isPreviousLetterUnderscore = false - char.toUpperCase().toString() - } else { - isPreviousLetterCapital = false - isPreviousLetterUnderscore = false - char.toString() + val result = when { + char == '_' -> { + isPreviousLetterUnderscore = true + "" + } + isPreviousLetterUnderscore -> { + isPreviousLetterCapital = true + isPreviousLetterUnderscore = false + char.toUpperCase().toString() + } + else -> { + isPreviousLetterCapital = false + isPreviousLetterUnderscore = false + char.toString() + } } result } diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleTest.kt index 45d7ff2bf6..f7774578ee 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/HeaderCommentRuleTest.kt @@ -6,7 +6,6 @@ import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_MISSING_IN_NON_SINGLE_C import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_MISSING_OR_WRONG_COPYRIGHT import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_NOT_BEFORE_PACKAGE import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_WRONG_FORMAT -import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_CONTAINS_DATE_OR_AUTHOR import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID import org.cqfn.diktat.ruleset.rules.chapter2.comments.HeaderCommentRule import org.cqfn.diktat.util.LintTestBase diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/ClassLikeStructuresOrderRuleWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/ClassLikeStructuresOrderRuleWarnTest.kt index 05dbfb2fb0..d32f793bd2 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/ClassLikeStructuresOrderRuleWarnTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/ClassLikeStructuresOrderRuleWarnTest.kt @@ -8,7 +8,6 @@ import org.cqfn.diktat.util.LintTestBase import com.pinterest.ktlint.core.LintError import generated.WarningNames -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/EmptyBlockWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/EmptyBlockWarnTest.kt index c2a87615f0..37e712e07b 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/EmptyBlockWarnTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/EmptyBlockWarnTest.kt @@ -8,8 +8,6 @@ import org.cqfn.diktat.util.LintTestBase import com.pinterest.ktlint.core.LintError import generated.WarningNames -import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/FileStructureRuleTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/FileStructureRuleTest.kt index 9ac9122706..f0f3c630af 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/FileStructureRuleTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/FileStructureRuleTest.kt @@ -363,7 +363,7 @@ class FileStructureRuleTest : LintTestBase(::FileStructureRule) { @Test @Tag(WarningNames.UNUSED_IMPORT) - fun `Acute`() { + fun `Acute import`() { lintMethod( """ |package org.cqfn.diktat.example diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt index f5fa29987a..52bb964a70 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt @@ -757,7 +757,7 @@ private class PrettyPrintingVisitor(private val elementType: IElementType, KtLint.Params( text = code, ruleSets = listOf(RuleSet("test", PrettyPrintingVisitor(elementType, level, maxLevel, expected))), - cb = { _, _ -> Unit } + cb = { _, _ -> } ) ) } diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AvailableRulesDocTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AvailableRulesDocTest.kt index 6ac304775e..d07c06287f 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AvailableRulesDocTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AvailableRulesDocTest.kt @@ -16,7 +16,7 @@ class AvailableRulesDocTest { val splitMarkDown = line .split("|") - val ruleName = splitMarkDown.get(SPLIT_MARK).trim() + val ruleName = splitMarkDown[SPLIT_MARK].trim() if (!ruleName.startsWith(TABLE_DELIMITER) && !ruleName.startsWith(RULE_NAME_HEADER)) { diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/RulesConfigYamlTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/RulesConfigYamlTest.kt index 97739f4a31..7df827bccb 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/RulesConfigYamlTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/RulesConfigYamlTest.kt @@ -19,6 +19,7 @@ import kotlinx.serialization.encodeToString * Special test that checks that developer has not forgotten to add his warning to a diktat-analysis.yml * This file is needed to be in tact with latest changes in Warnings.kt */ +@Suppress("UNUSED") inline class RulesConfigYamlTest(private val pathMap: Map = mapOf("diktat-analysis.yml" to "diKTat/diktat-rules/src/main/resources/diktat-analysis.yml", "diktat-analysis-huawei.yml" to "diKTat/diktat-rules/src/main/resources/diktat-analysis-huawei.yml", @@ -39,6 +40,7 @@ inline class RulesConfigYamlTest(private val pathMap: Map = } @Test + @Suppress("UNUSED") fun `check kotlin version`() { val currentKotlinVersion = KotlinVersion.CURRENT pathMap.keys.forEach { path -> diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt index 94ad54041d..eae0775caf 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Assertions /** * @property resourceFilePath path to files which will be compared in tests */ -open class FixTestBase(protected val resourceFilePath: String, +open class FixTestBase(private val resourceFilePath: String, private val ruleSetProviderRef: (rulesConfigList: List?) -> RuleSetProvider, private val cb: LintErrorCallback = defaultCallback, private val rulesConfigList: List? = null) { diff --git a/diktat-test-framework/src/main/java/org/cqfn/diktat/test/framework/common/StreamGobbler.java b/diktat-test-framework/src/main/java/org/cqfn/diktat/test/framework/common/StreamGobbler.java index bb236cbd86..7484279135 100644 --- a/diktat-test-framework/src/main/java/org/cqfn/diktat/test/framework/common/StreamGobbler.java +++ b/diktat-test-framework/src/main/java/org/cqfn/diktat/test/framework/common/StreamGobbler.java @@ -13,9 +13,9 @@ public class StreamGobbler extends Thread { private static final Logger log = LoggerFactory.getLogger(StreamGobbler.class); - private InputStream inputStream; - private String streamType; - private ArrayList result; + private final InputStream inputStream; + private final String streamType; + private final ArrayList result; private volatile boolean isStopped = false; /** diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfig.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfig.kt index ede63b6faa..71928094c9 100644 --- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfig.kt +++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfig.kt @@ -54,6 +54,7 @@ class TestConfig internal constructor( * different profiles that can be used to control common processing part for tests * (processing differs for different programming languages) */ + @Suppress("UNUSED") enum class TestProfile { CXX, JAVA, KT, PYTHON } diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestCheckWarn.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestCheckWarn.kt index ef5c25eaaa..76a31d50a3 100644 --- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestCheckWarn.kt +++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestCheckWarn.kt @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory */ class TestCheckWarn : TestCompare() { @Suppress("MISSING_KDOC_CLASS_ELEMENTS") override val log: Logger = LoggerFactory.getLogger(TestCheckWarn::class.java) - @Suppress("UnusedPrivateMember") private var testConfig: TestConfig? = null + @Suppress("UnusedPrivateMember", "UNUSED") private var testConfig: TestConfig? = null /** * Get tests execution result diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestMixed.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestMixed.kt index e8d84178ce..8a8b4e576a 100644 --- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestMixed.kt +++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestMixed.kt @@ -4,7 +4,7 @@ import org.cqfn.diktat.test.framework.common.TestBase import org.cqfn.diktat.test.framework.config.TestConfig import org.cqfn.diktat.test.framework.config.TestFrameworkProperties -@Suppress("MISSING_KDOC_TOP_LEVEL", "KDOC_NO_EMPTY_TAGS") // fixme: add documentation when implementation is done +@Suppress("MISSING_KDOC_TOP_LEVEL", "KDOC_NO_EMPTY_TAGS", "UNUSED") // fixme: add documentation when implementation is done class TestMixed : TestBase { private lateinit var testConfig: TestConfig diff --git a/info/guide/diktat-coding-convention.md b/info/guide/diktat-coding-convention.md index a6737a7a6a..8d6f8912b4 100644 --- a/info/guide/diktat-coding-convention.md +++ b/info/guide/diktat-coding-convention.md @@ -318,7 +318,7 @@ Note: The calling property access syntax is preferred to call getter directly. I b) `is` + boolean variable name() -c) `set` + field/attribute name(). However, note that the syntax and code generation for Kotlin are completely the same as those described for the getters in point. +c) `set` + field/attribute name(). However, note that the syntax and code generation for Kotlin are completely the same as those described for the getters in point a. d) `has` + Noun / adjective () @@ -354,7 +354,7 @@ fun addKeyListener(Listener) ### 1.5 Constants This section describes the general rules for naming constraints. ### 1.5.1 Using UPPER case and underscore characters in a constraint name -Constant names should be in UPPER case, words separated by a underscore. The general constant naming conventions are listed below: +Constant names should be in UPPER case, words separated by an underscore. The general constant naming conventions are listed below: 1. Constants are attributes created with the `const` keyword or top-level/`val` local variables of an object that holds immutable data. In most cases, constants can be identified as a `const val` property from the `object`/`companion object`/file top level. These variables contain fixed constant values that typically should never be changed by programmers. This includes basic types, strings, immutable types, and immutable collections of immutable types. The value is not constant for the object, which state can be changed. 2. Constant names should contain only uppercase letters separated by an underscores. They should have a val or const val modifier to make them final explicitly. In most cases, if you need to specify a constant value, then you need to create it with the "const val" modifier. Note that not all `val` variables are constants. 3. Objects with immutable content, such as `Logger` and `Lock`, can be in uppercase as constants or have camel case as regular variables. diff --git a/info/guide/guide-chapter-1.md b/info/guide/guide-chapter-1.md index b8f6cc5262..407478ed9a 100644 --- a/info/guide/guide-chapter-1.md +++ b/info/guide/guide-chapter-1.md @@ -188,7 +188,7 @@ val String sL = "Launcher"; **Valid example**: ```kotlin -const val int MAX_USER_NUM = 200; +const val Int MAX_USER_NUM = 200; const val String APPLICATION_NAME = "Launcher"; ``` From 2318c778caa93476293103992f1a3b88f424a9af Mon Sep 17 00:00:00 2001 From: kentr0w Date: Wed, 28 Apr 2021 17:05:16 +0300 Subject: [PATCH 03/14] Warnings ### What's done: Fixed according to our code-style --- .../org/cqfn/diktat/test/framework/processing/TestMixed.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestMixed.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestMixed.kt index 8a8b4e576a..063de83afc 100644 --- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestMixed.kt +++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/processing/TestMixed.kt @@ -4,7 +4,11 @@ import org.cqfn.diktat.test.framework.common.TestBase import org.cqfn.diktat.test.framework.config.TestConfig import org.cqfn.diktat.test.framework.config.TestFrameworkProperties -@Suppress("MISSING_KDOC_TOP_LEVEL", "KDOC_NO_EMPTY_TAGS", "UNUSED") // fixme: add documentation when implementation is done +@Suppress( + "MISSING_KDOC_TOP_LEVEL", + "KDOC_NO_EMPTY_TAGS", + "UNUSED" +) // fixme: add documentation when implementation is done class TestMixed : TestBase { private lateinit var testConfig: TestConfig From 96b3e8a3c49a907406e08dfe918043539c744313 Mon Sep 17 00:00:00 2001 From: kentr0w Date: Thu, 29 Apr 2021 15:13:14 +0300 Subject: [PATCH 04/14] Warnings ### What's done: Fixed bug in WhiteSpaceRule.kt Fixed according to our code style --- .../org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt | 2 +- .../cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt | 3 ++- .../kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt index 307babd4c2..c7e19859d1 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt @@ -243,7 +243,7 @@ class IdentifierNaming(configRules: List) : DiktatRule( val destructingDeclaration = node.getFirstChildWithType(DESTRUCTURING_DECLARATION) val result = destructingDeclaration?.getAllChildrenWithType(DESTRUCTURING_DECLARATION_ENTRY)?.map { it.getIdentifierName()!! } ?: if (node.parents().count() > 1 && node.treeParent.elementType == VALUE_PARAMETER_LIST && - node.treeParent.treeParent.elementType == FUNCTION_TYPE) { + node.treeParent.treeParent.elementType == FUNCTION_TYPE) { listOfNotNull(node.getIdentifierName()) } else { listOf(node.getIdentifierName()!!) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt index 254de14f43..2d3410ed68 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt @@ -387,7 +387,8 @@ class WhiteSpaceRule(configRules: List) : DiktatRule( 0 } else { // this can happen, e.g. in lambdas after an arrow, where block can be not surrounded by braces - val isBlockStartingWithComment = treeNext.elementType == BLOCK && treeNext.firstChildNode.isPartOfComment() + // treeNext may not have children ( {_, _ -> }) + val isBlockStartingWithComment = treeNext.elementType == BLOCK && treeNext.firstChildNode?.isPartOfComment() == true if (textContains('\n') || treeNext.isPartOfComment() || isBlockStartingWithComment) null else text.count { it == ' ' } } diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt index 52bb964a70..6a98a825bc 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt @@ -746,6 +746,7 @@ private class PrettyPrintingVisitor(private val elementType: IElementType, ) } } + @Suppress("WRONG_WHITESPACE") companion object { fun assertStringRepr( elementType: IElementType, From 564d05f6ed69599405c1d510b6da6295fff8af25 Mon Sep 17 00:00:00 2001 From: kentr0w Date: Thu, 29 Apr 2021 15:30:08 +0300 Subject: [PATCH 05/14] Warnings ### What's done: Fixed according to our code-style --- .../kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt index d26933e7bf..eba7648171 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt @@ -48,14 +48,17 @@ class DiktatGradlePlugin : Plugin { * Task to check diKTat */ const val DIKTAT_CHECK_TASK = "diktatCheck" + /** * DiKTat configuration */ const val DIKTAT_CONFIGURATION = "diktat" + /** * DiKTat extension */ const val DIKTAT_EXTENSION = "diktat" + /** * Task to run diKTat with fix */ From ed85b9213026ac081ed1ab1d8e1f46a2f6ed7ca0 Mon Sep 17 00:00:00 2001 From: kentr0w Date: Thu, 29 Apr 2021 19:15:10 +0300 Subject: [PATCH 06/14] Warnings ### What's done: Rollback all changes in md files --- CONTRIBUTING.md | 2 +- README.md | 4 +-- diktat-gradle-plugin/README.md | 2 +- .../rules/chapter1/IdentifierNaming.kt | 1 - info/guide/diktat-coding-convention.md | 32 +++++++++---------- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3d36207438..c7029e242d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -If you're reading this - then you have decided to contribute to our project. Oh, poor you... +If you reading this - then you have decided to contribute to our project. Oh, poor you... Rules are very simple: 1. Fork this repository to your own account 2. Make your changes and verify that tests pass (or wait that our CI/CD will do everything for you) diff --git a/README.md b/README.md index f45c677663..1345f1b214 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ diktat { reporter = "custom:name:pathToJar" } ``` -Name parameter is the name of your reporter and as the last parameter you should specify a path to jar, which contains your reporter. +Name parameter is the name of your reporter and as the last parameter you should specify path to jar, which contains your reporter. [Example of the junit custom reporter.](https://github.com/kryanod/ktlint-junit-reporter) You can also specify an output. @@ -286,7 +286,7 @@ for example, a filename of file where the code is stored; 3) We added a bunch of visitors, checkers and fixers that will extended KTlint functionaliity with code style rules; 4) We have proposed a code style for Kotlin language. -Before you make a pull request, make sure the build is clean as we have a lot of tests and other prechecks: +Before you make a pull request, make sure the build is clean as we have lot of tests and other prechecks: ```bash $ mvn clean install diff --git a/diktat-gradle-plugin/README.md b/diktat-gradle-plugin/README.md index 7dde684c8a..0d62b8ad2d 100644 --- a/diktat-gradle-plugin/README.md +++ b/diktat-gradle-plugin/README.md @@ -2,7 +2,7 @@ Build of gradle plugin is performed by gradle, but is wrapped in maven build. The module's `pom.xml` isn't exactly accurate and doesn't include gradle-specific dependencies, that are automatically provided by gradle when applying the plugin. -To avoid versions duplication, diktat and ktlint versions are passed to gradle via properties when running gradle task from a maven. +To avoid versions duplication, diktat and ktlint versions are passed to gradle via properties when running gradle task from maven. These versions are then written in a file and then included in the plugin jar to determine dependencies for JavaExec. Gradle plugin marker pom, which is normally produced by `java-gradle-plugin` plugin during gradle build, diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt index c7e19859d1..90cf2dcb03 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt @@ -238,7 +238,6 @@ class IdentifierNaming(configRules: List) : DiktatRule( * * need to handle DESTRUCTURING_DECLARATION correctly, as it does not have IDENTIFIER leaf. * * function type can have VALUE_PARAMETERs without name */ - @Suppress("UnsafeCallOnNullableType") private fun extractVariableIdentifiers(node: ASTNode): List { val destructingDeclaration = node.getFirstChildWithType(DESTRUCTURING_DECLARATION) val result = destructingDeclaration?.getAllChildrenWithType(DESTRUCTURING_DECLARATION_ENTRY)?.map { it.getIdentifierName()!! } diff --git a/info/guide/diktat-coding-convention.md b/info/guide/diktat-coding-convention.md index 8d6f8912b4..463b2bad37 100644 --- a/info/guide/diktat-coding-convention.md +++ b/info/guide/diktat-coding-convention.md @@ -177,13 +177,13 @@ Also, we need to consider the following factors when programming on Kotlin: **Invalid Example** — not recommended examples of rules and recommendations. -Unless otherwise stated, this specification applies to version 1.3 and later of Kotlin. +Unless otherwise stated, this specification applies to versions 1.3 and later of Kotlin. ### Exceptions Even though exceptions may exist, it is essential to understand why rules and recommendations are needed. -Depending on a project situation or personal habits, you can break some rules. However, remember that one exception may lead to many and eventually can destroy code consistency. As such, there should be very few exceptions. +Depending on a project situation or personal habits, you can break some of the rules. However, remember that one exception may lead to many and eventually can destroy code consistency. As such, there should be very few exceptions. When modifying open-source code or third-party code, you can choose to use the code style from this open-source project (instead of using the existing specifications) to maintain consistency. Software that is directly based on the Android native operating system interface, such as the Android Framework, remains consistent with the Android style. # 1. Naming @@ -354,7 +354,7 @@ fun addKeyListener(Listener) ### 1.5 Constants This section describes the general rules for naming constraints. ### 1.5.1 Using UPPER case and underscore characters in a constraint name -Constant names should be in UPPER case, words separated by an underscore. The general constant naming conventions are listed below: +Constant names should be in UPPER case, words separated by underscore. The general constant naming conventions are listed below: 1. Constants are attributes created with the `const` keyword or top-level/`val` local variables of an object that holds immutable data. In most cases, constants can be identified as a `const val` property from the `object`/`companion object`/file top level. These variables contain fixed constant values that typically should never be changed by programmers. This includes basic types, strings, immutable types, and immutable collections of immutable types. The value is not constant for the object, which state can be changed. 2. Constant names should contain only uppercase letters separated by an underscores. They should have a val or const val modifier to make them final explicitly. In most cases, if you need to specify a constant value, then you need to create it with the "const val" modifier. Note that not all `val` variables are constants. 3. Objects with immutable content, such as `Logger` and `Lock`, can be in uppercase as constants or have camel case as regular variables. @@ -566,7 +566,7 @@ Therefore, Kdoc should contain the following: Kdoc should not contain: - Empty descriptions in tag blocks. It is better not to write Kdoc than waste code line space. - There should be no empty lines between the method/class declaration and the end of Kdoc (`*/` symbols). -- `@author` tag. It doesn't matter who originally created a class when you can use `git blame` or VCS of your choice to look through the change history. +- `@author` tag. It doesn't matter who originally created a class when you can use `git blame` or VCS of your choice to look through the changes history. Important notes: - KDoc does not support the `@deprecated` tag. Instead, use the `@Deprecated` annotation. - The `@since` tag should be used for versions only. Do not use dates in `@since` tag, it's confusing and less accurate. @@ -618,7 +618,7 @@ Chinese version: `版权所有 (c) 华为技术有限公司 2012-2020` \ English version: `Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved.` `2012` and `2020` are the years the file was first created and the current year, respectively. -Do not place **release notes** in a header, use VCS to keep track of changes in a file. Notable changes can be marked in individual KDocs using `@since` tag with version. +Do not place **release notes** in header, use VCS to keep track of changes in a file. Notable changes can be marked in individual KDocs using `@since` tag with version. Invalid example: ```kotlin @@ -924,7 +924,7 @@ when (node.elementType) { CLASS -> checkClassElements(node) } ``` -**Exception:** The only exception is a ternary operator in Kotlin (a single line `if () <> else <>` ) +**Exception:** The only exception is ternary operator in Kotlin (a single line `if () <> else <>` ) **Invalid example:** @@ -1021,7 +1021,7 @@ someObject .filter() ``` - The code block is placed immediately after the opening parenthesis. -- The code block is placed immediately after an arrow in a lambda: +- The code block is placed immediately after an arrow in lambda: ```kotlin arg.map { value -> @@ -1271,7 +1271,7 @@ fun foo( If and only if the first parameter is on the same line as an opening parenthesis, all parameters can be horizontally aligned by the first parameter. Otherwise, there should be a line break after an opening parenthesis. -Kotlin 1.4 introduced a trailing comma as an optional feature, so it is generally recommended placing all parameters on a separate line +Kotlin 1.4 introduced a trailing comma as an optional feature, so it is generally recommended to place all parameters on a separate line and append [trailing comma](https://kotlinlang.org/docs/reference/whatsnew14.html#trailing-comma). It makes the resolving of merge conflicts easier. @@ -1394,7 +1394,7 @@ Follow the recommendations below for using space to separate keywords: 6. There should be *only one space* between the identifier and its type: `list: List` If the type is nullable, there should be no space before `?`. -7. When using `[]` operator (`get/set`) there should be **no** spaces between an identifier and `[` : `someList[0]`. +7. When using `[]` operator (`get/set`) there should be **no** spaces between identifier and `[` : `someList[0]`. 8. There should be no space between a method or constructor name (both at declaration and at call site) and a parenthesis: `foo() {}`. Note that this sub-rule is related only to spaces; the rules for whitespaces are described in [see 3.6.2](#r3.6.2). @@ -2254,9 +2254,9 @@ class YourClass(var name: String) { } ``` -The `init` block was not added to Kotlin to help you initialize your properties; it is needed for more complex tasks. -Therefore, if the `init` block contains only assignments of variables - move it directly to properties to be correctly initialized near the declaration. -In some cases, this rule can be in a clash with [6.1.1](#r6.1.1), but that should not stop you. +The `init` block was not added to Kotlin to help you initialize your properties; it is needed for more complex tasks. +Therefore if the `init` block contains only assignments of variables - move it directly to properties to be correctly initialized near the declaration. +In some cases, this rule can be in clash with [6.1.1](#r6.1.1), but that should not stop you. **Invalid example**: ```kotlin @@ -2323,7 +2323,7 @@ class NotAbstract { #### 6.1.7 When using the "implicit backing property" scheme, the name of real and back property should be the same Kotlin has a mechanism of [backing properties](https://kotlinlang.org/docs/reference/properties.html#backing-properties). -In some cases, implicit backing is not enough, and it should be done explicitly: +In some cases, implicit backing is not enough and it should be done explicitly: ```kotlin private var _table: Map? = null val table: Map @@ -2355,10 +2355,10 @@ class A { } ``` -From the callee code, these methods look like access to this property: `A().isEmpty = true` for a setter and `A().isEmpty` for a getter. +From the callee code, these methods look like access to this property: `A().isEmpty = true` for setter and `A().isEmpty` for getter. -However, when `get` and `set` are overridden, it isn't very clear for a developer who uses this particular class. -The developer expects to get the property value but receives some unknown value and some extra side effect hidden by the custom getter/setter. +However, when `get` and `set` are overridden, it isn't very clear for a developer who uses this particular class. +The developer expects to get the property value but receives some unknown value and some extra side-effect hidden by the custom getter/setter. Use extra functions instead to avoid confusion. From 727dd89e653eabfa47fd7e889d3fa2bb1a488f53 Mon Sep 17 00:00:00 2001 From: kentr0w Date: Fri, 30 Apr 2021 10:46:52 +0300 Subject: [PATCH 07/14] Warnings ### What's done: Fixed for test --- .../src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt index eae0775caf..d808f1cc5c 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Assertions /** * @property resourceFilePath path to files which will be compared in tests */ -open class FixTestBase(private val resourceFilePath: String, +open class FixTestBase(val resourceFilePath: String, private val ruleSetProviderRef: (rulesConfigList: List?) -> RuleSetProvider, private val cb: LintErrorCallback = defaultCallback, private val rulesConfigList: List? = null) { From 4a1fe9857573f30148216fa8716ed2e43387e041 Mon Sep 17 00:00:00 2001 From: kentr0w Date: Fri, 30 Apr 2021 11:29:12 +0300 Subject: [PATCH 08/14] Warnings ### What's done: Fixed after review --- .../ruleset/rules/chapter1/IdentifierNaming.kt | 17 ++++++++++------- .../diktat/ruleset/utils/AstNodeUtilsTest.kt | 2 +- .../kotlin/org/cqfn/diktat/util/FixTestBase.kt | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt index 90cf2dcb03..903614ac13 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt @@ -238,15 +238,18 @@ class IdentifierNaming(configRules: List) : DiktatRule( * * need to handle DESTRUCTURING_DECLARATION correctly, as it does not have IDENTIFIER leaf. * * function type can have VALUE_PARAMETERs without name */ + @Suppress("UnsafeCallOnNullableType") private fun extractVariableIdentifiers(node: ASTNode): List { val destructingDeclaration = node.getFirstChildWithType(DESTRUCTURING_DECLARATION) - val result = destructingDeclaration?.getAllChildrenWithType(DESTRUCTURING_DECLARATION_ENTRY)?.map { it.getIdentifierName()!! } - ?: if (node.parents().count() > 1 && node.treeParent.elementType == VALUE_PARAMETER_LIST && - node.treeParent.treeParent.elementType == FUNCTION_TYPE) { - listOfNotNull(node.getIdentifierName()) - } else { - listOf(node.getIdentifierName()!!) - } + val result = if (destructingDeclaration != null) { + destructingDeclaration.getAllChildrenWithType(DESTRUCTURING_DECLARATION_ENTRY) + .map { it.getIdentifierName()!! } + } else if (node.parents().count() > 1 && node.treeParent.elementType == VALUE_PARAMETER_LIST && + node.treeParent.treeParent.elementType == FUNCTION_TYPE) { + listOfNotNull(node.getIdentifierName()) + } else { + listOf(node.getIdentifierName()!!) + } // no need to do checks if variables are in a special list with exceptions return result.filterNot { oneCharIdentifiers.contains(it.text) } diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt index 6a98a825bc..c82cf91afb 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtilsTest.kt @@ -746,7 +746,7 @@ private class PrettyPrintingVisitor(private val elementType: IElementType, ) } } - @Suppress("WRONG_WHITESPACE") + companion object { fun assertStringRepr( elementType: IElementType, diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt index d808f1cc5c..94ad54041d 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/FixTestBase.kt @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Assertions /** * @property resourceFilePath path to files which will be compared in tests */ -open class FixTestBase(val resourceFilePath: String, +open class FixTestBase(protected val resourceFilePath: String, private val ruleSetProviderRef: (rulesConfigList: List?) -> RuleSetProvider, private val cb: LintErrorCallback = defaultCallback, private val rulesConfigList: List? = null) { From bbabfea7384c98d4582d2025c8bc97fc2e71697c Mon Sep 17 00:00:00 2001 From: kentr0w Date: Fri, 30 Apr 2021 12:04:19 +0300 Subject: [PATCH 09/14] Warnings ### What's done: Added suppress Added flags to poms --- diktat-common/pom.xml | 3 +++ diktat-gradle-plugin/build.gradle.kts | 3 ++- diktat-maven-plugin/pom.xml | 4 ++++ diktat-rules/pom.xml | 2 ++ .../cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt | 2 +- diktat-test-framework/pom.xml | 3 +++ 6 files changed, 15 insertions(+), 2 deletions(-) diff --git a/diktat-common/pom.xml b/diktat-common/pom.xml index c13c5f7868..35936fedd9 100644 --- a/diktat-common/pom.xml +++ b/diktat-common/pom.xml @@ -81,6 +81,9 @@ + + -Werror + kotlinx-serialization diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index 58c649ba7b..90ad50744e 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -62,7 +62,8 @@ tasks.withType { apiVersion = "1.3" jvmTarget = "1.8" useIR = true - } + allWarningsAsErrors = true + } dependsOn.add(generateVersionsFile) } diff --git a/diktat-maven-plugin/pom.xml b/diktat-maven-plugin/pom.xml index 5778ae1f52..b85060c0e9 100644 --- a/diktat-maven-plugin/pom.xml +++ b/diktat-maven-plugin/pom.xml @@ -106,6 +106,10 @@ src/test/kotlin + + -Werror + -Xopt-in=kotlin.RequiresOptIn + diff --git a/diktat-rules/pom.xml b/diktat-rules/pom.xml index 7546beb87e..8cd91928c5 100644 --- a/diktat-rules/pom.xml +++ b/diktat-rules/pom.xml @@ -121,7 +121,9 @@ + -Werror -Xinline-classes + -Xopt-in=kotlin.RequiresOptIn diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt index 903614ac13..821a979570 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt @@ -245,7 +245,7 @@ class IdentifierNaming(configRules: List) : DiktatRule( destructingDeclaration.getAllChildrenWithType(DESTRUCTURING_DECLARATION_ENTRY) .map { it.getIdentifierName()!! } } else if (node.parents().count() > 1 && node.treeParent.elementType == VALUE_PARAMETER_LIST && - node.treeParent.treeParent.elementType == FUNCTION_TYPE) { + node.treeParent.treeParent.elementType == FUNCTION_TYPE) { listOfNotNull(node.getIdentifierName()) } else { listOf(node.getIdentifierName()!!) diff --git a/diktat-test-framework/pom.xml b/diktat-test-framework/pom.xml index 763dd44987..c848d7d214 100644 --- a/diktat-test-framework/pom.xml +++ b/diktat-test-framework/pom.xml @@ -69,6 +69,9 @@ compile + + -Werror + src/main/java src/main/kotlin From f889dc7da197b6f995e1a61f3c4bb89d9b2fa41d Mon Sep 17 00:00:00 2001 From: kentr0w Date: Fri, 30 Apr 2021 12:30:16 +0300 Subject: [PATCH 10/14] Warnings ### What's done: Remove ktlint implementation --- diktat-gradle-plugin/build.gradle.kts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index 90ad50744e..4c0554fe4a 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -3,7 +3,7 @@ import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.getCurr plugins { `java-gradle-plugin` - kotlin("jvm") version "1.4.32" + kotlin("jvm") version "1.3.72" jacoco id("pl.droidsonroids.jacoco.testkit") version "1.0.7" id("org.gradle.test-retry") version "1.2.1" @@ -26,9 +26,6 @@ val jacocoVersion = project.properties.getOrDefault("jacocoVersion", "0.8.6") as dependencies { implementation(kotlin("gradle-plugin-api")) - implementation("com.pinterest.ktlint:ktlint-core:$ktlintVersion") { - exclude("com.pinterest.ktlint", "ktlint-ruleset-standard") - } implementation("org.cqfn.diktat:diktat-rules:$diktatVersion") testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") From 1f41d1987809d0a1c285e60107d613f26592a9d9 Mon Sep 17 00:00:00 2001 From: kentr0w Date: Fri, 30 Apr 2021 14:15:04 +0300 Subject: [PATCH 11/14] Warnings ### What's done: Exclude some libs --- diktat-gradle-plugin/build.gradle.kts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index 4c0554fe4a..7b81920dcc 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -26,7 +26,14 @@ val jacocoVersion = project.properties.getOrDefault("jacocoVersion", "0.8.6") as dependencies { implementation(kotlin("gradle-plugin-api")) - implementation("org.cqfn.diktat:diktat-rules:$diktatVersion") + implementation("org.cqfn.diktat:diktat-rules:$diktatVersion") { + exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk8") + exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk7") + exclude("org.jetbrains.kotlin", "kotlin-stdlib") + exclude("org.jetbrains.kotlin", "kotlin-stdlib-common") + exclude("org.jetbrains.kotlin", "kotlin-script-runtime") + exclude("org.jetbrains.kotlin", "kotlin-reflect") + } testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion") From fd4c9e7c6c232fd26297ebc6af741bfeff43a4c5 Mon Sep 17 00:00:00 2001 From: kentr0w Date: Fri, 30 Apr 2021 14:24:50 +0300 Subject: [PATCH 12/14] Warnings ### What's done: Exclude some libs --- diktat-gradle-plugin/build.gradle.kts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index 7b81920dcc..4fd41e5386 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -27,12 +27,11 @@ dependencies { implementation(kotlin("gradle-plugin-api")) implementation("org.cqfn.diktat:diktat-rules:$diktatVersion") { + exclude("org.jetbrains.kotlin", "kotlin-compiler-embeddable") exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk8") exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk7") exclude("org.jetbrains.kotlin", "kotlin-stdlib") exclude("org.jetbrains.kotlin", "kotlin-stdlib-common") - exclude("org.jetbrains.kotlin", "kotlin-script-runtime") - exclude("org.jetbrains.kotlin", "kotlin-reflect") } testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") From 682ce026e146e688e2a97fa5c6d544b105fbf6fc Mon Sep 17 00:00:00 2001 From: kentr0w Date: Fri, 30 Apr 2021 14:28:42 +0300 Subject: [PATCH 13/14] Warnings ### What's done: Rollback md files --- info/guide/diktat-coding-convention.md | 6 +++--- info/guide/guide-chapter-1.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/info/guide/diktat-coding-convention.md b/info/guide/diktat-coding-convention.md index 463b2bad37..59434cd19c 100644 --- a/info/guide/diktat-coding-convention.md +++ b/info/guide/diktat-coding-convention.md @@ -618,7 +618,7 @@ Chinese version: `版权所有 (c) 华为技术有限公司 2012-2020` \ English version: `Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved.` `2012` and `2020` are the years the file was first created and the current year, respectively. -Do not place **release notes** in header, use VCS to keep track of changes in a file. Notable changes can be marked in individual KDocs using `@since` tag with version. +Do not place **release notes** in header, use VCS to keep track of changes in file. Notable changes can be marked in individual KDocs using `@since` tag with version. Invalid example: ```kotlin @@ -2254,7 +2254,7 @@ class YourClass(var name: String) { } ``` -The `init` block was not added to Kotlin to help you initialize your properties; it is needed for more complex tasks. +The `init` block was not added to Kotlin to help you initialize your properties; it is needed for more complex tasks. Therefore if the `init` block contains only assignments of variables - move it directly to properties to be correctly initialized near the declaration. In some cases, this rule can be in clash with [6.1.1](#r6.1.1), but that should not stop you. @@ -2357,7 +2357,7 @@ class A { From the callee code, these methods look like access to this property: `A().isEmpty = true` for setter and `A().isEmpty` for getter. -However, when `get` and `set` are overridden, it isn't very clear for a developer who uses this particular class. +However, when `get` and `set` are overridden, it isn't very clear for a developer who uses this particular class. The developer expects to get the property value but receives some unknown value and some extra side-effect hidden by the custom getter/setter. Use extra functions instead to avoid confusion. diff --git a/info/guide/guide-chapter-1.md b/info/guide/guide-chapter-1.md index 407478ed9a..b8f6cc5262 100644 --- a/info/guide/guide-chapter-1.md +++ b/info/guide/guide-chapter-1.md @@ -188,7 +188,7 @@ val String sL = "Launcher"; **Valid example**: ```kotlin -const val Int MAX_USER_NUM = 200; +const val int MAX_USER_NUM = 200; const val String APPLICATION_NAME = "Launcher"; ``` From 8ce3cc89901f0db16a49883ba2e96e9fdf1b77db Mon Sep 17 00:00:00 2001 From: kentr0w Date: Fri, 30 Apr 2021 16:58:51 +0300 Subject: [PATCH 14/14] Warnings ### What's done: Added flag in parent pom --- diktat-common/pom.xml | 3 --- diktat-maven-plugin/pom.xml | 4 ---- diktat-rules/pom.xml | 2 -- diktat-test-framework/pom.xml | 3 --- pom.xml | 2 ++ 5 files changed, 2 insertions(+), 12 deletions(-) diff --git a/diktat-common/pom.xml b/diktat-common/pom.xml index 35936fedd9..c13c5f7868 100644 --- a/diktat-common/pom.xml +++ b/diktat-common/pom.xml @@ -81,9 +81,6 @@ - - -Werror - kotlinx-serialization diff --git a/diktat-maven-plugin/pom.xml b/diktat-maven-plugin/pom.xml index b85060c0e9..5778ae1f52 100644 --- a/diktat-maven-plugin/pom.xml +++ b/diktat-maven-plugin/pom.xml @@ -106,10 +106,6 @@ src/test/kotlin - - -Werror - -Xopt-in=kotlin.RequiresOptIn - diff --git a/diktat-rules/pom.xml b/diktat-rules/pom.xml index 8cd91928c5..7546beb87e 100644 --- a/diktat-rules/pom.xml +++ b/diktat-rules/pom.xml @@ -121,9 +121,7 @@ - -Werror -Xinline-classes - -Xopt-in=kotlin.RequiresOptIn diff --git a/diktat-test-framework/pom.xml b/diktat-test-framework/pom.xml index c848d7d214..763dd44987 100644 --- a/diktat-test-framework/pom.xml +++ b/diktat-test-framework/pom.xml @@ -69,9 +69,6 @@ compile - - -Werror - src/main/java src/main/kotlin diff --git a/pom.xml b/pom.xml index 567873d19e..37674ba1bc 100644 --- a/pom.xml +++ b/pom.xml @@ -225,6 +225,8 @@ -Xuse-ir + -Werror + -Xopt-in=kotlin.RequiresOptIn true