Skip to content

Commit

Permalink
Merge branch 'master' into feature/no-domain-name
Browse files Browse the repository at this point in the history
  • Loading branch information
kentr0w authored Jan 19, 2021
2 parents 9eadc6b + 0b61701 commit ac2db15
Show file tree
Hide file tree
Showing 90 changed files with 2,145 additions and 756 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ jobs:
key: ${{ runner.os }}-maven-build-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-build-
- name: Maven Package
run: mvn -B clean package -DskipTests
- name: Maven Install
run: mvn -B install
run: mvn -B clean install
- name: Code coverage report
uses: codecov/codecov-action@v1
with:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ jobs:
sed -i "s/$PREVIOUS_VERSION/$RELEASE_VERSION/g" $file || echo "File $file hasn't been updated!"
cp diktat-rules/src/main/resources/diktat-analysis.yml $(dirname $file)
done
next_snapshot_version=$(printf 'VERSION=${project.version}\n0\n' | mvn help:evaluate | grep '^VERSION' | cut -d= -f2)
echo "version=$next_snapshot_version" > info/buildSrc/gradle.properties
- name: Create pull request
uses: peter-evans/create-pull-request@v3
with:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ Now diKTat was already added to the lists of [static analysis tools](https://git

## See first

| | | | |
| --- | --- | --- | --- |
|[DiKTat codestyle](info/guide/diktat-coding-convention.md)|[Supported Rules](info/available-rules.md) | [Examples of Usage](https://github.com/akuleshov7/diktat-examples) | [Online Demo](https://ktlint-demo.herokuapp.com) |
| | | | | |
| --- | --- | --- | --- | --- |
|[DiKTat codestyle](info/guide/diktat-coding-convention.md)|[Supported Rules](info/available-rules.md) | [Examples of Usage](https://github.com/akuleshov7/diktat-examples) | [Online Demo](https://ktlint-demo.herokuapp.com) | [White Paper](wp/wp.pdf) |

## Why should I use diktat in my CI/CD?

Expand Down
22 changes: 19 additions & 3 deletions diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
# Checks that KDoc does not contain single line with words 'return', 'get' or 'set'
- name: KDOC_TRIVIAL_KDOC_ON_FUNCTION
enabled: true
# Checks that kdoc does not contain @author tag or date
- name: KDOC_CONTAINS_DATE_OR_AUTHOR
enabled: true
configuration:
versionRegex: \d+\.\d+\.\d+[-.\w\d]*
# Checks that there is newline after header KDoc
- name: HEADER_WRONG_FORMAT
enabled: true
Expand All @@ -130,9 +135,6 @@
# Checks that header kdoc is located before package directive
- name: HEADER_NOT_BEFORE_PACKAGE
enabled: true
# Checks that header kdoc does not contain @author tag ar date
- name: HEADER_CONTAINS_DATE_OR_AUTHOR
enabled: true
# Checks that file does not contain lines > maxSize
- name: FILE_IS_TOO_LONG
enabled: true
Expand Down Expand Up @@ -222,6 +224,9 @@
maxParametersInOneLine: 2
# 3 by default.
# maxCallsInOneLine: 3
# Inspection that checks if a long dot qualified expression is used in condition or as an argument
- name: COMPLEX_EXPRESSION
enabled: true
# Checks that there are not too many consecutive spaces in line
- name: TOO_MANY_CONSECUTIVE_SPACES
enabled: true
Expand Down Expand Up @@ -348,6 +353,14 @@
# Checks that function use default values, instead overloading
- name: WRONG_OVERLOADING_FUNCTION_ARGUMENTS
enabled: true
# Checks that using runBlocking inside async block code
- name: RUN_BLOCKING_INSIDE_ASYNC
enabled: true
# Checks that the long lambda has parameters
- name: TOO_MANY_LINES_IN_LAMBDA
enabled: true
configuration:
maxLambdaLength: 10 # max length of lambda without parameters
# Checks that property in constructor doesn't contains comment
- name: KDOC_NO_CONSTRUCTOR_PROPERTY
enabled: true
Expand Down Expand Up @@ -411,4 +424,7 @@
enabled: true
# If there is stateless class it is preferred to use object
- name: OBJECT_IS_PREFERRED
enabled: true
# If there exists negated version of function you should prefer it instead of !functionCall
- name: INVERSE_FUNCTION_PREFERRED
enabled: true
3 changes: 2 additions & 1 deletion diktat-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ repositories {

// default value is needed for correct gradle loading in IDEA; actual value from maven is used during build
val ktlintVersion = project.properties.getOrDefault("ktlintVersion", "0.39.0") as String
val diktatVersion = project.version.takeIf { it.toString() != Project.DEFAULT_VERSION } ?: "0.2.0"
val diktatVersion = project.version.takeIf { it.toString() != Project.DEFAULT_VERSION } ?: "0.3.0"
val junitVersion = project.properties.getOrDefault("junitVersion", "5.7.0") as String
val jacocoVersion = project.properties.getOrDefault("jacocoVersion", "0.8.6") as String
dependencies {
Expand Down Expand Up @@ -98,6 +98,7 @@ tasks.getByName<Test>("functionalTest") {
dependsOn("test")
testClassesDirs = functionalTest.output.classesDirs
classpath = functionalTest.runtimeClasspath
maxParallelForks = Runtime.getRuntime().availableProcessors()
doLast {
if (getCurrentOperatingSystem().isWindows) {
// workaround for https://github.com/koral--/jacoco-gradle-testkit-plugin/issues/9
Expand Down
1 change: 1 addition & 0 deletions diktat-rules/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
</goals>
<configuration>
<sourceDirs>
<!-- For some weird reason if main sourceset is removed from here, syntax highlighting in idea an ability to launch tests is broken -->
<source>src/main/kotlin</source>
<source>src/test/kotlin</source>
<source>${project.basedir}/src/main/kotlin</source>
Expand Down
12 changes: 10 additions & 2 deletions diktat-rules/src/main/kotlin/generated/WarningNames.kt
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ public object WarningNames {
public const val KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT: String =
"KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT"

public const val KDOC_CONTAINS_DATE_OR_AUTHOR: String = "KDOC_CONTAINS_DATE_OR_AUTHOR"

public const val HEADER_WRONG_FORMAT: String = "HEADER_WRONG_FORMAT"

public const val HEADER_MISSING_OR_WRONG_COPYRIGHT: String = "HEADER_MISSING_OR_WRONG_COPYRIGHT"

public const val WRONG_COPYRIGHT_YEAR: String = "WRONG_COPYRIGHT_YEAR"

public const val HEADER_CONTAINS_DATE_OR_AUTHOR: String = "HEADER_CONTAINS_DATE_OR_AUTHOR"

public const val HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE: String =
"HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE"

Expand Down Expand Up @@ -143,6 +143,8 @@ public object WarningNames {

public const val WRONG_NEWLINES: String = "WRONG_NEWLINES"

public const val COMPLEX_EXPRESSION: String = "COMPLEX_EXPRESSION"

public const val STRING_CONCATENATION: String = "STRING_CONCATENATION"

public const val TOO_MANY_BLANK_LINES: String = "TOO_MANY_BLANK_LINES"
Expand Down Expand Up @@ -199,6 +201,8 @@ public object WarningNames {
public const val WRONG_OVERLOADING_FUNCTION_ARGUMENTS: String =
"WRONG_OVERLOADING_FUNCTION_ARGUMENTS"

public const val RUN_BLOCKING_INSIDE_ASYNC: String = "RUN_BLOCKING_INSIDE_ASYNC"

public const val SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY: String =
"SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY"

Expand Down Expand Up @@ -229,4 +233,8 @@ public object WarningNames {
public const val AVOID_USING_UTILITY_CLASS: String = "AVOID_USING_UTILITY_CLASS"

public const val OBJECT_IS_PREFERRED: String = "OBJECT_IS_PREFERRED"

public const val INVERSE_FUNCTION_PREFERRED: String = "INVERSE_FUNCTION_PREFERRED"

public const val TOO_MANY_LINES_IN_LAMBDA: String = "TOO_MANY_LINES_IN_LAMBDA"
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ enum class Warnings(
KDOC_NO_CONSTRUCTOR_PROPERTY(true, "2.1.1", "all properties from the primary constructor should be documented in a @property tag in KDoc"),
KDOC_EXTRA_PROPERTY(false, "2.1.1", "There is property in KDoc which is not present in the class"),
KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT(true, "2.1.1", "replace comment before property with @property tag in class KDoc"),
KDOC_CONTAINS_DATE_OR_AUTHOR(false, "2.1.3", "KDoc should not contain creation date and author name"),
HEADER_WRONG_FORMAT(true, "2.2.1", "file header comments should be properly formatted"),
HEADER_MISSING_OR_WRONG_COPYRIGHT(true, "2.2.1", "file header comment must include copyright information inside a block comment"),
WRONG_COPYRIGHT_YEAR(true, "2.2.1", "year defined in copyright and current year are different"),
HEADER_CONTAINS_DATE_OR_AUTHOR(false, "2.2.1", "file header comment should not contain creation date and author name"),
HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE(false, "2.2.1", "files that contain multiple or no classes should contain description of what is inside of this file"),
HEADER_NOT_BEFORE_PACKAGE(true, "2.2.1", "header KDoc should be placed before package and imports"),
COMMENTED_OUT_CODE(false, "2.4.2", "you should not comment out code, use VCS to save it in history and delete this block"),
Expand All @@ -96,6 +96,7 @@ enum class Warnings(
LONG_LINE(true, "3.5.1", "this line is longer than allowed"),
REDUNDANT_SEMICOLON(true, "3.6.2", "there should be no redundant semicolon at the end of lines"),
WRONG_NEWLINES(true, "3.6.2", "incorrect line breaking"),
COMPLEX_EXPRESSION(false, "3.6.3", "complex dot qualified expression should be replaced with variable"),

// FixMe: autofixing will be added for this rule
STRING_CONCATENATION(false, "3.15.1", "strings should not be concatenated using plus operator - use string templates instead if the statement fits one line"),
Expand Down Expand Up @@ -131,6 +132,8 @@ enum class Warnings(
TOO_MANY_PARAMETERS(false, "5.2.2", "function has too many parameters"),
NESTED_BLOCK(false, "5.1.2", "function has too many nested blocks and should be simplified"),
WRONG_OVERLOADING_FUNCTION_ARGUMENTS(false, "5.2.3", "use default argument instead of function overloading"),
RUN_BLOCKING_INSIDE_ASYNC(false, "5.2.4", "avoid using runBlocking in asynchronous code"),
TOO_MANY_LINES_IN_LAMBDA(false, "5.2.5", "long lambdas should have a parameter name instead of it"),

// ======== chapter 6 ========
SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY(true, "6.1.1", "if a class has single constructor, it should be converted to a primary constructor"),
Expand All @@ -147,6 +150,7 @@ enum class Warnings(
NO_CORRESPONDING_PROPERTY(false, "6.1.7", "backing property should have the same name, but there is no corresponding property"),
AVOID_USING_UTILITY_CLASS(false, "6.4.1", "avoid using utility classes/objects, use extensions functions"),
OBJECT_IS_PREFERRED(true, "6.4.2", "it is better to use object for stateless classes"),
INVERSE_FUNCTION_PREFERRED(true, "5.1.4", "it is better to use inverse function"),
;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,28 @@ private fun generateWarningNames() {
}

private fun validateYear() {
val file = File("diktat-rules/src/test/resources/test/paragraph2/header/CopyrightDifferentYearExpected.kt")
val tempFile = createTempFile()
tempFile.printWriter().use { writer ->
file.forEachLine { line ->
writer.println(when {
hyphenRegex.matches(line) -> hyphenRegex.replace(line) {
val years = it.value.split("-")
val validYears = "${years[0]}-$curYear"
line.replace(hyphenRegex, validYears)
val files = File("diktat-rules/src/test/resources/test/paragraph2/header")
files
.listFiles()
.filterNot { it.name.contains("CopyrightDifferentYearTest.kt") }
.forEach { file ->
val tempFile = createTempFile()
tempFile.printWriter().use { writer ->
file.forEachLine { line ->
writer.println(when {
line.contains(hyphenRegex) -> line.replace(hyphenRegex) {
val years = it.value.split("-")
"${years[0]}-$curYear"
}
line.contains(afterCopyrightRegex) -> line.replace(afterCopyrightRegex) {
val copyrightYears = it.value.split("(c)", "(C)", "©")
"${copyrightYears[0]}-$curYear"
}
else -> line
})
}
afterCopyrightRegex.matches(line) -> afterCopyrightRegex.replace(line) {
val copyrightYears = it.value.split("(c)", "(C)", "©")
val validYears = "${copyrightYears[0]}-$curYear"
line.replace(afterCopyrightRegex, validYears)
}
else -> line
})
}
file.delete()
tempFile.renameTo(file)
}
}
file.delete()
tempFile.renameTo(file)
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ class AnnotationNewLineRule(private val configRules: List<RulesConfig>) : Rule("
if (node == node.treeParent.getFirstChildWithType(node.elementType)) {
// Current node is ANNOTATION_ENTRY. treeParent(ModifierList) -> treeParent(PRIMARY_CONSTRUCTOR)
// Checks if there is a white space before grandparent node
if (node.treeParent.treeParent.treePrev.isWhiteSpace()) {
val hasSpaceBeforeGrandparent = node
.treeParent
.treeParent
.treePrev
.isWhiteSpace()
if (hasSpaceBeforeGrandparent) {
(node.treeParent.treeParent.treePrev as LeafPsiElement).replaceWithText("\n")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.cqfn.diktat.ruleset.rules

import org.cqfn.diktat.common.config.rules.RulesConfig
import org.cqfn.diktat.ruleset.constants.EmitType
import org.cqfn.diktat.ruleset.constants.Warnings.RUN_BLOCKING_INSIDE_ASYNC
import org.cqfn.diktat.ruleset.utils.hasChildOfType

import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.FUN
import com.pinterest.ktlint.core.ast.ElementType.LAMBDA_ARGUMENT
import com.pinterest.ktlint.core.ast.ElementType.REFERENCE_EXPRESSION
import com.pinterest.ktlint.core.ast.parent
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier

/**
* This rule finds if using runBlocking in asynchronous code
*/
class AsyncAndSyncRule(private val configRules: List<RulesConfig>) : Rule("sync-in-async") {
private val asyncList = listOf("async", "launch")
private var isFixMode: Boolean = false
private lateinit var emitWarn: EmitType

override fun visit(node: ASTNode,
autoCorrect: Boolean,
emit: EmitType) {
emitWarn = emit
isFixMode = autoCorrect

if (node.isRunBlocking()) {
checkRunBlocking(node)
}
}

private fun checkRunBlocking(node: ASTNode) {
node.parent({it.isAsync() || it.isSuspend()})?.let {
RUN_BLOCKING_INSIDE_ASYNC.warn(configRules, emitWarn, isFixMode, node.text, node.startOffset, node)
}
}

private fun ASTNode.isAsync() = this.elementType == CALL_EXPRESSION && this.findChildByType(REFERENCE_EXPRESSION)?.text in asyncList

private fun ASTNode.isSuspend() = this.elementType == FUN && (this.psi as KtFunction).modifierList?.hasSuspendModifier() ?: false

private fun ASTNode.isRunBlocking() = this.elementType == REFERENCE_EXPRESSION && this.text == "runBlocking" && this.treeParent.hasChildOfType(LAMBDA_ARGUMENT)
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,14 @@ class BlockStructureBraces(private val configRules: List<RulesConfig>) : Rule("b
allMiddleSpace: List<ASTNode>,
node: ASTNode,
keyword: IElementType) {
allMiddleSpace.forEach {
if (checkBraceNode(it, true)) {
allMiddleSpace.forEach { space ->
if (checkBraceNode(space, true)) {
BRACES_BLOCK_STRUCTURE_ERROR.warnAndFix(configRules, emitWarn, isFixMode, "incorrect new line after closing brace",
it.startOffset, it) {
if (it.elementType != WHITE_SPACE) {
space.startOffset, space) {
if (space.elementType != WHITE_SPACE) {
node.addChild(PsiWhiteSpaceImpl(" "), node.findChildByType(keyword))
} else {
(it as LeafPsiElement).replaceWithText(" ")
(space as LeafPsiElement).replaceWithText(" ")
}
}
}
Expand Down
Loading

0 comments on commit ac2db15

Please sign in to comment.