{"id":13611438,"url":"https://github.com/saveourtool/diktat","last_synced_at":"2025-09-27T23:31:30.205Z","repository":{"id":36965508,"uuid":"275879956","full_name":"saveourtool/diktat","owner":"saveourtool","description":"Strict coding standard for Kotlin and a custom set of rules for detecting code smells, code style issues and bugs","archived":false,"fork":false,"pushed_at":"2024-06-12T18:59:16.000Z","size":8892,"stargazers_count":515,"open_issues_count":144,"forks_count":37,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-06-16T14:33:52.508Z","etag":null,"topics":["android","awesome","awesome-kotlin","checkstyle","code-checker","code-fixer","codecheck","codestyle","hacktoberfest","kotlin","ktlint","linter","static-analysis"],"latest_commit_sha":null,"homepage":"https://diktat.saveourtool.com","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saveourtool.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-29T17:14:54.000Z","updated_at":"2024-06-19T19:39:41.835Z","dependencies_parsed_at":"2023-10-16T18:34:21.201Z","dependency_job_id":"da849024-8aa7-4998-ab9b-720b0c4ddeba","html_url":"https://github.com/saveourtool/diktat","commit_stats":null,"previous_names":["analysis-dev/diktat"],"tags_count":47,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saveourtool%2Fdiktat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saveourtool%2Fdiktat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saveourtool%2Fdiktat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saveourtool%2Fdiktat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saveourtool","download_url":"https://codeload.github.com/saveourtool/diktat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234470303,"owners_count":18838628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","awesome","awesome-kotlin","checkstyle","code-checker","code-fixer","codecheck","codestyle","hacktoberfest","kotlin","ktlint","linter","static-analysis"],"created_at":"2024-08-01T19:01:55.300Z","updated_at":"2025-09-27T23:31:22.625Z","avatar_url":"https://github.com/saveourtool.png","language":"Kotlin","funding_links":[],"categories":["Kotlin","android"],"sub_categories":[],"readme":"\u003cimg src=\"/logo.svg\" width=\"64px\"/\u003e\n\n![Build and test](https://github.com/saveourtool/diKTat/workflows/Build%20and%20test/badge.svg?branch=master)\n![deteKT static analysis](https://github.com/saveourtool/diKTat/workflows/Run%20deteKT/badge.svg)\n![diKTat code style](https://github.com/saveourtool/diKTat/workflows/Run%20diKTat%20%28release%29/badge.svg?branch=master)\n[![codecov](https://codecov.io/gh/saveourtool/diKTat/branch/master/graph/badge.svg)](https://codecov.io/gh/saveourtool/diKTat)\n\n[![Releases](https://img.shields.io/github/v/release/saveourtool/diKTat)](https://github.com/saveourtool/diKTat/releases)\n[![Maven Central](https://img.shields.io/maven-central/v/com.saveourtool.diktat/diktat-rules)](https://mvnrepository.com/artifact/com.saveourtool.diktat)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fsaveourtool%2Fdiktat.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fsaveourtool%2Fdiktat?ref=badge_shield)\n[![Chat on Telegram](https://img.shields.io/badge/Chat%20on-Telegram-brightgreen.svg)](https://t.me/diktat_support)\n\n[![Hits-of-Code](https://hitsofcode.com/github/saveourtool/diktat)](https://hitsofcode.com/view/github/saveourtool/diktat)\n![Lines of code](https://img.shields.io/tokei/lines/github/saveourtool/diktat)\n![GitHub repo size](https://img.shields.io/github/repo-size/saveourtool/diktat)\n[![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin)\n\n\n**DiKTat** is a strict [coding standard](info/guide/diktat-coding-convention.md) for Kotlin, consisting of a collection of [Kotlin](https://kotlinlang.org/) code style rules implemented as Abstract Syntax Tree (AST) visitors built on top of [KTlint](https://ktlint.github.io/). It serves the purpose of detecting and automatically fixing code smells in the Continuous Integration/Continuous Deployment (CI/CD) process. You can find the comprehensive list of supported rules and inspections [here](info/available-rules.md).\n\nDiKTat has gained recognition and has been added to the lists of [static analysis tools](https://github.com/analysis-tools-dev/static-analysis), [kotlin-awesome](https://github.com/KotlinBy/awesome-kotlin), and [kompar](https://catalog.kompar.tools/Analyzer/diKTat/1.2.5). We extend our gratitude to the community for this support!\n\n## See first\n\n|  |  |  |  |  |  |\n| --- | --- | --- | --- | --- | --- |\n|[Codestyle](info/guide/diktat-coding-convention.md)|[Inspections](info/available-rules.md) | [Examples](examples) | [Demo](https://saveourtool.com/#/demo/diktat) | [White Paper](wp/wp.pdf) | [Groups of Inspections](info/rules-mapping.md) |\n\n## Why Choose DiKTat for CI/CD?\n\nWhile there are other tools like `detekt` and `ktlint` performing static analysis, you might wonder why DiKTat is necessary. Here are the key reasons:\n\n1. **More Inspections:** DiKTat boasts over 100 inspections tightly coupled with its [Codestyle](info/guide/diktat-coding-convention.md).\n\n2. **Unique Inspections:** DiKTat introduces unique inspections not found in other linters.\n\n3. **Highly Configurable:** Every inspection is highly configurable, allowing customization and suppression. Check [configuration options](#config) and [suppression](#suppress).\n\n4. **Strict Codestyle:** DiKTat enforces a detailed [Codestyle](info/guide/diktat-coding-convention.md) that can be adopted and applied in your project.\n\n## Run as [CLI-application](diktat-cli/README.md)\n\n### Download binary\n\n1. Download diKTat manually: [here](https://github.com/saveourtool/diktat/releases)\n\n   **OR** use `curl`:\n   ```shell\n   curl -sSLO https://github.com/saveourtool/diktat/releases/download/v2.0.0/diktat \u0026\u0026 chmod a+x diktat\n   ```\n\n_**For Windows only**_. Download diKTat.cmd manually: [here](https://github.com/saveourtool/diktat/releases)\n\n### Run diKTat\n\nFinally, run KTlint (with diKTat injected) to check your '*.kt' files in 'dir/your/dir':\n\n```console\n$ ./diktat \"dir/your/dir/**/*.kt\"\n```\n\n\u003e _**On Windows**_\n\u003e ```console\n\u003e diktat.bat \"dir/your/dir/**/*.kt\"\n\u003e ```\n\nTo **autofix** all code style violations, use `--mode fix` option.\n\n## Run with Maven using diktat-maven-plugin\n\nYou can see how it is configured in our examples:\n- [Single project](examples/maven/pom.xml)\n- [Multi-module project](examples/maven-multiproject/pom.xml)\n\n\u003cdetails\u003e\n\u003csummary\u003eAdd this plugin to your pom.xml:\u003c/summary\u003e\n\n```xml\n            \u003cplugin\u003e\n                \u003cgroupId\u003ecom.saveourtool.diktat\u003c/groupId\u003e\n                \u003cartifactId\u003ediktat-maven-plugin\u003c/artifactId\u003e\n                \u003cversion\u003e${diktat.version}\u003c/version\u003e\n                \u003cexecutions\u003e\n                    \u003cexecution\u003e\n                        \u003cid\u003ediktat\u003c/id\u003e\n                        \u003cphase\u003enone\u003c/phase\u003e\n                        \u003cgoals\u003e\n                            \u003cgoal\u003echeck\u003c/goal\u003e\n                            \u003cgoal\u003efix\u003c/goal\u003e\n                        \u003c/goals\u003e\n                        \u003cconfiguration\u003e\n                            \u003cinputs\u003e\n                                \u003cinput\u003e${project.basedir}/src/main/kotlin\u003c/input\u003e\n                                \u003cinput\u003e${project.basedir}/src/test/kotlin\u003c/input\u003e\n                            \u003c/inputs\u003e\n                            \u003cdiktatConfigFile\u003ediktat-analysis.yml\u003c/diktatConfigFile\u003e\n                           \u003cexcludes\u003e\n                              \u003cexclude\u003e${project.basedir}/src/test/kotlin/excluded\u003c/exclude\u003e\n                           \u003c/excludes\u003e\n                        \u003c/configuration\u003e\n                    \u003c/execution\u003e\n                \u003c/executions\u003e\n            \u003c/plugin\u003e\n```\n\u003c/details\u003e\n\nTo run diktat in **only-check** mode use command `$ mvn diktat:check@diktat`.\nTo run diktat in **autocorrect** mode use command `$ mvn diktat:fix@diktat`.\n\nRequesting a specific _Maven_ `executionId` on the command line (the trailing\n`diktat` in the above example) may be essential in these cases:\n\n  * In your `pom.xml`, you have multiple executions with different\n    configurations (e. g.: multiple rule sets):\n    \u003cdetails\u003e\n\n    ```xml\n    \u003cexecutions\u003e\n\n        \u003cexecution\u003e\n            \u003cid\u003ediktat-basic\u003c/id\u003e\n            \u003cconfiguration\u003e\n                \u003cdiktatConfigFile\u003ediktat-analysis.yml\u003c/diktatConfigFile\u003e\n            \u003c/configuration\u003e\n        \u003c/execution\u003e\n\n        \u003cexecution\u003e\n            \u003cid\u003ediktat-advanced\u003c/id\u003e\n            \u003cconfiguration\u003e\n                \u003cdiktatConfigFile\u003ediktat-analysis-advanced.yml\u003c/diktatConfigFile\u003e\n            \u003c/configuration\u003e\n        \u003c/execution\u003e\n\n    \u003c/executions\u003e\n    ```\n    \u003c/details\u003e\n  * Your YAML file with DiKTat rules has a non-default name and/or resides in a\n    non-default location:\n    \u003cdetails\u003e\n\n    ```xml\n    \u003cexecutions\u003e\n        \u003cexecution\u003e\n            \u003cid\u003ediktat\u003c/id\u003e\n            \u003cconfiguration\u003e\n                \u003cdiktatConfigFile\u003e/non/default/rule-set-file.yml\u003c/diktatConfigFile\u003e\n            \u003c/configuration\u003e\n        \u003c/execution\u003e\n    \u003c/executions\u003e\n    ```\n    \u003c/details\u003e\n\n    * You can omit the `diktatConfigFile` or if it points to non-existed file\n      then DiKTat runs with default configuration.\n\nIf you omit the `executionId`:\n\n```console\n$ mvn diktat:check\n```\n\n\u0026mdash; the plug-in will use the default configuration and search for\n`diktat-analysis.yml` file in the project directory (you can still customize the\nrule sets by editing the YAML file).\n\n## Run with Gradle using diktat-gradle-plugin\nRequires a gradle version no lower than 7.0\n\nYou can see how the plugin is configured in our examples:\n- [Kotlin DSL](examples/gradle-kotlin-dsl/build.gradle.kts)\n- [Kotlin DSL for multi-module project](examples/gradle-kotlin-dsl-multiproject/build.gradle.kts)\n- [Groovy DSL](examples/gradle-groovy-dsl/build.gradle)\n\n\u003cdetails\u003e\n\u003csummary\u003eAdd this plugin to your `build.gradle.kts`:\u003c/summary\u003e\n\n```kotlin\nplugins {\n    id(\"com.saveourtool.diktat\") version \"2.0.0\"\n}\n```\n\n\u003e _**Note**_ If you want to apply the plugin to multi-module projects\"\n\u003e ```kotlin\n\u003e import com.saveourtool.diktat.plugin.gradle.DiktatGradlePlugin\n\u003e\n\u003e plugins {\n\u003e     id(\"com.saveourtool.diktat\") version \"2.0.0\" apply false\n\u003e }\n\u003e\n\u003e allprojects {\n\u003e     apply\u003cDiktatGradlePlugin\u003e()\n\u003e }\n\u003e ```\n\nYou can then configure diktat using `diktat` extension:\n```kotlin\ndiktat {\n    inputs {\n        include(\"src/**/*.kt\")  // path matching this pattern (per PatternFilterable) that will be checked by diktat\n        exclude(\"src/test/kotlin/excluded/**\")  // path matching this pattern will not be checked by diktat\n    }\n    debug = true  // turn on debug logging\n}\n```\n\nAlso in `diktat` extension you can configure different reporters and their output. You can specify `json`, `html`, `sarif`, `plain` (default).\nIf `output` is set, it should be a file path. If not set, results will be printed to stdout.\nYou can specify multiple reporters.\nIf no reporter is specified, `plain` will be used with `stdout` as output.\n```kotlin\ndiktat {\n    reporters {\n        plain()\n        json()\n        html {\n            output = file(\"someFile.html\")\n        }\n        // checkstyle()\n        // sarif()\n        // gitHubActions()\n    }\n}\n```\n\u003c/details\u003e\n\nYou can run diktat checks using task `./gradlew diktatCheck` and automatically fix errors with task `./gradlew diktatFix`.\n\n## Run with Spotless\n[Spotless](https://github.com/diffplug/spotless) is a linter aggregator.\n\n### Gradle\nDiktat can be run via spotless-gradle-plugin since version 5.10.0\n\n\u003cdetails\u003e\n\u003csummary\u003eAdd this plugin to your build.gradle.kts\u003c/summary\u003e\n\n```kotlin\nplugins {\n   id(\"com.diffplug.spotless\") version \"5.10.0\"\n}\n\nspotless {\n   kotlin {\n      diktat()\n   }\n   kotlinGradle {\n      diktat()\n   }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eYou can provide a version and configuration path manually as configFile.\u003c/summary\u003e\n\n```kotlin\nspotless {\n   kotlin {\n      diktat(\"2.0.0\").configFile(\"full/path/to/diktat-analysis.yml\")\n   }\n}\n```\n\u003c/details\u003e\n\n### Maven\nDiktat can be run via spotless-maven-plugin since version 2.8.0\n\n\u003cdetails\u003e\n\u003csummary\u003eAdd this plugin to your pom.xml\u003c/summary\u003e\n\n```xml\n\u003cplugin\u003e\n   \u003cgroupId\u003ecom.diffplug.spotless\u003c/groupId\u003e\n   \u003cartifactId\u003espotless-maven-plugin\u003c/artifactId\u003e\n   \u003cversion\u003e${spotless.version}\u003c/version\u003e\n   \u003cconfiguration\u003e\n      \u003ckotlin\u003e\n         \u003cdiktat /\u003e\n      \u003c/kotlin\u003e\n   \u003c/configuration\u003e\n\u003c/plugin\u003e\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eYou can provide a version and configuration path manually as configFile\u003c/summary\u003e\n\n```xml\n\u003cdiktat\u003e\n  \u003cversion\u003e2.0.0\u003c/version\u003e \u003c!-- optional --\u003e\n  \u003cconfigFile\u003efull/path/to/diktat-analysis.yml\u003c/configFile\u003e \u003c!-- optional, configuration file path --\u003e\n\u003c/diktat\u003e\n```\n\u003c/details\u003e\n\n## GitHub Integration\nWe suggest everyone to use common [\"sarif\"](https://docs.oasis-open.org/sarif/sarif/v2.0/sarif-v2.0.html) format as a `reporter` in CI/CD.\nGitHub has an [integration](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning)\nwith SARIF format and provides you a native reporting of diktat issues in Pull Requests.\n\n![img.png](example.png)\n\n\u003cdetails\u003e\n\u003csummary\u003e Github Integration\u003c/summary\u003e\n1) Add the following configuration to your project's setup for GitHub Actions:\n\nGradle Plugin:\n```text\n    githubActions = true\n```\n\nMaven Plugin (pom.xml):\n```xml\n    \u003cgithubActions\u003etrue\u003c/githubActions\u003e\n```\n\nMaven Plugin (cli options):\n```text\nmvn -B diktat:check@diktat -Ddiktat.githubActions=true\n```\n\n2) Add the following code to your GitHub Action to upload diktat SARIF report (after it was generated):\n\n```yml\n      - name: Upload SARIF to Github using the upload-sarif action\n        uses: github/codeql-action/upload-sarif@v1\n        if: ${{ always() }}\n        with:\n          sarif_file: ${{ github.workspace }}\n```\n\n*Note*: `codeql-action/upload-sarif` limits the number of uploaded files at 15. If your project has more than 15 subprojects,\nthe limit will be exceeded and the step will fail. To solve this issue one can merge SARIF reports.\n\n`diktat-gradle-plugin` provides this capability with `mergeDiktatReports` task. This task aggregates reports of all diktat tasks\nof all Gradle project, which produce SARIF reports, and outputs the merged report into root project's build directory. Then this single\nfile can be used as an input for GitHub action:\n```yaml\nwith:\n    sarif_file: build/reports/diktat/diktat-merged.sarif\n```\n\n\u003c/details\u003e\n\n## \u003ca name=\"config\"\u003e\u003c/a\u003e Customizations via `diktat-analysis.yml`\n\nIn Diktat we have supported `diktat-analysis.yml` that can be easily\nchanged and help in customization of your own rule set.\nIt has simple fields:\n`name` — name of the rule,\n`enabled` (true/false) — to enable or disable that rule (all rules are enabled by the default),\n`configuration` — a simple map of some extra unique configurations for this particular rule.\nFor example:\n\n```yaml\n- name: HEADER_MISSING_OR_WRONG_COPYRIGHT\n  # all rules are enabled by the default. To disable add 'enabled: false' to the config.\n  enabled: true\n  configuration:\n    isCopyrightMandatory: true\n    copyrightText: Copyright (c) Jeff Lebowski, 2012-2020. All rights reserved.\n```\nNote, that you can specify and put `diktat-analysis.yml` that contains configuration of diktat in the parent directory of your project on the same level where `build.gradle/pom.xml` is stored. \\\nSee default configuration in [diktat-analysis.yml](diktat-rules/src/main/resources/diktat-analysis.yml) \\\nAlso see [the list of all rules supported by diKTat](info/available-rules.md).\n\n\n## \u003ca name=\"suppress\"\u003e\u003c/a\u003e Suppress warnings/inspections\n\n\u003cdetails\u003e\n\u003csummary\u003eSuppress warnings on individual code blocks\u003c/summary\u003e\nIn addition to enabling/disabling warning globally via config file (`enable = false`), you can suppress warnings\nby adding `@Suppress` annotation on individual code blocks or `@file:Suppress()` annotation on a file-level.\n\nFor example:\n\n``` kotlin\n@Suppress(\"FUNCTION_NAME_INCORRECT_CASE\")\nclass SomeClass {\n    fun methODTREE(): String {\n\n    }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eDisable all inspections on selected code blocks\u003c/summary\u003e\nAlso you can suppress **all** warnings by adding `@Suppress(\"diktat\")` annotation on individual code blocks.\n\nFor example:\n\n``` kotlin\n@Suppress(\"diktat\")\nclass SomeClass {\n    fun methODTREE(): String {\n\n    }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eignoreAnnotated: disable inspections on blocks with predefined annotation\u003c/summary\u003e\nIn the `diktat-analysis.yml` file for each inspection it is possible to define a list of annotations that will cause\ndisabling of the inspection on that particular code block:\n\n```yaml\n- name: HEADER_NOT_BEFORE_PACKAGE\n  enabled: true\n  ignoreAnnotated: [MyAnnotation, Compose, Controller]\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eSuppress groups of inspections by chapters\u003c/summary\u003e\nIt is easy to suppress even groups of inspections in diKTat.\n\nThese groups are linked to chapters of [Codestyle](info/guide/diktat-coding-convention.md).\n\nTo disable chapters, you will need to add the following configuration to common configuration (`- name: DIKTAT_COMMON`):\n```yaml\n    disabledChapters: \"1, 2, 3\"\n```\n\nMapping of inspections to chapters can be found in [Groups of Inspections](info/rules-mapping.md).\n\u003c/details\u003e\n\n## Running against the baseline\nWhen setting up code style analysis on a large existing project, one often doesn't have an ability to fix all findings at once.\nTo allow gradual adoption, diktat and ktlint support baseline mode. When running ktlint for the first time with active baseline,\nthe baseline file will be generated. It is a xml file with a complete list of findings by the tool. On later invocations,\nonly the findings that are not in the baseline file will be reported. Baseline can be activated with CLI flag:\n```bash\n./diktat --baseline=diktat-baseline.xml **/*.kt\n```\nor with corresponding configuration options in maven or gradle plugins. Baseline report is intended to be added into the VCS,\nbut it can be removed and re-generated later, if needed.\n\n## Contribution\nSee our [Contributing Policy](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md)\n\n## Kotlin Coding Style Guide (Diktat Code Style), v.1.0.0\n\nI [Preface](#c0)\n* [I.I Purpose of this document](#c0.1)\n* [I.II General principles](#c0.2)\n* [I.III Terminology](#c0.3)\n* [I.IV Exceptions](#c0.4)\n\n[1. Naming](#c1)\n\n* [1.1 Identifiers](#c1.1)\n* [1.2 Packages](#c1.2)\n* [1.3 Classes, enumerations, interfaces](#c1.3)\n* [1.4 Functions](#c1.4)\n* [1.5 Constants](#c1.5)\n* [1.6 Non-constant fields (variables)](#c1.6)\n    * [1.6.1 Non-constant field name](#r1.6.1)\n    * [1.6.2 Boolean variable names with negative meaning](#r1.6.2)\n\n[2. Comments](#c2)\n* [2.1 General form of Kdoc](#c2.1)\n    * [2.1.1 Using KDoc for the public, protected, or internal code elements](#r2.1.1)\n    * [2.1.2 Describing methods that have arguments, a return value, or can throw an exception in the KDoc block](#r2.1.2)\n    * [2.1.3 Only one space between the Kdoc tag and content. Tags are arranged in the order.](#r2.1.3)\n* [2.2 Adding comments on the file header](#c2.2)\n* [2.3 Comments on the function header](#c2.3)\n* [2.4 Code comments](#c2.4)\n    * [2.4.1 Add a blank line between the body of the comment and Kdoc tag-blocks](#r2.4.1)\n    * [2.4.2 Do not comment on unused code blocks](#r2.4.2)\n    * [2.4.3 Code delivered to the client should not contain TODO/FIXME comments](#r2.4.3)\n\n[3. General formatting (typesetting)](#c3)\n* [3.1 File-related rules](#c3.1)\n    * [3.1.1 Avoid files that are too long](#r3.1.1)\n    * [3.1.2 Code blocks in the source file should be separated by one blank line](#r3.1.2)\n    * [3.1.3 Import statements order](#r3.1.3)\n    * [3.1.4 Order of declaration parts of class-like code structures](#r3.1.4)\n    * [3.1.5 Order of declaration of top-level code structures](#r3.1.5)\n* [3.2 Braces](#c3.2)\n    * [3.2.1 Using braces in conditional statements and loop blocks](#r3.2.1)\n    * [3.2.2 Opening braces are placed at the end of the line in *non-empty* blocks and block structures](#r3.2.2)\n* [3.3 Indentation](#c3.3)\n* [3.4 Empty blocks](#c3.4)\n* [3.5 Line length](#c3.5)\n* [3.6 Line breaks (newlines)](#c3.6)\n    * [3.6.1 Each line can have a maximum of one statement](#r3.6.1)\n    * [3.6.2 Rules for line-breaking](#r3.6.2)\n* [3.7 Using blank lines](#c3.7)\n* [3.8 Horizontal space](#c3.8)\n    * [3.8.1 Usage of whitespace for code separation](#r3.8.1)\n    * [3.8.2 No spaces for horizontal alignment](#r3.8.2)\n* [3.9 Enumerations](#c3.9)\n* [3.10 Variable declaration](#c3.10)\n    * [3.10.1 Declare one variable per line](#r3.10.1)\n    * [3.10.2 Variables should be declared near the line where they are first used](#r3.10.2)\n* [3.11 'When' expression](#c3.11)\n* [3.12 Annotations](#c3.12)\n* [3.13 Block comments](#c3.13)\n* [3.14 Modifiers and constant values](#c3.14)\n    * [3.14.1 Declaration with multiple modifiers](#r3.14.1)\n    * [3.14.2 Separate long numerical values with an underscore](#r3.14.2)\n* [3.15 Strings](#c3.15)\n    * [3.15.1 Concatenation of Strings](#r3.15.1)\n    * [3.15.2 String template format](#r3.15.2)\n* [3.16 Conditional statements](#c3.16)\n    * [3.16.1 Collapsing redundant nested if-statements](#r3.16.1)\n    * [3.16.2 Too complex conditions](#r3.16.2)\n\n[4. Variables and types](#c4)\n* [4.1 Variables](#c4.1)\n    * [4.1.1 Do not use Float and Double types when accurate calculations are needed](#r4.1.1)\n    * [4.1.2 Comparing numeric float type values](#r4.1.2)\n    * [4.1.3 Try to use 'val' instead of 'var' for variable declaration [SAY_NO_TO_VAR]](#r4.1.3)\n* [4.2 Types](#c4.2)\n    * [4.2.1 Use Contracts and smart cast as much as possible](#r4.2.1)\n    * [4.2.2 Try to use type alias to represent types making code more readable](#r4.2.2)\n* [4.3 Null safety and variable declarations](#c4.3)\n    * [4.3.1 Avoid declaring variables with nullable types, especially from Kotlin stdlib](#r4.3.1)\n    * [4.3.2 Variables of generic types should have an explicit type declaration](#r4.3.2)\n    * [4.3.3 Null-safety](#r4.3.3)\n\n[5. Functions](#c5)\n* [5.1 Function design](#c5.1)\n    * [5.1.1 Avoid functions that are too long ](#r5.1.1)\n    * [5.1.2 Avoid deep nesting of function code blocks, limiting to four levels](#r5.1.2)\n    * [5.1.3 Avoid using nested functions](#r5.1.3)\n    * [5.1.4 Negated function calls](#r5.1.4)\n* [5.2 Function arguments](#c5.2)\n    * [5.2.1 The lambda parameter of the function should be placed at the end of the argument list](#r5.2.1)\n    * [5.2.2 Number of function parameters should be limited to five](#r5.2.2)\n    * [5.2.3 Use default values for function arguments instead of overloading them](#r5.2.3)\n    * [5.2.4 Synchronizing code inside asynchronous code](#r5.2.4)\n    * [5.2.5 Long lambdas should have explicit parameters](#r5.2.5)\n    * [5.2.6 Avoid using unnecessary, custom label](#r5.2.6)\n\n[6. Classes, interfaces, and extension functions](#c6)\n* [6.1 Classes](#c6.1)\n    * [6.1.1 Denoting a class with a single constructor](#r6.1.1)\n    * [6.1.2 Prefer data classes instead of classes without any functional logic](#r6.1.2)\n    * [6.1.3 Do not use the primary constructor if it is empty or useless](#r6.1.3)\n    * [6.1.4 Do not use redundant init blocks in your class](#r6.1.4)\n    * [6.1.5 Explicit supertype qualification](#r6.1.5)\n    * [6.1.6 Abstract class should have at least one abstract method](#r6.1.6)\n    * [6.1.7 When using the \"implicit backing property\" scheme, the name of real and back property should be the same](#r6.1.7)\n    * [6.1.8 Avoid using custom getters and setters](#r6.1.8)\n    * [6.1.9 Never use the name of a variable in the custom getter or setter (possible_bug)](#r6.1.9)\n    * [6.1.10 No trivial getters and setters are allowed in the code](#r6.1.10)\n    * [6.1.11 Use 'apply' for grouping object initialization](#r6.1.11)\n    * [6.1.12 Prefer Inline classes when a class has a single property](#r6.1.12)\n* [6.2 Extension functions](#c6.2)\n    * [6.2.1 Use extension functions for making logic of classes less coupled](#r6.2.1)\n    * [6.2.2 No extension functions with the same name and signature if they extend base and inheritor classes (possible_bug)](#r6.2.2)\n    * [6.2.3 Don't use extension functions for the class in the same file](#r6.2.3)\n* [6.3 Interfaces](#c6.3)\n* [6.4 Objects](#c6.4)\n    * [6.4.1 Instead of using utility classes/objects, use extensions](#r6.4.1)\n    * [6.4.2 Objects should be used for Stateless Interfaces](#r6.4.2)\n* [6.5 Kts Files](#c6.5)\n    * [6.5.1 kts files should wrap logic into top-level scope](#r6.5.1)\n\n## \u003ca name=\"c0\"\u003e\u003c/a\u003e Preface\n \u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c0.1\"\u003e\u003c/a\u003e Purpose of this document\n\nThe purpose of this document is to provide a specification that software developers could reference to enhance their ability to write consistent, easy-to-read, and high-quality code.\nSuch a specification will ultimately improve software development efficiency and product competitiveness.\nFor the code to be considered high-quality, it must entail the following characteristics:\n1.\tSimplicity\n2.\tMaintainability\n3.\tReliability\n4.\tTestability\n5.\tEfficiency\n6.\tPortability\n7.\tReusability\n\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c0.2\"\u003e\u003c/a\u003e General principles\n\nLike other modern programming languages, Kotlin is an advanced programming language that complies with the following general principles:\n1.\tClarity — a necessary feature of programs that are easy to maintain and refactor.\n2.\tSimplicity — a code is easy to understand and implement.\n3.\tConsistency — enables a code to be easily modified, reviewed, and understood by the team members. Unification is particularly important when the same team works on the same project, utilizing similar styles enabling a code to be easily modified, reviewed, and understood by the team members.\n\nAlso, we need to consider the following factors when programming on Kotlin:\n\n1. Writing clean and simple Kotlin code\n\n   Kotlin combines two of the main programming paradigms: functional and object-oriented.\n   Both of these paradigms are trusted and well-known software engineering practices.\n   As a young programming language, Kotlin is built on top of well-established languages such as Java, C++, C#, and Scala.\n   This enables Kotlin to introduce many features that help a developer write cleaner, more readable code while also reducing the number of complex code structures. For example, type and null safety, extension functions, infix syntax, immutability, val/var differentiation, expression-oriented features, \"when\" statements, much easier work with collections, type auto conversion, and other syntactic sugar.\n\n2. Following Kotlin idioms\n\n   The author of Kotlin, Andrey Breslav, mentioned that Kotlin is both pragmatic and practical, but not academic.\n   Its pragmatic features enable ideas to be transformed into real working software easily. Kotlin is closer to natural languages than its predecessors, and it implements the following design principles: readability, reusability, interoperability, security, and tool-friendliness (https://blog.jetbrains.com/kotlin/2018/10/kotlinconf-2018-announcements/).\n\n3. Using Kotlin efficiently\n\n   Some Kotlin features can help you to write higher-performance code: including rich coroutine library, sequences, inline functions/classes, arrays of basic types, tailRec, and CallsInPlace of contract.\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c0.3\"\u003e\u003c/a\u003e Terminology\n\n**Rules** — conventions that should be followed when programming.\n\n**Recommendations** — conventions that should be considered when programming.\n\n**Explanation** — necessary explanations of rules and recommendations.\n\n**Valid Example** — recommended examples of rules and recommendations.\n\n**Invalid Example** — not recommended examples of rules and recommendations.\n\nUnless otherwise stated, this specification applies to versions 1.3 and later of Kotlin.\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c0.4\"\u003e\u003c/a\u003e Exceptions\n\nEven though exceptions may exist, it is essential to understand why rules and recommendations are needed.\nDepending 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.\nWhen 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.\nSoftware that is directly based on the Android native operating system interface, such as the Android Framework, remains consistent with the Android style.\n# \u003ca name=\"c1\"\u003e\u003c/a\u003e 1. Naming\nIn programming, it is not always easy to meaningfully and appropriately name variables, functions, classes, etc. Using meaningful names helps to clearly express your code's main ideas and functionality and avoid misinterpretation, unnecessary coding and decoding, \"magic\" numbers, and inappropriate abbreviations.\n\nNote: The source file encoding format (including comments) must be UTF-8 only. The ASCII horizontal space character (0x20, that is, space) is the only permitted whitespace character. Tabs should not be used for indentation.\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c1.1\"\u003e\u003c/a\u003e 1.1 Identifiers\nThis section describes the general rules for naming identifiers.\n#### \u003ca name=\"r1.1.1\"\u003e\u003c/a\u003e 1.1.1 Identifiers naming conventions\n\nFor identifiers, use the following naming conventions:\n1.\tAll identifiers should use only ASCII letters or digits, and the names should match regular expressions `\\w{2,64}`.\n      Explanation: Each valid identifier name should match the regular expression `\\w{2,64}`.\n      `{2,64}` means that the name length is 2 to 64 characters, and the length of the variable name should be proportional to its life range, functionality, and responsibility.\n      Name lengths of less than 31 characters are generally recommended. However, this depends on the project. Otherwise, a class declaration with generics or inheritance from a superclass can cause line breaking.\n      No special prefix or suffix should be used in names. The following examples are inappropriate names: name_, mName, s_name, and kName.\n\n2.\tChoose file names that would describe the content. Use camel case (PascalCase) and `.kt` extension.\n\n3.\tTypical examples of naming:\n\n| Meaning | Correct |Incorrect|\n| ---- | ---- | ---- |\n| \"XML Http Request\" | XmlHttpRequest | XMLHTTPRequest |\n| \"new customer ID\" | newCustomerId | newCustomerID |\n| \"inner stopwatch\" | innerStopwatch | innerStopWatch |\n| \"supports IPv6 on iOS\" | supportsIpv6OnIos | supportsIPv6OnIOS |\n| \"YouTube importer\" | YouTubeImporter | YoutubeImporter |\n\n4.\tThe usage of (``) and free naming for functions and identifiers are prohibited. For example, the following code is not recommended:\n\n```kotlin\nval `my dummy name-with-minus` = \"value\"\n```\n\nThe only exception is function names in `Unit tests.`\n\n5.\tBackticks (``) should not be used for identifiers, except the names of test methods (marked with @Test annotation):\n```kotlin\n @Test fun `my test`() { /*...*/ }\n```\n6.  The following table contains some characters that may cause confusion. Be careful when using them as identifiers. To avoid issues, use other names instead.\n\n| Expected      | Confusing name           | Suggested name   |\n| ------------- | ------------------------ | ---------------- |\n| 0 (zero)      | O, D                     | obj, dgt         |\n| 1 (one)       | I, l                     | it, ln, line     |\n| 2 (two)       | Z                        | n1, n2           |\n| 5 (five)      | S                        | xs, str          |\n| 6 (six)       | e                        | ex, elm          |\n| 8 (eight)     | B                        | bt, nxt          |\n| n,h           | h,n                      | nr, head, height |\n| rn, m         | m,rn                     | mbr, item        |\n\n**Exceptions:**\n- The i,j,k variables used in loops are part of the industry standard. One symbol can be used for such variables.\n- The `e` variable can be used to catch exceptions in catch block: `catch (e: Exception) {}`\n- The Java community generally does not recommend the use of prefixes. However, when developing Android code, you can use the s and m prefixes for static and non-public non-static fields, respectively.\n  Note that prefixing can also negatively affect the style and the auto-generation of getters and setters.\n\n| Type | Naming style |\n| ---- | ---- |\n| Interfaces, classes, annotations, enumerated types, and object type names | Camel case, starting with a capital letter. Test classes have a Test suffix. The filename is 'TopClassName'.kt.  |\n| Class fields, local variables, methods, and method parameters | Camel case starting with a low case letter. Test methods can be underlined with '_'; the only exception is [backing properties](#r6.1.7).\n| Static constants and enumerated values | Only uppercase underlined with '_' |\n| Generic type variable | Single capital letter, which can be followed by a number, for example: `E, T, U, X, T2` |\n| Exceptions | Same as class names, but with a suffix Exception, for example: `AccessException` and `NullPointerException`|\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c1.2\"\u003e\u003c/a\u003e 1.2 Packages\n\n#### \u003ca name=\"r1.2.1\"\u003e\u003c/a\u003e Rule 1.2.1 Package names dots\nPackage names are in lower case and separated by dots. Code developed within your company should start with `your.company.domain.` Numbers are permitted in package names.\nEach file should have a `package` directive.\nPackage names are all written in lowercase, and consecutive words are concatenated together (no underscores). Package names should contain both the product or module names and the department (or team) name to prevent conflicts with other teams.  Numbers are not permitted. For example: `org.apache.commons.lang3`, `xxx.yyy.v2`.\n\n**Exceptions:**\n\n- In certain cases, such as open-source projects or commercial cooperation, package names should not start with `your.company.domain.`\n- If the package name starts with a number or other character that cannot be used at the beginning of the Java/Kotlin package name, then underscores are allowed. For example: `com.example._123name`.\n- Underscores are sometimes permitted if the package name contains reserved Java/Kotlin keywords, such as `org.example.hyphenated_name`, `int_.example`.\n\n**Valid example**:\n```kotlin\npackage your.company.domain.mobilecontrol.views\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c1.3\"\u003e\u003c/a\u003e 1.3 Classes, enumerations, typealias, interfaces\nThis section describes the general rules for naming classes, enumerations, and interfaces.\n### \u003ca name=\"r1.3.1\"\u003e\u003c/a\u003e 1.3.1 Classes, enumerations, typealias, interface names use Camel case\nClasses, enumerations, and interface names use `UpperCamelCase` nomenclature. Follow the naming rules described below:\n1.\tA class name is usually a noun (or a noun phrase) denoted using the camel case nomenclature, such as UpperCamelCase. For example: `Character` or `ImmutableList`.\n      An interface name can also be a noun or noun phrase (such as `List`) or an adjective or adjective phrase (such as `Readable`).\n      Note that verbs are not used to name classes. However, nouns (such as `Customer`, `WikiPage`, and `Account`) can be used. Try to avoid using vague words such as `Manager` and `Process`.\n\n2.\tTest classes start with the name of the class they are testing and end with 'Test'. For example, `HashTest` or `HashIntegrationTest`.\n\n**Invalid example**:\n```kotlin\nclass marcoPolo {}\nclass XMLService {}\ninterface TAPromotion {}\nclass info {}\n```\n\n**Valid example**:\n```kotlin\nclass MarcoPolo {}\nclass XmlService {}\ninterface TaPromotion {}\nclass Order {}\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c1.4\"\u003e\u003c/a\u003e 1.4 Functions\nThis section describes the general rules for naming functions.\n### \u003ca name=\"r1.4.1\"\u003e\u003c/a\u003e 1.4.1 Function names should be in camel case\nFunction names should use `lowerCamelCase` nomenclature. Follow the naming rules described below:\n1.\tFunction names are usually verbs or verb phrases denoted with the camel case nomenclature (`lowerCamelCase`).\n      For example: `sendMessage`, `stopProcess`, or `calculateValue`.\n      To name functions, use the following formatting rules:\n\na) To get, modify, or calculate a certain value: get + non-boolean field(). Note that the Kotlin compiler automatically generates getters for some classes, applying the special syntax preferred for the 'get' fields: kotlin private val field: String get() { }. kotlin private val field: String get() { }.\n```kotlin\nprivate val field: String\nget() {\n}\n```\nNote: The calling property access syntax is preferred to call getter directly. In this case, the Kotlin compiler automatically calls the corresponding getter.\n\nb) `is` + boolean variable name()\n\nc) `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.\n\nd) `has` + Noun / adjective ()\n\ne) verb()\nNote: Note: Verb are primarily used for the action objects, such as `document.print ()`\n\nf) verb + noun()\n\ng) The Callback function allows the names that use the preposition + verb format, such as: `onCreate()`, `onDestroy()`, `toString()`.\n\n**Invalid example**:\n\n```kotlin\nfun type(): String\nfun Finished(): Boolean\nfun visible(boolean)\nfun DRAW()\nfun KeyListener(Listener)\n```\n\n**Valid example**:\n\n```kotlin\nfun getType(): String\nfun isFinished(): Boolean\nfun setVisible(boolean)\nfun draw()\nfun addKeyListener(Listener)\n```\n\n2.\tAn underscore (`_`) can be included in the JUnit test function name and should be used as a separator. Each logical part is denoted in `lowerCamelCase`, for example, a typical pattern of using underscore: `pop_emptyStack`.\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c1.5\"\u003e\u003c/a\u003e 1.5 Constants\nThis section describes the general rules for naming constraints.\n### \u003ca name=\"r1.5.1\"\u003e\u003c/a\u003e 1.5.1 Using UPPER case and underscore characters in a constraint name\nConstant names should be in UPPER case, words separated by underscore. The general constant naming conventions are listed below:\n1. 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.\n2. 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.\n3. Objects with immutable content, such as `Logger` and `Lock`, can be in uppercase as constants or have camel case as regular variables.\n4. Use meaningful constants instead of `magic numbers`. SQL or logging strings should not be treated as magic numbers, nor should they be defined as string constants.\n   Magic constants, such as `NUM_FIVE = 5` or `NUM_5 = 5` should not be treated as constants. This is because mistakes will easily be made if they are changed to `NUM_5 = 50` or 55.\n   These constants typically represent business logic values, such as measures, capacity, scope, location, tax rate, promotional discounts, and power base multiples in algorithms.\n   You can avoid using magic numbers with the following method:\n- Using library functions and APIs. For example, instead of checking that `size == 0`, use `isEmpty()` function. To work with `time`, use built-ins from `java.time API`.\n- Enumerations can be used to name patterns. Refer to [Recommended usage scenario for enumeration in 3.9](#c3.9).\n\n**Invalid example**:\n\n```kotlin\nvar int MAXUSERNUM = 200;\nval String sL = \"Launcher\";\n```\n\n**Valid example**:\n\n```kotlin\nconst val int MAX_USER_NUM = 200;\nconst val String APPLICATION_NAME = \"Launcher\";\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c1.6\"\u003e\u003c/a\u003e 1.6 Non-constant fields (variables)\nThis section describes the general rules for naming variables.\n### \u003ca name=\"r1.6.1\"\u003e\u003c/a\u003e 1.6.1 Non-constant field name\nNon-constant field names should use camel case and start with a lowercase letter.\nA local variable cannot be treated as constant even if it is final and immutable. Therefore, it should not use the preceding rules. Names of collection type variables (sets, lists, etc.) should contain plural nouns.\nFor example: `var namesList: List\u003cString\u003e`\n\nNames of non-constant variables should use `lowerCamelCase`. The name of the final immutable field used to store the singleton object can use the same camel case notation.\n\n**Invalid example**:\n```kotlin\ncustomername: String\nuser: List\u003cString\u003e = listof()\n```\n\n**Valid example**:\n```kotlin\nvar customerName: String\nval users: List\u003cString\u003e = listOf();\nval mutableCollection: MutableSet\u003cString\u003e = HashSet()\n```\n\n### \u003ca name=\"r1.6.2\"\u003e\u003c/a\u003e 1.6.2 Boolean variable names with negative meaning\n\nAvoid using Boolean variable names with a negative meaning. When using a logical operator and name with a negative meaning, the code may be difficult to understand, which is referred to as the \"double negative\".\nFor instance, it is not easy to understand the meaning of !isNotError.\nThe JavaBeans specification automatically generates isXxx() getters for attributes of Boolean classes.\nHowever, not all methods returning Boolean type have this notation.\nFor Boolean local variables or methods, it is highly recommended that you add non-meaningful prefixes, including is (commonly used by JavaBeans), has, can, should, and must. Modern integrated development environments (IDEs) such as Intellij are already capable of doing this for you when you generate getters in Java. For Kotlin, this process is even more straightforward as everything is on the byte-code level under the hood.\n\n**Invalid example**:\n```kotlin\nval isNoError: Boolean\nval isNotFound: Boolean\nfun empty()\nfun next();\n```\n\n**Valid example**:\n```kotlin\nval isError: Boolean\nval isFound: Boolean\nval hasLicense: Boolean\nval canEvaluate: Boolean\nval shouldAbort: Boolean\nfun isEmpty()\nfun hasNext()\n```\n# \u003ca name=\"c2\"\u003e\u003c/a\u003e 2. Comments\n\nThe best practice is to begin your code with a summary, which can be one sentence.\nTry to balance between writing no comments at all and obvious commentary statements for each line of code.\nComments should be accurately and clearly expressed, without repeating the name of the class, interface, or method.\nComments are not a solution to the wrong code. Instead, you should fix the code as soon as you notice an issue or plan to fix it (by entering a TODO comment, including a Jira number).\nComments should accurately reflect the code's design ideas and logic and further describe its business logic.\nAs a result, other programmers will be able to save time when trying to understand the code.\nImagine that you are writing the comments to help yourself to understand the original ideas behind the code in the future.\n\n### \u003ca name=\"c2.1\"\u003e\u003c/a\u003e 2.1 General form of Kdoc\n\nKDoc is a combination of JavaDoc's block tags syntax (extended to support specific constructions of Kotlin) and Markdown's inline markup.\nThe basic format of KDoc is shown in the following example:\n\n```kotlin\n /**\n * There are multiple lines of KDoc text,\n * Other ...\n */\nfun method(arg: String) {\n    // ...\n}\n```\n\nIt is also shown in the following single-line form:\n\n```kotlin\n /** Short form of KDoc. */\n```\nUse a single-line form when you store the entire KDoc block in one line (and there is no KDoc mark @XXX). For detailed instructions on how to use KDoc, refer to [Official Document](https://docs.oracle.com/en/Kotlin/Kotlinse/11/tools/KDoc.html).\n\n#### \u003ca name=\"r2.1.1\"\u003e\u003c/a\u003e 2.1.1 Using KDoc for the public, protected, or internal code elements\n\nAt a minimum, KDoc should be used for every public, protected, or internal decorated class, interface, enumeration, method, and member field (property).\nOther code blocks can also have KDocs if needed.\nInstead of using comments or KDocs before properties in the primary constructor of a class - use `@property` tag in a KDoc of a class.\nAll properties of the primary constructor should also be documented in a KDoc with a `@property` tag.\n\n\n**Incorrect example:**\n```kotlin\n/**\n * Class description\n */\nclass Example(\n /**\n  * property description\n  */\n  val foo: Foo,\n  // another property description\n  val bar: Bar\n)\n```\n\n**Correct example:**\n```kotlin\n/**\n * Class description\n * @property foo property description\n * @property bar another property description\n */\nclass Example(\n  val foo: Foo,\n  val bar: Bar\n)\n```\n- Don't use Kdoc comments inside code blocks as block comments\n\n**Incorrect Example:**\n\n```kotlin\nclass Example {\n  fun doGood() {\n    /**\n     * wrong place for kdoc\n     */\n    1 + 2\n  }\n}\n```\n\n**Correct Example:**\n\n```kotlin\nclass Example {\n  fun doGood() {\n    /*\n     * right place for block comment\n    */\n    1 + 2\n  }\n}\n```\n\n**Exceptions:**\n\n* For setters/getters of properties, obvious comments (like `this getter returns field`) are optional. Note that Kotlin generates simple `get/set` methods under the hood.\n\n* It is optional to add comments for simple one-line methods, such as shown in the example below:\n```kotlin\nval isEmpty: Boolean\n    get() = this.size == 0\n```\n\nor\n\n```kotlin\nfun isEmptyList(list: List\u003cString\u003e) = list.size == 0\n```\n\n**Note:** You can skip KDocs for a method's override if it is almost the same as the superclass method.\n\n#### \u003ca name=\"r2.1.2\"\u003e\u003c/a\u003e 2.1.2 Describing methods that have arguments, a return value, or can throw an exception in the KDoc block\n\nWhen the method has such details as arguments, return value, or can throw exceptions, it must be described in the KDoc block (with @param, @return, @throws, etc.).\n\n**Valid examples:**\n\n ```kotlin\n/**\n * This is the short overview comment for the example interface.\n *     / * Add a blank line between the comment text and each KDoc tag underneath * /\n * @since 1.6\n */\n protected abstract class Sample {\n    /**\n     * This is a long comment with whitespace that should be split in\n     * comments on multiple lines if the line comment formatting is enabled.\n     *     / * Add a blank line between the comment text and each KDoc tag underneath * /\n     * @param fox A quick brown fox jumps over the lazy dog\n     * @return battle between fox and dog\n     */\n    protected abstract fun foo(Fox fox)\n     /**\n      * These possibilities include: Formatting of header comments\n      *     / * Add a blank line between the comment text and each KDoc tag underneath * /\n      * @return battle between fox and dog\n      * @throws ProblemException if lazy dog wins\n      */\n    protected fun bar() throws ProblemException {\n        // Some comments / * No need to add a blank line here * /\n        var aVar = ...\n\n        // Some comments  / * Add a blank line before the comment * /\n        fun doSome()\n    }\n }\n ```\n\n#### \u003ca name=\"r2.1.3\"\u003e\u003c/a\u003e2.1.3 Only one space between the Kdoc tag and content. Tags are arranged in the order.\n\nThere should be only one space between the Kdoc tag and content. Tags are arranged in the following order: @param, @return, and @throws.\n\nTherefore, Kdoc should contain the following:\n- Functional and technical description, explaining the principles, intentions, contracts, API, etc.\n- The function description and @tags (`implSpec`, `apiNote`, and `implNote`) require an empty line after them.\n- `@implSpec`: A specification related to API implementation, and it should let the implementer decide whether to override it.\n- `@apiNote`: Explain the API precautions, including whether to allow null and whether the method is thread-safe, as well as the algorithm complexity, input, and output range, exceptions, etc.\n- `@implNote`: A note related to API implementation, which implementers should keep in mind.\n- One empty line, followed by regular `@param`, `@return`, `@throws`, and other comments.\n- The conventional standard \"block labels\" are arranged in the following order: `@param`, `@return`, `@throws`.\n  Kdoc should not contain:\n- Empty descriptions in tag blocks. It is better not to write Kdoc than waste code line space.\n- There should be no empty lines between the method/class declaration and the end of Kdoc (`*/` symbols).\n- `@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.\n  Important notes:\n- KDoc does not support the `@deprecated` tag. Instead, use the `@Deprecated` annotation.\n- The `@since` tag should be used for versions only. Do not use dates in `@since` tag, it's confusing and less accurate.\n\nIf a tag block cannot be described in one line, indent the content of the new line by *four spaces* from the `@` position to achieve alignment (`@` counts as one + three spaces).\n\n**Exception:**\n\nWhen the descriptive text in a tag block is too long to wrap, you can indent the alignment with the descriptive text in the last line. The descriptive text of multiple tags does not need to be aligned.\nSee [3.8 Horizontal space](#c3.8).\n\nIn Kotlin, compared to Java, you can put several classes inside one file, so each class should have a Kdoc formatted comment (as stated in rule 2.1).\nThis comment should contain @since tag. The right style is to write the application version when its functionality is released. It should be entered after the `@since` tag.\n\n**Examples:**\n\n```kotlin\n/**\n * Description of functionality\n *\n * @since 1.6\n */\n```\n\nOther KDoc tags (such as @param type parameters and @see.) can be added as follows:\n```kotlin\n/**\n * Description of functionality\n *\n * @apiNote: Important information about API\n *\n * @since 1.6\n */\n```\n\n### \u003ca name=\"c2.2\"\u003e\u003c/a\u003e 2.2 Adding comments on the file header\n\nThis section describes the general rules of adding comments on the file header.\n\n### \u003ca name=\"r2.2.1\"\u003e\u003c/a\u003e 2.2.1 Formatting of comments in the file header\n\nComments on the file header should be placed before the package name and imports. If you need to add more content to the comment, subsequently add it in the same format.\n\nComments on the file header must include copyright information, without the creation date and author's name (use VCS for history management).\nAlso, describe the content inside files that contain multiple or no classes.\n\nThe following examples for Huawei describe the format of the *copyright license*: \\\nChinese version: `版权所有 (c) 华为技术有限公司 2012-2020` \\\nEnglish version: `Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved.`\n`2012` and `2020` are the years the file was first created and the current year, respectively.\n\nDo 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.\n\nInvalid example:\n```kotlin\n/**\n * Release notes:\n * 2019-10-11: added class Foo\n */\n\nclass Foo\n```\n\nValid example:\n```kotlin\n/**\n * @since 2.4.0\n */\nclass Foo\n```\n\n- The **copyright statement** can use your company's subsidiaries, as shown in the below examples: \\\n  Chinese version: `版权所有 (c) 海思半导体 2012-2020` \\\n  English version: `Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2020. All rights reserved.`\n\n- The copyright information should not be written in KDoc style or use single-line comments. It must start from the beginning of the file.\n  The following example is a copyright statement for Huawei, without other functional comments:\n\n```kotlin\n/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved.\n */\n```\n\nThe following factors should be considered when writing the file header or comments for top-level classes:\n- File header comments must start from the top of the file. If it is a top-level file comment, there should be a blank line after the last Kdoc `*/` symbol. If it is a comment for a top-level class, the class declaration should start immediately without using a newline.\n- Maintain a unified format. The specific format can be formulated by the project (for example, if you use an existing opensource project), and you need to follow it.\n- A top-level file-Kdoc must include a copyright and functional description, especially if there is more than one top-level class.\n- Do not include empty comment blocks. If there is no content after the option `@apiNote`, the entire tag block should be deleted.\n- The industry practice is not to include historical information in the comments. The corresponding history can be found in VCS (git, svn, etc.). Therefore, it is not recommended to include historical data in the comments of the Kotlin source code.\n\n### \u003ca name=\"c2.3\"\u003e\u003c/a\u003e 2.3 Comments on the function header\n\nComments on the function header are placed above function declarations or definitions. A newline should not exist between a function declaration and its Kdoc. Use the preceding \u003c\u003cc2.1,KDoc\u003e\u003e style rules.\n\nAs stated in Chapter 1, the function name should reflect its functionality as much as possible. Therefore, in the Kdoc, try to describe the functionality that is not mentioned in the function name.\nAvoid unnecessary comments on dummy coding.\n\nThe function header comment's content is optional, but not limited to function description, return value, performance constraints, usage, memory conventions, algorithm implementation, reentrant requirements, etc.\n\n### \u003ca name=\"c2.4\"\u003e\u003c/a\u003e 2.4 Code comments\n\nThis section describes the general rules of adding code comments.\n\n#### \u003ca name=\"r2.4.1\"\u003e\u003c/a\u003e 2.4.1 Add a blank line between the body of the comment and Kdoc tag-blocks.\n\nIt is a good practice to add a blank line between the body of the comment and Kdoc tag-blocks. Also, consider the following rules:\n- There must be one space between the comment character and the content of the comment.\n- There must be a newline between a Kdoc and the presiding code.\n- An empty line should not exist between a Kdoc and the code it is describing. You do not need to add a blank line before the first comment in a particular namespace (code block) (for example, between the function declaration and first comment in a function body).\n\n**Valid Examples:**\n\n```kotlin\n/**\n * This is the short overview comment for the example interface.\n *\n * @since 1.6\n */\n public interface Example {\n    // Some comments  /* Since it is the first member definition in this code block, there is no need to add a blank line here */\n    val aField: String = ...\n                     /* Add a blank line above the comment */\n    // Some comments\n    val bField: String = ...\n                      /* Add a blank line above the comment */\n    /**\n     * This is a long comment with whitespace that should be split in\n     * multiple line comments in case the line comment formatting is enabled.\n     *                /* blank line between description and Kdoc tag */\n     * @param fox A quick brown fox jumps over the lazy dog\n     * @return the rounds of battle of fox and dog\n     */\n    fun foo(Fox fox)\n                      /* Add a blank line above the comment */\n     /**\n      * These possibilities include: Formatting of header comments\n      *\n      * @return the rounds of battle of fox and dog\n      * @throws ProblemException if lazy dog wins\n      */\n    fun bar() throws ProblemException {\n        // Some comments  /* Since it is the first member definition in this range, there is no need to add a blank line here */\n        var aVar = ...\n\n        // Some comments  /* Add a blank line above the comment */\n        fun doSome()\n    }\n }\n```\n\n- Leave one single space between the comment on the right side of the code and the code.\n  If you use conditional comments in the `if-else-if` scenario, put the comments inside the `else-if` branch or in the conditional block, but not before the `else-if`. This makes the code more understandable.\n  When the if-block is used with curly braces, the comment should be placed on the next line after opening the curly braces.\n  Compared to Java, the `if` statement in Kotlin statements returns a value. For this reason, a comment block can describe a whole `if-statement`.\n\n**Valid examples:**\n\n```kotlin\n\nval foo = 100  // right-side comment\nval bar = 200  /* right-side comment */\n\n// general comment for the value and whole if-else condition\nval someVal = if (nr % 15 == 0) {\n    // when nr is a multiple of both 3 and 5\n    println(\"fizzbuzz\")\n} else if (nr % 3 == 0) {\n    // when nr is a multiple of 3, but not 5\n    // We print \"fizz\", only.\n    println(\"fizz\")\n} else if (nr % 5 == 0) {\n    // when nr is a multiple of 5, but not 3\n    // we print \"buzz\" only.\n    println(\"buzz\")\n} else {\n    // otherwise, we print the number.\n    println(x)\n}\n```\n\n- Start all comments (including KDoc) with a space after the first symbol (`//`, `/*`, `/**` and `*`)\n\n**Valid example:**\n\n```kotlin\nval x = 0  // this is a comment\n```\n\n#### \u003ca name=\"r2.4.2\"\u003e\u003c/a\u003e 2.4.2 Do not comment on unused code blocks\n\nDo not comment on unused code blocks, including imports. Delete these code blocks immediately.\nA code is not used to store history. Git, svn, or other VCS tools should be used for this purpose.\nUnused imports increase the coupling of the code and are not conducive to maintenance. The commented out code cannot be appropriately maintained.\nIn an attempt to reuse the code, there is a high probability that you will introduce defects that are easily missed.\nThe correct approach is to delete the unnecessary code directly and immediately when it is not used anymore.\nIf you need the code again, consider porting or rewriting it as changes could have occurred since you first commented on the code.\n\n#### \u003ca name=\"r2.4.3\"\u003e\u003c/a\u003e2.4.3 Code delivered to the client should not contain TODO/FIXME comments\n\nThe code officially delivered to the client typically should not contain TODO/FIXME comments.\n`TODO` comments are typically used to describe modification points that need to be improved and added. For example, refactoring FIXME comments are typically used to describe known defects and bugs that will be subsequently fixed and are not critical for an application.\nThey should all have a unified style to facilitate unified text search processing.\n\n**Example:**\n\n```kotlin\n// TODO(\u003cauthor-name\u003e): Jira-XXX - support new json format\n// FIXME: Jira-XXX - fix NPE in this code block\n```\n\nAt a version development stage, these annotations can be used to highlight the issues in the code, but all of them should be fixed before a new product version is released.\n# \u003ca name=\"c3\"\u003e\u003c/a\u003e3. General formatting (typesetting)\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.1\"\u003e\u003c/a\u003e 3.1 File-related rules\nThis section describes the rules related to using files in your code.\n#### \u003ca name=\"r3.1.1\"\u003e\u003c/a\u003e 3.1.1 Avoid files that are too long\n\nIf the file is too long and complicated, it should be split into smaller files, functions, or modules. Files should not exceed 2000 lines (non-empty and non-commented lines).\nIt is recommended to horizontally or vertically split the file according to responsibilities or hierarchy of its parts.\nThe only exception to this rule is code generation - the auto-generated files that are not manually modified can be longer.\n\n#### \u003ca name=\"r3.1.2\"\u003e\u003c/a\u003e 3.1.2 Code blocks in the source file should be separated by one blank line\nA source file contains code blocks in the following order: copyright, package name, imports, and top-level classes. They should be separated by one blank line.\n\na) Code blocks should be in the following order:\n1.\tKdoc for licensed or copyrighted files\n2.\t`@file` annotation\n3.\tPackage name\n4.\tImport statements\n5.\tTop-class header and top-function header comments\n6.\tTop-level classes or functions\n\nb) Each of the preceding code blocks should be separated by a blank line.\n\nc) Import statements are alphabetically arranged, without using line breaks and wildcards ( wildcard imports - `*`).\n\nd) **Recommendation**: One `.kt` source file should contain only one class declaration, and its name should match the filename\n\ne) Avoid empty files that do not contain the code or contain only imports/comments/package name\n\nf) Unused imports should be removed\n#### \u003ca name=\"r3.1.3\"\u003e\u003c/a\u003e 3.1.3 Import statements order\n\nFrom top to bottom, the order is the following:\n1. Android\n2. Imports of packages used internally in your organization\n3. Imports from other non-core dependencies\n4. Java core packages\n5. kotlin stdlib\n\nEach category should be alphabetically arranged. Each group should be separated by a blank line. This style is compatible with  [Android import order](https://source.android.com/setup/contribute/code-style#order-import-statements).\n\n**Valid example**:\n```kotlin\nimport android.* // android\nimport androidx.* // android\nimport com.android.* // android\n\nimport com.your.company.* // your company's libs\nimport your.company.* // your company's libs\n\nimport com.fasterxml.jackson.databind.ObjectMapper // other third-party dependencies\nimport org.junit.jupiter.api.Assertions\n\nimport java.io.IOException // java core packages\nimport java.net.URL\n\nimport kotlin.system.exitProcess  // kotlin standard library\nimport kotlinx.coroutines.*  // official kotlin extension library\n```\n\n#### \u003ca name=\"r3.1.4\"\u003e\u003c/a\u003e 3.1.4 Order of declaration parts of class-like code structures\nThe declaration parts of class-like code structures (class, interface, etc.) should be in the following order: compile-time constants (for objects), class properties, late-init class properties, init-blocks, constructors, public methods, internal methods, protected methods, private methods, and companion object. Blank lines should separate their declaration.\nNotes:\n1.\tThere should be no blank lines between properties with the following **exceptions**: when there is a comment before a property on a separate line or annotations on a separate line.\n2.\tProperties with comments/Kdoc should be separated by a newline before the comment/Kdoc.\n3.\tEnum entries and constant properties (`const val`) in companion objects should be alphabetically arranged.\n\nThe declaration part of a class or interface should be in the following order:\n- Compile-time constants (for objects)\n- Properties\n- Late-init class properties\n- Init-blocks\n- Constructors\n- Methods or nested classes. Put nested classes next to the code they are used by.\n  If the classes are meant to be used externally, and are not referenced inside the class, put them after the companion object.\n- Companion object\n\n**Exception:**\nAll variants of a `private val` logger should be placed at the beginning of the class (`private val log`, `LOG`, `logger`, etc.).\n\n#### \u003ca name=\"r3.1.5\"\u003e\u003c/a\u003e 3.1.5 Order of declaration of top-level code structures\nKotlin allows several top-level declaration types: classes, objects, interfaces, properties and functions.\nWhen 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.\nWhen declaring top-level structures, keep the following order:\n1. Top-level constants and properties (following same order as properties inside a class: `const val`,`val`, `lateinit var`, `var`)\n2. typealiases (grouped by their visibility modifiers)\n2. Interfaces, classes and objects (grouped by their visibility modifiers)\n3. Extension functions\n4. Other functions\n\n**Note**:\nExtension functions shouldn't have receivers declared in the same file according to [rule 6.2.3](#r6.2.3)\n\nValid example:\n```kotlin\npackage com.saveourtool.diktat.example\n\nconst val CONSTANT = 42\n\nval topLevelProperty = \"String constant\"\n\ninternal typealias ExamplesHandler = (IExample) -\u003e Unit\n\ninterface IExample\n\nclass Example : IExample\n\nprivate class Internal\n\nfun Other.asExample(): Example { /* ... */ }\n\nprivate fun Other.asInternal(): Internal { /* ... */ }\n\nfun doStuff() { /* ... */ }\n```\n\n**Note**:\nkotlin scripts (.kts) allow arbitrary code to be placed on the top level. When writing kotlin scripts, you should first declare all properties, classes\nand functions. Only then you should execute functions on top level. It is still recommended wrapping logic inside functions and avoid using top-level statements\nfor function calls or wrapping blocks of code in top-level scope functions like `run`.\n\nExample:\n```kotlin\n/* class declarations */\n/* function declarations */\nrun {\n    // call functions here\n}\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.2\"\u003e\u003c/a\u003e 3.2 Braces\nThis section describes the general rules of using braces in your code.\n#### \u003ca name=\"r3.2.1\"\u003e\u003c/a\u003e 3.2.1 Using braces in conditional statements and loop blocks\n\nBraces should always be used in `if`, `else`, `for`, `do`, and `while` statements, even if the program body is empty or contains only one statement. In special Kotlin `when` statements, you do not need to use braces for single-line statements.\n\n**Valid example:**\n\n```kotlin\nwhen (node.elementType) {\n    FILE -\u003e {\n        checkTopLevelDoc(node)\n        checkSomething()\n     }\n    CLASS -\u003e checkClassElements(node)\n}\n```\n**Exception:** The only exception is ternary operator in Kotlin (a single line `if () \u003c\u003e else \u003c\u003e` )\n\n**Invalid example:**\n\n```kotlin\nval value = if (string.isEmpty())  // WRONG!\n                0\n            else\n                1\n```\n\n**Valid example**:\n\n```kotlin\nval value = if (string.isEmpty()) 0 else 1  // Okay\n```\n\n```kotlin\nif (condition) {\n    println(\"test\")\n} else {\n    println(0)\n}\n```\n\n#### \u003ca name=\"r3.2.2\"\u003e\u003c/a\u003e 3.2.2  Opening braces are placed at the end of the line in *non-empty* blocks and block structures\nFor *non-empty* blocks and block structures, the opening brace is placed at the end of the line.\nFollow the K\u0026R style (1TBS or OTBS) for *non-empty* code blocks with braces:\n- The opening brace and first line of the code block are on the same line.\n- The closing brace is on its own new line.\n- The closing brace can be followed by a newline character. The only exceptions are `else`, `finally`, and `while` (from `do-while` statement), or `catch` keywords.\n  These keywords should not be split from the closing brace by a newline character.\n\n**Exception cases**:\n\n1) For lambdas, there is no need to put a newline character after the first (function-related) opening brace. A newline character should appear only after an arrow (`-\u003e`) (see [point 5 of Rule 3.6.2](#r3.6.2)).\n\n```kotlin\narg.map { value -\u003e\n    foo(value)\n}\n```\n\n2) for `else`/`catch`/`finally`/`while` (from `do-while` statement) keywords closing brace should stay on the same line:\n ```kotlin\ndo {\n    if (true) {\n        x++\n    } else {\n        x--\n    }\n} while (x \u003e 0)\n```\n\n**Valid example:**\n\n ```kotlin\n        return arg.map { value -\u003e\n            while (condition()) {\n                method()\n            }\n            value\n        }\n\n        return MyClass() {\n            @Override\n              fun method() {\n                if (condition()) {\n                    try {\n                        something()\n                    } catch (e: ProblemException) {\n                        recover()\n                    }\n                } else if (otherCondition()) {\n                    somethingElse()\n                } else {\n                    lastThing()\n                }\n            }\n        }\n ```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.3\"\u003e\u003c/a\u003e 3.3 Indentation\n\nOnly spaces are permitted for indentation, and each indentation should equal `four spaces` (tabs are not permitted).\nIf you prefer using tabs, simply configure them to change to spaces in your IDE automatically.\nThese code blocks should be indented if they are placed on the new line, and the following conditions are met:\n-\tThe code block is placed immediately after an opening brace.\n-\tThe code block is placed after each operator, including the assignment operator (`+`/`-`/`\u0026\u0026`/`=`/etc.)\n-\tThe code block is a call chain of methods:\n```kotlin\nsomeObject\n    .map()\n    .filter()\n```\n-  The code block is placed immediately after the opening parenthesis.\n-  The code block is placed immediately after an arrow in lambda:\n\n ```kotlin\narg.map { value -\u003e\n    foo(value)\n}\n```\n\n**Exceptions**:\n1.\tArgument lists: \\\n      a) Eight spaces are used to indent argument lists (both in declarations and at call sites). \\\n      b) Arguments in argument lists can be aligned if they are on different lines.\n\n2.\tEight spaces are used if there is a newline after any binary operator.\n\n3.\tEight spaces are used for functional-like styles when the newline is placed before the dot.\n\n4.\tSupertype lists: \\\n      a) Four spaces are used if the colon before the supertype list is on a new line. \\\n      b) Four spaces are used before each supertype, and eight spaces are used if the colon is on a new line.\n\n**Note:** there should be an indentation after all statements such as `if`, `for`, etc. However, according to this code style, such statements require braces.\n\n```kotlin\nif (condition)\n    foo()\n```\n\n**Exceptions**:\n- When breaking the parameter list of a method/class constructor, it can be aligned with `8 spaces`. A parameter that was moved to a new line can be on the same level as the previous argument:\n\n```kotlin\nfun visit(\n        node: ASTNode,\n        autoCorrect: Boolean,\n        params: KtLint.ExperimentalParams,\n        emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -\u003e Unit\n) {\n}\n```\n\n- Such operators as `+`/`-`/`*` can be indented with `8 spaces`:\n\n```kotlin\nval abcdef = \"my splitted\" +\n                \" string\"\n```\n\n- Opening and closing quotes in multiline string should have same indentation\n\n```kotlin\nlintMethod(\n            \"\"\"\n                    |val q = 1\n                    |\n            \"\"\".trimMargin()\n    )\n```\n\n- A list of supertypes should be indented with `4 spaces` if they are on different lines or with `8 spaces` if the leading colon is also on a separate line\n\n```kotlin\nclass A :\n    B()\n\nclass A\n    :\n        B()\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.4\"\u003e\u003c/a\u003e 3.4 Empty blocks\n\nAvoid 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.)\n\nGenerally, empty code blocks are prohibited; using them is considered a bad practice (especially for catch block).\nThey 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.\n```kotlin\noverride fun foo() {\n}\n```\n\n**Valid examples** (note once again that generally empty blocks are prohibited):\n\n```kotlin\nfun doNothing() {}\n\nfun doNothingElse() {\n}\n\nfun foo(bar: () -\u003e Unit = {})\n```\n\n**Invalid examples:**\n```kotlin\ntry {\n  doSomething()\n} catch (e: Some) {}\n```\n\nUse the following valid code instead:\n```kotlin\ntry {\n   doSomething()\n} catch (e: Some) {\n}\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.5\"\u003e\u003c/a\u003e 3.5 Line length\n\nLine length should be less than 120 symbols. Otherwise, it should be split.\n\nIf `complex property` initializing is too long, It should be split into priorities: \\\n1. Logic Binary Expression (\u0026\u0026  ||) \\\n2. Comparison Binary Expression (\u003e \u003c == \u003e= \u003c= !=) \\\n3. Other types (Arithmetical and Bit operation) (+ - * / % \u003e\u003e \u003c\u003c *= += -= /= %= ++ -- ! in !in etc)\n\n**Invalid example:**\n```kotlin\nval complexProperty = 1 + 2 + 3 + 4\n```\n**Valid example:**\n```kotlin\nval complexProperty = 1 + 2 +\n    3 + 4\n```\n\n**Invalid example:**\n```kotlin\nval complexProperty = (1 + 2 + 3 \u003e 0) \u0026\u0026 ( 23 * 4 \u003e 10 * 6)\n```\n**Valid example:**\n```kotlin\nval complexProperty = (1 + 2 + 3 \u003e 0) \u0026\u0026\n    (23 * 4 \u003e 10 * 6)\n```\n\nIf long line should be split in `Elvis Operator` (?:), it`s done like this\n\n**Invalid example:**\n```kotlin\nval value = first ?: second\n```\n**Valid example:**\n```kotlin\nval value = first\n    ?: second\n```\n\nIf long line in `Dot Qualified Expression` or `Safe Access Expression`, it`s done like this:\n\n**Invalid example:**\n```kotlin\nval value = This.Is.Very.Long.Dot.Qualified.Expression\n```\n**Valid example:**\n```kotlin\nval value = This.Is.Very.Long\n    .Dot.Qualified.Expression\n```\n\n**Invalid example:**\n```kotlin\nval value = This.Is?.Very?.Long?.Safe?.Access?.Expression\n```\n**Valid example:**\n```kotlin\nval value = This.Is?.Very?.Long\n    ?.Safe?.Access?.Expression\n```\n\nif `value arguments list` is too long, it also should be split:\n\n**Invalid example:**\n```kotlin\nval result1 = ManyParamInFunction(firstArgument, secondArgument, thirdArgument, fourthArgument, fifthArguments)\n```\n**Valid example:**\n```kotlin\nval result1 = ManyParamInFunction(firstArgument,\n secondArgument, thirdArgument, fourthArgument,\n fifthArguments)\n```\n\nIf `annotation` is too long, it also should be split:\n\n**Invalid example:**\n```kotlin\n@Query(value = \"select * from table where age = 10\", nativeQuery = true)\nfun foo() {}\n```\n**Valid example:**\n```kotlin\n@Query(\n    value = \"select * from table where age = 10\",\n    nativeQuery = true)\nfun foo() {}\n```\n\nLong one line `function` should be split:\n\n**Invalid example:**\n```kotlin\nfun foo() = goo().write(\"TooLong\")\n```\n**Valid example:**\n```kotlin\nfun foo() =\n    goo().write(\"TooLong\")\n```\n\nLong `binary expression` should be split into priorities: \\\n1. Logic Binary Expression (**\u0026\u0026**  **||**) \\\n2. Comparison Binary Expression (**\u003e** **\u003c** **==** **\u003e=** **\u003c=** **!=**) \\\n3. Other types (Arithmetical and Bit operation) (**+** **-** * **/** **%** **\u003e\u003e** **\u003c\u003c** **/*=** **+=** **-=** **/=** **%=** **++** **--** **!** **in** **!in** etc)\n\n**Invalid example:**\n```kotlin\nif (( x \u003e  100) || y \u003c 100 \u0026\u0026 !isFoo()) {}\n```\n\n**Valid example:**\n```kotlin\nif (( x \u003e  100) ||\n    y \u003c 100 \u0026\u0026 !isFoo()) {}\n```\n\n`String template` also can be split in white space in string text\n\n**Invalid example:**\n```kotlin\nval nameString = \"This is very long string template\"\n```\n\n**Valid example:**\n```kotlin\nval nameString = \"This is very long\" +\n        \" string template\"\n```\n\nLong `Lambda argument` should be split:\n\n**Invalid example:**\n```kotlin\nval variable = a?.filter { it.elementType == true } ?: null\n```\n\n**Valid example:**\n```kotlin\nval variable = a?.filter {\n    it.elementType == true\n} ?: null\n```\n\nLong one line `When Entry` should be split:\n\n**Invalid example:**\n```kotlin\nwhen(elem) {\n    true -\u003e long.argument.whenEntry\n}\n```\n**Valid example:**\n```kotlin\nwhen(elem) {\n    true -\u003e {\n        long.argument.whenEntry\n    }\n}\n```\n\nIf the examples above do not fit, but the line needs to be split and this in `property`, this is fixed like thisЖ\n\n**Invalid example:**\n```kotlin\nval element = veryLongNameFunction(firstParam)\n```\n**Valid example:**\n```kotlin\nval element =\n    varyLongNameFunction(firstParam)\n```\n\n`Eol comment` also can be split, but it depends on comment location.\nIf this comment is on the same line with code it should be on line before:\n\n**Invalid example:**\n```kotlin\nfun foo() {\n    val name = \"Nick\" // this comment is too long\n}\n```\n**Valid example:**\n```kotlin\nfun foo() {\n    // this comment is too long\n    val name = \"Nick\"\n}\n```\n\nBut if this comment is on new line - it should be split to several lines:\n\n**Invalid example:**\n```kotlin\n// This comment is too long. It should be on two lines.\nfun foo() {}\n```\n\n**Valid example:**\n```kotlin\n// This comment is too long.\n// It should be on two lines.\nfun foo() {}\n```\n\nThe international code style prohibits `non-Latin` (`non-ASCII`) symbols. (See [Identifiers](#r1.1.1)) However, if you still intend on using them, follow\nthe following convention:\n\n- One wide character occupies the width of two narrow characters.\n  The \"wide\" and \"narrow\" parts of a character are defined by its [east Asian width Unicode attribute](https://unicode.org/reports/tr11/).\n  Typically, narrow characters are also called \"half-width\" characters.\n  All characters in the ASCII character set include letters (such as `a, A`), numbers (such as `0, 3`), and punctuation spaces (such as `,` , `{`), all of which are narrow characters.\n  Wide characters are also called \"full-width\" characters. Chinese characters (such as `中, 文`), Chinese punctuation (`，` , `；` ), full-width letters and numbers (such as `Ａ、３`) are \"full-width\" characters.\n  Each one of these characters represents two narrow characters.\n\n- Any line that exceeds this limit (`120 narrow symbols`) should be wrapped, as described in the [Newline section](#c3.5).\n\n**Exceptions:**\n\n1.\tThe long URL or long JSON method reference in KDoc.\n2.\tThe `package` and `import` statements.\n3.\tThe command line in the comment, enabling it to be cut and pasted into the shell for use.\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.6\"\u003e\u003c/a\u003e 3.6 Line breaks (newlines)\nThis section contains the rules and recommendations on using line breaks.\n#### \u003ca name=\"r3.6.1\"\u003e\u003c/a\u003e 3.6.1 Each line can have a maximum of one statement\nEach line can have a maximum of one code statement. This recommendation prohibits the use of code with `;` because it decreases code visibility.\n\n**Invalid example:**\n```kotlin\nval a = \"\"; val b = \"\"\n```\n\n**Valid example:**\n```kotlin\nval a = \"\"\nval b = \"\"\n```\n\n#### \u003ca name=\"r3.6.2\"\u003e\u003c/a\u003e 3.6.2 Rules for line-breaking\n\n1) Unlike Java, Kotlin allows you not to put a semicolon (`;`) after each statement separated by a newline character.\n   There should be no redundant semicolon at the end of the lines.\n\nWhen a newline character is needed to split the line, it should be placed after such operators as `\u0026\u0026`/`||`/`+`/etc. and all infix functions (for example, `xor`).\nHowever, the newline character should be placed before operators such as `.`, `?.`, `?:`, and `::`.\n\nNote that all comparison operators, such as `==`, `\u003e`, `\u003c`, should not be split.\n\n**Invalid example**:\n```kotlin\n     if (node !=\n             null \u0026\u0026 test != null) {}\n```\n\n**Valid example**:\n```kotlin\n         if (node != null \u0026\u0026\n                 test != null) {\n         }\n```\n\n**Note:** You need to follow the functional style, meaning each function call in a chain with `.` should start at a new line if the chain of functions contains more than one call:\n```kotlin\n  val value = otherValue!!\n          .map { x -\u003e x }\n          .filter {\n              val a = true\n              true\n          }\n          .size\n```\n**Note:** The parser prohibits the separation of the `!!` operator from the value it is checking.\n\n**Exception**: If a functional chain is used inside the branches of a ternary operator, it does not need to be split with newlines.\n\n**Valid example**:\n```kotlin\nif (condition) list.map { foo(it) }.filter { bar(it) } else list.drop(1)\n```\n\n**Note:** If dot qualified expression is inside condition or passed as an argument - it should be replaced with new variable.\n\n**Invalid example**:\n```kotlin\n if (node.treeParent.treeParent?.treeParent.findChildByType(IDENTIFIER) != null) {}\n```\n\n**Valid example**:\n```kotlin\n        val grandIdentifier = node\n            .treeParent\n            .treeParent\n            ?.treeParent\n            .findChildByType(IDENTIFIER)\n        if (grandIdentifier != null) {}\n```\n**Second valid example**:\n```kotlin\n        val grandIdentifier = node.treeParent\n            .treeParent\n            ?.treeParent\n            .findChildByType(IDENTIFIER)\n        if (grandIdentifier != null) {}\n```\n\n2)\tNewlines should be placed after the assignment operator (`=`).\n3)\tIn function or class declarations, the name of a function or constructor should not be split by a newline from the opening brace `(`.\n      A brace should be placed immediately after the name without any spaces in declarations or at call sites.\n4)\tNewlines should be placed right after the comma (`,`).\n5)\tIf a lambda statement contains more than one line in its body, a newline should be placed after an arrow if the lambda statement has explicit parameters.\n      If it uses an implicit parameter (`it`), the newline character should be placed after the opening brace (`{`).\n      The following examples illustrate this rule:\n\n\n**Invalid example:**\n```kotlin\n    value.map { name -\u003e foo()\n        bar()\n    }\n```\n\n**Valid example:**\n```kotlin\nvalue.map { name -\u003e\n    foo()\n    bar()\n}\n\nval someValue = { node:String -\u003e node }\n```\n\n6) When the function contains only a single expression, it can be written as [expression function](https://kotlinlang.org/docs/reference/functions.html#single-expression-functions).\n   The below example shows the style that should not be used.\n\nInstead of:\n```kotlin\noverride fun toString(): String { return \"hi\" }\n```\nuse:\n```kotlin\noverride fun toString() = \"hi\"\n```\n\n7)  If an argument list in a function declaration (including constructors) or function call contains more than two arguments, these arguments should be split by newlines in the following style.\n\n**Valid example:**\n ```kotlin\nclass Foo(val a: String,\n          b: String,\n          val c: String) {\n}\n\nfun foo(\n        a: String,\n        b: String,\n        c: String\n) {\n\n}\n ```\n\nIf 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.\nOtherwise, there should be a line break after an opening parenthesis.\n\nKotlin 1.4 introduced a trailing comma as an optional feature, so it is generally recommended to place all parameters on a separate line\nand append [trailing comma](https://kotlinlang.org/docs/reference/whatsnew14.html#trailing-comma).\nIt makes the resolving of merge conflicts easier.\n\n**Valid example:**\n ```kotlin\nfun foo(\n        a: String,\n        b: String,\n) {\n\n}\n ```\n\nsame should be done for function calls/constructor arguments/e.t.c\n\nKotlin supports trailing commas in the following cases:\n\nEnumerations\nValue arguments\nClass properties and parameters\nFunction value parameters\nParameters with optional type (including setters)\nIndexing suffix\nLambda parameters\nwhen entry\nCollection literals (in annotations)\nType arguments\nType parameters\nDestructuring declarations\n\n8) If the supertype list has more than two elements, they should be separated by newlines.\n\n**Valid example:**\n```kotlin\nclass MyFavouriteVeryLongClassHolder :\n    MyLongHolder\u003cMyFavouriteVeryLongClass\u003e(),\n    SomeOtherInterface,\n    AndAnotherOne { }\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.7\"\u003e\u003c/a\u003e 3.7 Using blank lines\n\nReduce unnecessary blank lines and maintain a compact code size. By reducing unnecessary blank lines, you can display more code on one screen, which improves code readability.\n- Blank lines should separate content based on relevance and should be placed between groups of fields, constructors, methods, nested classes, `init` blocks, and objects (see [3.1.2](#r3.1.2)).\n- Do not use more than one line inside methods, type definitions, and initialization expressions.\n- Generally, do not use more than two consecutive blank lines in a row.\n- Do not put newlines in the beginning or end of code blocks with curly braces.\n\n**Valid example:**\n```kotlin\nfun baz() {\n\n    doSomething()  // No need to add blank lines at the beginning and end of the code block\n    // ...\n\n}\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.8\"\u003e\u003c/a\u003e 3.8 Horizontal space\nThis section describes general rules and recommendations for using spaces in the code.\n#### \u003ca name=\"r3.8.1\"\u003e\u003c/a\u003e 3.8.1: Usage of whitespace for code separation\n\nFollow the recommendations below for using space to separate keywords:\n\n**Note:** These recommendations are for cases where symbols are located on the same line. However, in some cases, a line break could be used instead of a space.\n\n1.  Separate keywords (such as `if`, `when`, `for`) from the opening parenthesis with single whitespace.\n    The only exception is the `constructor` keyword, which should not be separated from the opening parenthesis.\n\n2.  Separate keywords like `else` or `try` from the opening brace (`{`) with single whitespace.\n    If `else` is used in a ternary-style statement without braces, there should be a single space between `else` and the statement after: `if (condition) foo() else bar()`\n\n3.  Use a **single** whitespace before all opening braces (`{`). The only exception is the passing of a lambda as a parameter inside parentheses:\n ```kotlin\n     private fun foo(a: (Int) -\u003e Int, b: Int) {}\n     foo({x: Int -\u003e x}, 5) // no space before '{'\n ```\n\n4.  Single whitespace should be placed on both sides of binary operators. This also applies to operator-like symbols.\n    For example:\n\n- A colon in generic structures with the `where` keyword:  `where T : Type`\n- Arrow in lambdas: `(str: String) -\u003e str.length()`\n\n**Exceptions:**\n\n- Two colons (`::`) are written without spaces:\\\n  `Object::toString`\n- The dot separator (`.`) that stays on the same line with an object name:\\\n  `object.toString()`\n- Safe access modifiers `?.` and `!!` that stay on the same line with an object name:\\\n  `object?.toString()`\n- Operator `..` for creating ranges:\\\n  `1..100`\n\n5.  Use spaces after (`,`), (`:`), and (`;`), except when the symbol is at the end of the line.\n    However, note that this code style prohibits the use of (`;`) in the middle of a line ([see 3.3.2](#r3.2.2)).\n    There should be no whitespaces at the end of a line.\n    The only scenario where there should be no space after a colon is when the colon is used in the annotation to specify a use-site target (for example, `@param:JsonProperty`).\n    There should be no spaces before `,` , `:` and `;`.\n\n    **Exceptions** for spaces and colons:\n\n    - When `:` is used to separate a type and a supertype, including an anonymous object (after object keyword)\n    - When delegating to a superclass constructor or different constructor of the same class\n\n**Valid example:**\n```kotlin\n  abstract class Foo\u003cout T : Any\u003e : IFoo { }\n\n  class FooImpl : Foo() {\n      constructor(x: String) : this(x) { /*...*/ }\n\n      val x = object : IFoo { /*...*/ }\n  }\n```\n\n6. There should be *only one space* between the identifier and its type: `list: List\u003cString\u003e`\n   If the type is nullable, there should be no space before `?`.\n\n7. When using `[]` operator (`get/set`) there should be **no** spaces between identifier and `[` : `someList[0]`.\n\n8. There should be no space between a method or constructor name (both at declaration and at call site) and a parenthesis:\n   `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).\n   This rule does not prohibit, for example, the following code:\n```kotlin\nfun foo\n(\n    a: String\n)\n```\n\n9. Never put a space after `(`, `[`, `\u003c` (when used as a bracket in templates) or before `)`, `]`, `\u003e` (when used as a bracket in templates).\n\n10. There should be no spaces between a prefix/postfix operator (like `!!` or `++`) and its operand.\n\n#### \u003ca name=\"r3.8.2\"\u003e\u003c/a\u003e 3.8.2: No spaces for horizontal alignment\n\n*Horizontal alignment* refers to aligning code blocks by adding space to the code. Horizontal alignment should not be used because:\n\n- When modifying code, it takes much time for new developers to format, support, and fix alignment issues.\n- Long identifier names will break the alignment and lead to less presentable code.\n- There are more disadvantages than advantages in alignment. To reduce maintenance costs, misalignment (???) is the best choice.\n\nRecommendation: Alignment only looks suitable for `enum class`, where it can be used in table format to improve code readability:\n```kotlin\nenum class Warnings(private val id: Int, private val canBeAutoCorrected: Boolean, private val warn: String) : Rule {\n    PACKAGE_NAME_MISSING         (1, true,  \"no package name declared in a file\"),\n    PACKAGE_NAME_INCORRECT_CASE  (2, true,  \"package name should be completely in a lower case\"),\n    PACKAGE_NAME_INCORRECT_PREFIX(3, false, \"package name should start from the company's domain\")\n    ;\n}\n```\n\n**Valid example:**\n ```kotlin\n private val nr: Int // no alignment, but looks fine\n private var color: Color // no alignment\n ```\n\n**Invalid example**:\n ```kotlin\n private val    nr: Int    // aligned comment with extra spaces\n private val color: Color  // alignment for a comment and alignment for identifier name\n ```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.9\"\u003e\u003c/a\u003e 3.9 Enumerations\nEnum values are separated by a comma and line break, with ';' placed on the new line.\n\n1) The comma and line break characters separate enum values. Put `;` on the new line:\n```kotlin\nenum class Warnings {\n    A,\n    B,\n    C,\n    ;\n}\n```\n\nThis will help to resolve conflicts and reduce the number of conflicts during merging pull requests.\nAlso, use [trailing comma](https://kotlinlang.org/docs/reference/whatsnew14.html#trailing-comma).\n\n2) If the enum is simple (no properties, methods, and comments inside), you can declare it in a single line:\n```kotlin\nenum class Suit { CLUBS, HEARTS, SPADES, DIAMONDS }\n```\n\n3) Enum classes take preference (if it is possible to use it). For example, instead of two boolean properties:\n\n```kotlin\nval isCelsius = true\nval isFahrenheit = false\n```\n\nuse enum class:\n\n```kotlin\nenum class TemperatureScale { CELSIUS, FAHRENHEIT }\n```\n\n- The variable value only changes within a fixed range and is defined with the enum type.\n- Avoid comparison with magic numbers of `-1, 0, and 1`; use enums instead.\n\n```kotlin\nenum class ComparisonResult {\n    ORDERED_ASCENDING,\n    ORDERED_SAME,\n    ORDERED_DESCENDING,\n    ;\n}\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.10\"\u003e\u003c/a\u003e 3.10 Variable declaration\nThis section describes rules for the declaration of variables.\n#### \u003ca name=\"r3.10.1\"\u003e\u003c/a\u003e 3.10.1 Declare one variable per line\n\nEach property or variable must be declared on a separate line.\n\n**Invalid example**:\n```kotlin\nval n1: Int; val n2: Int\n```\n\n#### \u003ca name=\"r3.10.2\"\u003e\u003c/a\u003e 3.10.2 Variables should be declared near the line where they are first used\nDeclare local variables close to the point where they are first used to minimize their scope. This will also increase the readability of the code.\nLocal variables are usually initialized during their declaration or immediately after.\nThe member fields of the class should be declared collectively (see [Rule 3.1.2](#r3.1.2) for details on the class structure).\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.11\"\u003e\u003c/a\u003e 3.11 'When' expression\n\nThe `when` statement must have an 'else' branch unless the condition variable is enumerated or a sealed type.\nEach `when` statement should contain an `else` statement group, even if it does not contain any code.\n\n**Exception:** If 'when' statement of the `enum or sealed` type contains all enum values, there is no need to have an \"else\" branch.\nThe compiler can issue a warning when it is missing.\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.12\"\u003e\u003c/a\u003e 3.12 Annotations\n\nEach annotation applied to a class, method or constructor should be placed on its own line. Consider the following examples:\n1. Annotations applied to the class, method or constructor are placed on separate lines (one annotation per line).\n\n**Valid example**:\n```kotlin\n@MustBeDocumented\n@CustomAnnotation\nfun getNameIfPresent() { /* ... */ }\n```\n\n2. A single annotation should be on the same line as the code it is annotating.\n\n**Valid example**:\n```kotlin\n@CustomAnnotation class Foo {}\n```\n\n3. Multiple annotations applied to a field or property can appear on the same line as the corresponding field.\n\n**Valid example**:\n```kotlin\n@MustBeDocumented @CustomAnnotation val loader: DataLoader\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.13\"\u003e\u003c/a\u003e 3.13 Block comments\n\nBlock comments should be placed at the same indentation level as the surrounding code. See examples below.\n\n**Valid example**:\n\n ```kotlin\nclass SomeClass {\n     /*\n      * This is\n      * okay\n      */\n      fun foo() {}\n}\n ```\n\n**Note**: Use `/*...*/` block comments to enable automatic formatting by IDEs.\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.14\"\u003e\u003c/a\u003e 3.14 Modifiers and constant values\nThis section contains recommendations regarding modifiers and constant values.\n#### \u003ca name=\"r3.14.1\"\u003e\u003c/a\u003e 3.14.1 Declaration with multiple modifiers\nIf a declaration has multiple modifiers, always follow the proper sequence.\n**Valid sequence:**\n\n```kotlin\npublic / internal / protected / private\nexpect / actual\nfinal / open / abstract / sealed / const\nexternal\noverride\nlateinit\ntailrec\ncrossinline\nvararg\nsuspend\ninner\nout\nenum / annotation\ncompanion\ninline / noinline\nreified\ninfix\noperator\ndata\n```\n\n#### \u003ca name=\"r3.14.2\"\u003e\u003c/a\u003e 3.14.2: Separate long numerical values with an underscore\nAn underscore character should separate long numerical values.\n**Note:** Using underscores simplifies reading and helps to find errors in numeric constants.\n```kotlin\nval oneMillion = 1_000_000\nval creditCardNumber = 1234_5678_9012_3456L\nval socialSecurityNumber = 999_99_9999L\nval hexBytes = 0xFF_EC_DE_5E\nval bytes = 0b11010010_01101001_10010100_10010010\n```\n#### \u003ca name=\"r3.14.3\"\u003e\u003c/a\u003e 3.14.3: Magic number\nPrefer defining constants with clear names describing what the magic number means.\n**Valid example**:\n```kotlin\nclass Person() {\n    fun isAdult(age: Int): Boolean = age \u003e= majority\n\n    companion object {\n        private const val majority = 18\n    }\n}\n```\n**Invalid example**:\n```kotlin\nclass Person() {\n    fun isAdult(age: Int): Boolean = age \u003e= 18\n}\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.15\"\u003e\u003c/a\u003e 3.15 Strings\nThis section describes the general rules of using strings.\n\n#### \u003ca name=\"r3.15.1\"\u003e\u003c/a\u003e 3.15.1 Concatenation of Strings\nString concatenation is prohibited if the string can fit on one line. Use raw strings and string templates instead. Kotlin has significantly improved the use of Strings:\n[String templates](https://kotlinlang.org/docs/reference/basic-types.html#string-templates), [Raw strings](https://kotlinlang.org/docs/reference/basic-types.html#string-literals).\nTherefore, compared to using explicit concatenation, code looks much better when proper Kotlin strings are used for short lines, and you do not need to split them with newline characters.\n\n**Invalid example**:\n```kotlin\nval myStr = \"Super string\"\nval value = myStr + \" concatenated\"\n```\n\n**Valid example**:\n```kotlin\nval myStr = \"Super string\"\nval value = \"$myStr concatenated\"\n```\n\n#### \u003ca name=\"r3.15.2\"\u003e\u003c/a\u003e 3.15.2 String template format\n**Redundant curly braces in string templates**\n\nIf there is only one variable in a string template, there is no need to use such a template. Use this variable directly.\n**Invalid example**:\n```kotlin\nval someString = \"${myArgument} ${myArgument.foo()}\"\n```\n\n**Valid example**:\n```kotlin\nval someString = \"$myArgument ${myArgument.foo()}\"\n```\n\n**Redundant string template**\n\nIn case a string template contains only one variable - there is no need to use the string template. Use this variable directly.\n\n**Invalid example**:\n```kotlin\nval someString = \"$myArgument\"\n```\n\n**Valid example**:\n```kotlin\nval someString = myArgument\n```\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c3.16\"\u003e\u003c/a\u003e 3.16 Conditional Statements\nThis section describes the general rules related to the сonditional statements.\n\n#### \u003ca name=\"r3.16.1\"\u003e\u003c/a\u003e 3.16.1 Collapsing redundant nested if-statements\nThe nested if-statements, when possible, should be collapsed into a single one\nby concatenating their conditions with the infix operator \u0026\u0026.\n\nThis improves the readability by reducing the number of the nested language constructs.\n\n#### Simple collapse\n\n**Invalid example**:\n```kotlin\nif (cond1) {\n    if (cond2) {\n        doSomething()\n    }\n}\n```\n\n**Valid example**:\n```kotlin\nif (cond1 \u0026\u0026 cond2) {\n    doSomething()\n}\n```\n\n#### Compound conditions\n\n**Invalid example**:\n```kotlin\nif (cond1) {\n    if (cond2 || cond3) {\n        doSomething()\n    }\n}\n```\n\n**Valid example**:\n```kotlin\nif (cond1 \u0026\u0026 (cond2 || cond3)) {\n    doSomething()\n}\n```\n#### \u003ca name=\"r3.16.2\"\u003e\u003c/a\u003e 3.16.2 Too complex conditions\nToo complex conditions should be simplified according to boolean algebra rules, if it is possible.\nThe following rules are considered when simplifying an expression:\n* boolean literals are removed (e.g. `foo() || false` -\u003e `foo()`)\n* double negation is removed (e.g. `!(!a)` -\u003e `a`)\n* expression with the same variable are simplified (e.g. `a \u0026\u0026 b \u0026\u0026 a` -\u003e `a \u0026\u0026 b`)\n* remove expression from disjunction, if they are subset of other expression (e.g. `a || (a \u0026\u0026 b)` -\u003e `a`)\n* remove expression from conjunction, if they are more broad than other expression (e.g. `a \u0026\u0026 (a || b)` -\u003e `a`)\n* de Morgan's rule (negation is moved inside parentheses, i.e. `!(a || b)` -\u003e `!a \u0026\u0026 !b`)\n\n**Valid example**\n```kotlin\nif (condition1 \u0026\u0026 condition2) {\n    foo()\n}\n```\n\n**Invalid example**\n```kotlin\nif (condition1 \u0026\u0026 condition2 \u0026\u0026 condition1) {\n    foo()\n}\n```\n# \u003ca name=\"c4\"\u003e\u003c/a\u003e 4. Variables and types\nThis section is dedicated to the rules and recommendations for using variables and types in your code.\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c4.1\"\u003e\u003c/a\u003e 4.1 Variables\nThe rules of using variables are explained in the below topics.\n#### \u003ca name=\"r4.1.1\"\u003e\u003c/a\u003e 4.1.1 Do not use Float and Double types when accurate calculations are needed\nFloating-point numbers provide a good approximation over a wide range of values, but they cannot produce accurate results in some cases.\nBinary floating-point numbers are unsuitable for precise calculations because it is impossible to represent 0.1 or any other negative power of 10 in a `binary representation` with a finite length.\n\nThe following code example seems to be obvious:\n```kotlin\n    val myValue = 2.0 - 1.1\n    println(myValue)\n```\n\nHowever, it will print the following value: `0.8999999999999999`\n\nTherefore, for precise calculations (for example, in finance or exact sciences), using such types as `Int`, `Long`, `BigDecimal`are recommended.\nThe `BigDecimal` type should serve as a good choice.\n\n**Invalid example**:\nFloat values containing more than six or seven decimal numbers will be rounded.\n ```kotlin\n val eFloat = 2.7182818284f // Float, will be rounded to 2.7182817\n ```\n\n**Valid example**: (when precise calculations are needed):\n ```kotlin\n    val income = BigDecimal(\"2.0\")\n    val expense = BigDecimal(\"1.1\")\n    println(income.subtract(expense)) // you will obtain 0.9 here\n ```\n\n#### \u003ca name=\"r4.1.2\"\u003e\u003c/a\u003e 4.1.2: Comparing numeric float type values\nNumeric float type values should not be directly compared with the equality operator (==) or other methods, such as `compareTo()` and `equals()`. Since floating-point numbers involve precision problems in computer representation, it is better to use `BigDecimal` as recommended in [Rule 4.1.1](#r4.1.1) to make accurate computations and comparisons. The following code describes these problems.\n\n**Invalid example**:\n ```kotlin\nval f1 = 1.0f - 0.9f\nval f2 = 0.9f - 0.8f\nif (f1 == f2) {\n    println(\"Expected to enter here\")\n} else {\n    println(\"But this block will be reached\")\n}\n\nval flt1 = f1;\nval flt2 = f2;\nif (flt1.equals(flt2)) {\n    println(\"Expected to enter here\")\n} else {\n    println(\"But this block will be reached\")\n}\n ```\n\n**Valid example**:\n\n```kotlin\nval foo = 1.03f\nval bar = 0.42f\nif (abs(foo - bar) \u003e 1e-6f) {\n    println(\"Ok\")\n} else {\n    println(\"Not\")\n}\n```\n\n#### \u003ca name=\"r4.1.3\"\u003e\u003c/a\u003e 4.1.3 Try to use 'val' instead of 'var' for variable declaration [SAY_NO_TO_VAR]\n\nVariables with the `val` modifier are immutable (read-only).\nUsing `val` variables instead of `var` variables increases code robustness and readability.\nThis is because `var` variables can be reassigned several times in the business logic.\nHowever, in some scenarios with loops or accumulators, only `var`s are permitted.\n\n\u003c!-- =============================================================================== --\u003e\n### \u003ca name=\"c4.2\"\u003e\u003c/a\u003e 4.2 Types\nThis section provides recommendations for using types.\n#### \u003ca name=\"r4.2.1\"\u003e\u003c/a\u003e 4.2.1: Use Contracts and smart cast as much as possible\n\nThe Kotlin compiler has introduced [Smart Casts](https://kotlinlang.org/docs/reference/typecasts.html#smart-casts) that help reduce the size of code.\n\n**Invalid example**:\n```kotlin\n    if (x is String) {\n        print((x as String).length) // x was already automatically cast to String - no need to use 'as' keyword here\n    }\n```\n\n**Valid example**:\n```kotlin\n    if (x is String) {\n        print(x.length) // x was already automatically cast to String - no need to use 'as' keyword here\n    }\n```\n\nAlso, Kotlin 1.3 introduced [Contracts](https://kotlinlang.org/docs/reference/whatsnew13.html#contracts) that provide enhanced logic for smart-cast.\nContracts are ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaveourtool%2Fdiktat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaveourtool%2Fdiktat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaveourtool%2Fdiktat/lists"}