Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes in code style, update documentation #930

Merged
merged 5 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ typealias ListOfPairs = MutableList<Pair<ASTNode, String>>
/**
* This class represent individual inspections of diktat code style.
* A [Warnings] entry contains rule name, warning message and is used in code check.
* @property canBeAutoCorrected whether this inspection can automatically fix the code
* @property canBeAutoCorrected whether this inspection can automatically fix the code. Should be public to be able to use it in docs generator.
* @property ruleId number of the inspection according to []diktat code style](https://www.cqfn.org/diKTat/info/guide/diktat-coding-convention.html)
*/
@Suppress(
Expand All @@ -28,7 +28,7 @@ typealias ListOfPairs = MutableList<Pair<ASTNode, String>>
"WRONG_NEWLINES"
)
enum class Warnings(
private val canBeAutoCorrected: Boolean,
@Suppress("PRIVATE_MEMBER") val canBeAutoCorrected: Boolean,
val ruleId: String,
private val warn: String) : Rule {
// ======== dummy test warning ======
Expand Down
19 changes: 19 additions & 0 deletions info/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,51 @@ import org.cqfn.diktat.generation.docs.generateFullDoc
import org.cqfn.diktat.generation.docs.generateRulesMapping

tasks.register("generateRulesMapping") {
group = "documentation"
description = "Generates a table (rules-mapping.md), which maps warning names to chapters in code style"
doFirst {
generateRulesMapping()
}
}

tasks.register("generateFullDoc") {
group = "documentation"
description = "Compile individual chapters into a single markdown document"
doFirst {
generateFullDoc(file("$rootDir/guide"), "diktat-coding-convention.md")
}
}

tasks.register("generateAvailableRules") {
group = "documentation"
description = "Generate table for White paper based on available-rules.md and rules-mapping.md"
dependsOn("generateRulesMapping")
doFirst {
generateAvailableRules(rootDir, file("$rootDir/../wp"))
}
}

tasks.register("generateCodeStyle") {
group = "documentation"
description = "Adds/updates diktat code style in white paper document"
dependsOn("generateFullDoc")
doFirst {
generateCodeStyle(file("$rootDir/guide"), file("$rootDir/../wp"))
}
}

tasks.register("updateMarkdownDocumentation") {
group = "documentation"
description = "Task that aggregates all documentation updates without white paper updates"
dependsOn(
"generateRulesMapping",
"generateFullDoc"
)
}

tasks.register("updateDocumentation") {
group = "documentation"
description = "Task that aggregates all documentation updates"
dependsOn(
"generateRulesMapping",
"generateAvailableRules",
Expand Down
7 changes: 6 additions & 1 deletion info/buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ plugins {
}

repositories {
mavenLocal()
mavenCentral()
mavenLocal {
content {
includeGroup("org.cqfn.diktat")
}
}
flatDir {
dirs(
"$rootDir/../../diktat-rules/target",
Expand Down
2 changes: 1 addition & 1 deletion info/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
112 changes: 106 additions & 6 deletions info/guide/diktat-coding-convention.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ I [Preface](#c0)
* [3.15 Strings](#c3.15)
* [3.15.1 Concatenation of Strings](#r3.15.1)
* [3.15.2 String template format](#r3.15.2)
* [3.16 Conditional statements](#c3.16)
* [3.16.1 Collapsing redundant nested if-statements](#r3.16.1)
* [3.16.2 Too complex conditions](#r3.16.2)

[4. Variables and types](#c4)
* [4.1 Variables](#c4.1)
Expand Down Expand Up @@ -114,7 +117,9 @@ I [Preface](#c0)
* [6.3 Interfaces](#c6.3)
* [6.4 Objects](#c6.4)
* [6.4.1 Instead of using utility classes/objects, use extensions](#r6.4.1)
* [6.4.2 Objects should be used for Stateless Interfaces](#r6.4.2)
* [6.4.2 Objects should be used for Stateless Interfaces](#r6.4.2)
* [6.5 Kts Files](#c6.5)
* [6.5.1 kts files should wrap logic into top-level scope](#r6.5.1)


# Diktat Coding Style Guide
Expand Down Expand Up @@ -228,6 +233,7 @@ The only exception is function names in `Unit tests.`
@Test fun `my test`() { /*...*/ }
```
6. The following table contains some characters that may cause confusion. Be careful when using them as identifiers. To avoid issues, use other names instead.

| Expected | Confusing name | Suggested name |
| ------------- | ------------------------ | ---------------- |
| 0 (zero) | O, D | obj, dgt |
Expand Down Expand Up @@ -857,13 +863,14 @@ If the classes are meant to be used externally, and are not referenced inside th
- Companion object

**Exception:**
All variants of a `(private) val` logger should be placed at the beginning of the class (`(private) val log`, `LOG`, `logger`, etc.).
All variants of a `private val` logger should be placed at the beginning of the class (`private val log`, `LOG`, `logger`, etc.).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you generated it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, why?


#### <a name="r3.1.5"></a> 3.1.5 Order of declaration of top-level code structures
Kotlin allows several top-level declaration types: classes, objects, interfaces, properties and functions.
When declaring more than one class or zero classes (e.g. only functions), as per rule [2.2.1](#r2.2.1), you should document the whole file in the header KDoc.
When declaring top-level structures, keep the following order:
1. Top-level constants and properties (following same order as properties inside a class: `const val`,`val`, `lateinit var`, `var`)
2. typealiases (grouped by their visibility modifiers)
2. Interfaces, classes and objects (grouped by their visibility modifiers)
3. Extension functions
4. Other functions
Expand All @@ -879,6 +886,8 @@ const val CONSTANT = 42

val topLevelProperty = "String constant"

internal typealias ExamplesHandler = (IExample) -> Unit

interface IExample

class Example : IExample
Expand Down Expand Up @@ -1086,7 +1095,7 @@ class A
Avoid empty blocks, and ensure braces start on a new line. An empty code block can be closed immediately on the same line and the next line. However, a newline is recommended between opening and closing braces `{}` (see the examples below.)

Generally, empty code blocks are prohibited; using them is considered a bad practice (especially for catch block).
They are only appropriate for overridden functions when the base class's functionality is not needed in the class-inheritor.
They are appropriate for overridden functions, when the base class's functionality is not needed in the class-inheritor, for lambdas used as a function and for empty function in implementation of functional interface.
```kotlin
override fun foo() {
}
Expand All @@ -1099,6 +1108,8 @@ fun doNothing() {}

fun doNothingElse() {
}

fun foo(bar: () -> Unit = {})
```

**Invalid examples:**
Expand Down Expand Up @@ -1598,6 +1609,24 @@ val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
```
#### <a name="r3.14.3"></a> 3.14.3: Magic number
Prefer defining constants with clear names describing what the magic number means.
**Valid example**:
```kotlin
class Person() {
fun isAdult(age: Int): Boolean = age >= majority

companion object {
private const val majority = 18
}
}
```
**Invalid example**:
```kotlin
class Person() {
fun isAdult(age: Int): Boolean = age >= 18
}
```

<!-- =============================================================================== -->
### <a name="c3.15"></a> 3.15 Strings
Expand Down Expand Up @@ -1647,6 +1676,75 @@ val someString = "$myArgument"
```kotlin
val someString = myArgument
```

<!-- =============================================================================== -->
### <a name="c3.16"></a> 3.16 Conditional Statements
This section describes the general rules related to the сonditional statements.

#### <a name="r3.16.1"></a> 3.16.1 Collapsing redundant nested if-statements
The nested if-statements, when possible, should be collapsed into a single one
by concatenating their conditions with the infix operator &&.

This improves the readability by reducing the number of the nested language constructs.

#### Simple collapse

**Invalid example**:
```kotlin
if (cond1) {
if (cond2) {
doSomething()
}
}
```

**Valid example**:
```kotlin
if (cond1 && cond2) {
doSomething()
}
```

#### Compound conditions

**Invalid example**:
```kotlin
if (cond1) {
if (cond2 || cond3) {
doSomething()
}
}
```

**Valid example**:
```kotlin
if (cond1 && (cond2 || cond3)) {
doSomething()
}
```
#### <a name="r3.16.2"></a> 3.16.2 Too complex conditions
Too complex conditions should be simplified according to boolean algebra rules, if it is possible.
The following rules are considered when simplifying an expression:
* boolean literals are removed (e.g. `foo() || false` -> `foo()`)
* double negation is removed (e.g. `!(!a)` -> `a`)
* expression with the same variable are simplified (e.g. `a && b && a` -> `a && b`)
* remove expression from disjunction, if they are subset of other expression (e.g. `a || (a && b)` -> `a`)
* remove expression from conjunction, if they are more broad than other expression (e.g. `a && (a || b)` -> `a`)
* de Morgan's rule (negation is moved inside parentheses, i.e. `!(a || b)` -> `!a && !b`)

**Valid example**
```kotlin
if (condition1 && condition2) {
foo()
}
```

**Invalid example**
```kotlin
if (condition1 && condition2 && condition1) {
foo()
}
```
# <a name="c4"></a> 4. Variables and types
This section is dedicated to the rules and recommendations for using variables and types in your code.
<!-- =============================================================================== -->
Expand Down Expand Up @@ -2496,8 +2594,9 @@ It is recommended that for classes, the non-tightly coupled functions, which are
They should be implemented in the same class/file where they are used. This is a non-deterministic rule, so the code cannot be checked or fixed automatically by a static analyzer.

#### <a name="r6.2.2"></a> 6.2.2 No extension functions with the same name and signature if they extend base and inheritor classes (possible_bug)
You should have ho extension functions with the same name and signature if they extend base and inheritor classes (possible_bug).esolved statically. There could be a situation when a developer implements two extension functions: one is for the base class and another for the inheritor.
This can lead to an issue when an incorrect method is used.
You should avoid declaring extension functions with the same name and signature if their receivers are base and inheritor classes (possible_bug),
as extension functions are resolved statically. There could be a situation when a developer implements two extension functions: one is for the base class and
another for the inheritor. This can lead to an issue when an incorrect method is used.

**Invalid example**:
```kotlin
Expand Down Expand Up @@ -2577,7 +2676,8 @@ object O: I {
override fun foo() {}
}
```

### <a name="c6.5"></a> 6.5 Kts Files
This section describes general rules for `.kts` files
#### <a name="r6.5.1"></a> 6.5.1 kts files should wrap logic into top-level scope
It is still recommended wrapping logic inside functions and avoid using top-level statements for function calls or wrapping blocks of code
in top-level scope functions like `run`.
Expand Down
13 changes: 10 additions & 3 deletions info/guide/guide-chapter-3.md
Original file line number Diff line number Diff line change
Expand Up @@ -936,18 +936,25 @@ if (cond1 && (cond2 || cond3)) {
}
```
#### <a name="r3.16.2"></a> 3.16.2 Too complex conditions
Too complex conditions should be simplified according to boolean algebra rules, if it is possible
Too complex conditions should be simplified according to boolean algebra rules, if it is possible.
The following rules are considered when simplifying an expression:
* boolean literals are removed (e.g. `foo() || false` -> `foo()`)
* double negation is removed (e.g. `!(!a)` -> `a`)
* expression with the same variable are simplified (e.g. `a && b && a` -> `a && b`)
* remove expression from disjunction, if they are subset of other expression (e.g. `a || (a && b)` -> `a`)
* remove expression from conjunction, if they are more broad than other expression (e.g. `a && (a || b)` -> `a`)
* de Morgan's rule (negation is moved inside parentheses, i.e. `!(a || b)` -> `!a && !b`)

**Valid example**
```kotlin
if (cond1 && cond2) {
if (condition1 && condition2) {
foo()
}
```

**Invalid example**
```kotlin
if (cond1 && cond2 && cond1) {
if (condition1 && condition2 && condition1) {
foo()
}
```
5 changes: 3 additions & 2 deletions info/guide/guide-chapter-6.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,9 @@ It is recommended that for classes, the non-tightly coupled functions, which are
They should be implemented in the same class/file where they are used. This is a non-deterministic rule, so the code cannot be checked or fixed automatically by a static analyzer.

#### <a name="r6.2.2"></a> 6.2.2 No extension functions with the same name and signature if they extend base and inheritor classes (possible_bug)
You should have ho extension functions with the same name and signature if they extend base and inheritor classes (possible_bug).esolved statically. There could be a situation when a developer implements two extension functions: one is for the base class and another for the inheritor.
This can lead to an issue when an incorrect method is used.
You should avoid declaring extension functions with the same name and signature if their receivers are base and inheritor classes (possible_bug),
as extension functions are resolved statically. There could be a situation when a developer implements two extension functions: one is for the base class and
another for the inheritor. This can lead to an issue when an incorrect method is used.

**Invalid example**:
```kotlin
Expand Down
14 changes: 12 additions & 2 deletions info/rules-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,12 @@
| FILE_NO_BLANK_LINE_BETWEEN_BLOCKS | [3.1.2](guide/diktat-coding-convention.md#r3.1.2) | yes | General |
| FILE_UNORDERED_IMPORTS | [3.1.2](guide/diktat-coding-convention.md#r3.1.2) | yes | General |
| FILE_WILDCARD_IMPORTS | [3.1.2](guide/diktat-coding-convention.md#r3.1.2) | no | General |
| UNUSED_IMPORT | [3.1.2](guide/diktat-coding-convention.md#r3.1.2) | yes | General |
| FILE_NAME_MATCH_CLASS | [3.1.2](guide/diktat-coding-convention.md#r3.1.2) | yes | General |
| WRONG_ORDER_IN_CLASS_LIKE_STRUCTURES | [3.1.4](guide/diktat-coding-convention.md#r3.1.4) | yes | General |
| BLANK_LINE_BETWEEN_PROPERTIES | [3.1.4](guide/diktat-coding-convention.md#r3.1.4) | yes | General |
| WRONG_DECLARATIONS_ORDER | [3.1.4](guide/diktat-coding-convention.md#r3.1.4) | yes | General |
| TOP_LEVEL_ORDER | [3.1.5](guide/diktat-coding-convention.md#r3.1.5) | yes | General |
| NO_BRACES_IN_CONDITIONALS_AND_LOOPS | [3.2.1](guide/diktat-coding-convention.md#r3.2.1) | yes | General |
| BRACES_BLOCK_STRUCTURE_ERROR | [3.2.2](guide/diktat-coding-convention.md#r3.2.2) | yes | General |
| WRONG_INDENTATION | [3.3.1](guide/diktat-coding-convention.md#r3.3.1) | yes | General |
Expand All @@ -69,7 +71,9 @@
| MORE_THAN_ONE_STATEMENT_PER_LINE | [3.6.1](guide/diktat-coding-convention.md#r3.6.1) | yes | General |
| REDUNDANT_SEMICOLON | [3.6.2](guide/diktat-coding-convention.md#r3.6.2) | yes | General |
| WRONG_NEWLINES | [3.6.2](guide/diktat-coding-convention.md#r3.6.2) | yes | General |
| TRAILING_COMMA | [3.6.2](guide/diktat-coding-convention.md#r3.6.2) | yes | General |
| COMPLEX_EXPRESSION | [3.6.3](guide/diktat-coding-convention.md#r3.6.3) | no | General |
| COMPLEX_BOOLEAN_EXPRESSION | [3.6.4](guide/diktat-coding-convention.md#r3.6.4) | yes | General |
| TOO_MANY_BLANK_LINES | [3.7.1](guide/diktat-coding-convention.md#r3.7.1) | yes | General |
| WRONG_WHITESPACE | [3.8.1](guide/diktat-coding-convention.md#r3.8.1) | yes | General |
| TOO_MANY_CONSECUTIVE_SPACES | [3.8.1](guide/diktat-coding-convention.md#r3.8.1) | yes | General |
Expand All @@ -79,9 +83,11 @@
| ANNOTATION_NEW_LINE | [3.12.1](guide/diktat-coding-convention.md#r3.12.1) | yes | General |
| WRONG_MULTIPLE_MODIFIERS_ORDER | [3.14.1](guide/diktat-coding-convention.md#r3.14.1) | yes | General |
| LONG_NUMERICAL_VALUES_SEPARATED | [3.14.2](guide/diktat-coding-convention.md#r3.14.2) | yes | General |
| STRING_CONCATENATION | [3.15.1](guide/diktat-coding-convention.md#r3.15.1) | no | General |
| MAGIC_NUMBER | [3.14.3](guide/diktat-coding-convention.md#r3.14.3) | no | General |
| STRING_CONCATENATION | [3.15.1](guide/diktat-coding-convention.md#r3.15.1) | yes | General |
| STRING_TEMPLATE_CURLY_BRACES | [3.15.2](guide/diktat-coding-convention.md#r3.15.2) | yes | General |
| STRING_TEMPLATE_QUOTES | [3.15.2](guide/diktat-coding-convention.md#r3.15.2) | yes | General |
| COLLAPSE_IF_STATEMENTS | [3.16.1](guide/diktat-coding-convention.md#r3.16.1) | yes | General |
| FLOAT_IN_ACCURATE_CALCULATIONS | [4.1.1](guide/diktat-coding-convention.md#r4.1.1) | no | Variables |
| SAY_NO_TO_VAR | [4.1.3](guide/diktat-coding-convention.md#r4.1.3) | no | Variables |
| SMART_CAST_NEEDED | [4.2.1](guide/diktat-coding-convention.md#r4.2.1) | yes | Variables |
Expand All @@ -98,6 +104,7 @@
| WRONG_OVERLOADING_FUNCTION_ARGUMENTS | [5.2.3](guide/diktat-coding-convention.md#r5.2.3) | no | Functions |
| RUN_BLOCKING_INSIDE_ASYNC | [5.2.4](guide/diktat-coding-convention.md#r5.2.4) | no | Functions |
| TOO_MANY_LINES_IN_LAMBDA | [5.2.5](guide/diktat-coding-convention.md#r5.2.5) | no | Functions |
| CUSTOM_LABEL | [5.2.6](guide/diktat-coding-convention.md#r5.2.6) | no | Functions |
| SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY | [6.1.1](guide/diktat-coding-convention.md#r6.1.1) | yes | Classes |
| USE_DATA_CLASS | [6.1.2](guide/diktat-coding-convention.md#r6.1.2) | no | Classes |
| EMPTY_PRIMARY_CONSTRUCTOR | [6.1.3](guide/diktat-coding-convention.md#r6.1.3) | yes | Classes |
Expand All @@ -109,6 +116,9 @@
| WRONG_NAME_OF_VARIABLE_INSIDE_ACCESSOR | [6.1.9](guide/diktat-coding-convention.md#r6.1.9) | no | Classes |
| TRIVIAL_ACCESSORS_ARE_NOT_RECOMMENDED | [6.1.10](guide/diktat-coding-convention.md#r6.1.10) | yes | Classes |
| COMPACT_OBJECT_INITIALIZATION | [6.1.11](guide/diktat-coding-convention.md#r6.1.11) | yes | Classes |
| INLINE_CLASS_CAN_BE_USED | [6.1.12](guide/diktat-coding-convention.md#r6.1.12) | yes | Classes |
| EXTENSION_FUNCTION_SAME_SIGNATURE | [6.2.2](guide/diktat-coding-convention.md#r6.2.2) | no | Classes |
| EXTENSION_FUNCTION_WITH_CLASS | [6.2.3](guide/diktat-coding-convention.md#r6.2.3) | no | Classes |
| AVOID_USING_UTILITY_CLASS | [6.4.1](guide/diktat-coding-convention.md#r6.4.1) | no | Classes |
| OBJECT_IS_PREFERRED | [6.4.2](guide/diktat-coding-convention.md#r6.4.2) | yes | Classes |
| OBJECT_IS_PREFERRED | [6.4.2](guide/diktat-coding-convention.md#r6.4.2) | yes | Classes |
| RUN_IN_SCRIPT | [6.5.1](guide/diktat-coding-convention.md#r6.5.1) | yes | Classes |