Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0380716
commit 745a45f
Showing
385 changed files
with
14,180 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
...les-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryBackticks.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package io.gitlab.arturbosch.detekt.rules.style | ||
|
||
import io.gitlab.arturbosch.detekt.api.CodeSmell | ||
import io.gitlab.arturbosch.detekt.api.Config | ||
import io.gitlab.arturbosch.detekt.api.Debt | ||
import io.gitlab.arturbosch.detekt.api.Entity | ||
import io.gitlab.arturbosch.detekt.api.Issue | ||
import io.gitlab.arturbosch.detekt.api.Rule | ||
import io.gitlab.arturbosch.detekt.api.Severity | ||
import org.jetbrains.kotlin.com.intellij.psi.PsiElement | ||
import org.jetbrains.kotlin.lexer.KtTokens | ||
import org.jetbrains.kotlin.psi.KtElement | ||
import org.jetbrains.kotlin.psi.KtSimpleNameStringTemplateEntry | ||
import org.jetbrains.kotlin.psi.psiUtil.allChildren | ||
import org.jetbrains.kotlin.psi.psiUtil.canPlaceAfterSimpleNameEntry | ||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType | ||
import org.jetbrains.kotlin.psi.psiUtil.isIdentifier | ||
|
||
/** | ||
* This rule reports unnecessary backticks. | ||
* | ||
* <noncompliant> | ||
* class `HelloWorld` | ||
* </noncompliant> | ||
* | ||
* <compliant> | ||
* class HelloWorld | ||
* </compliant> | ||
*/ | ||
class UnnecessaryBackticks(config: Config = Config.empty) : Rule(config) { | ||
override val issue: Issue = Issue( | ||
javaClass.simpleName, | ||
Severity.Style, | ||
"Backticks are unnecessary.", | ||
Debt.FIVE_MINS | ||
) | ||
|
||
override fun visitKtElement(element: KtElement) { | ||
element.allChildren | ||
.filter { it.node.elementType == KtTokens.IDENTIFIER && it.hasUnnecessaryBackticks() } | ||
.forEach { report(CodeSmell(issue, Entity.from(it), "Backticks are unnecessary.")) } | ||
super.visitKtElement(element) | ||
} | ||
|
||
@Suppress("ReturnCount") | ||
private fun PsiElement.hasUnnecessaryBackticks(): Boolean { | ||
val text = this.text | ||
if (!text.startsWith("`") || !text.endsWith("`")) return false | ||
|
||
val unquoted = text.drop(1).dropLast(1) | ||
if (!unquoted.isIdentifier() || unquoted.isKeyword()) return false | ||
|
||
val stringTemplateEntry = getStrictParentOfType<KtSimpleNameStringTemplateEntry>() | ||
return stringTemplateEntry == null || canPlaceAfterSimpleNameEntry(stringTemplateEntry.nextSibling) | ||
} | ||
|
||
private fun String.isKeyword() = this in KEYWORDS || this.all { it == '_' } | ||
|
||
companion object { | ||
private val KEYWORDS = | ||
(KtTokens.KEYWORDS.types + KtTokens.SOFT_KEYWORDS.types).map { it.toString() } + listOf("yield") | ||
} | ||
} |
140 changes: 140 additions & 0 deletions
140
...style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryBackticksSpec.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package io.gitlab.arturbosch.detekt.rules.style | ||
|
||
import io.gitlab.arturbosch.detekt.api.Config | ||
import io.gitlab.arturbosch.detekt.test.assertThat | ||
import io.gitlab.arturbosch.detekt.test.compileAndLint | ||
import io.gitlab.arturbosch.detekt.test.lint | ||
import org.junit.jupiter.api.Nested | ||
import org.junit.jupiter.api.Test | ||
|
||
class UnnecessaryBackticksSpec { | ||
val subject = UnnecessaryBackticks(Config.empty) | ||
|
||
@Nested | ||
inner class `Reports UnnecessaryInnerClass Rule` { | ||
@Test | ||
fun `class`() { | ||
val code = """ | ||
class `Foo` { | ||
val x: `Foo` = `Foo`() | ||
val y = ::`Foo` | ||
} | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(4) | ||
} | ||
|
||
@Test | ||
fun function() { | ||
val code = """ | ||
fun `foo`() = 1 | ||
val x = `foo`() | ||
val y = ::`foo` | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(3) | ||
} | ||
|
||
@Test | ||
fun property() { | ||
val code = """ | ||
val `foo` = "" | ||
val x = `foo` | ||
val y = ::`foo` | ||
val z = `foo`.length | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(4) | ||
} | ||
|
||
@Test | ||
fun import() { | ||
val code = """ | ||
import kotlin.`let` | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(1) | ||
} | ||
|
||
@Test | ||
fun `in string template`() { | ||
val code = """ | ||
val foo = "" | ||
val x = "${'$'}`foo`" | ||
val y = "${'$'}`foo` bar" | ||
val z = "${'$'}{`foo`}bar" | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(3) | ||
} | ||
} | ||
|
||
@Nested | ||
inner class `Does not report UnnecessaryInnerClass Rule` { | ||
@Test | ||
fun `class with spaces`() { | ||
val code = """ | ||
class `Foo Bar` | ||
val x: `Foo Bar` = `Foo Bar`() | ||
val y = ::`Foo Bar` | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(0) | ||
} | ||
|
||
@Test | ||
fun `function with spaces`() { | ||
val code = """ | ||
fun `foo bar`() = 1 | ||
val x = `foo bar`() | ||
val y = ::`foo bar` | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(0) | ||
} | ||
|
||
@Test | ||
fun `property with spaces`() { | ||
val code = """ | ||
val `foo bar` = "" | ||
val x = `foo bar` | ||
val y = ::`foo bar` | ||
val z = `foo bar`.length | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(0) | ||
} | ||
|
||
@Test | ||
fun keyword() { | ||
val code = """ | ||
val `is` = 1 | ||
val `fun` = 2 | ||
val `yield` = 3 | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).isEmpty() | ||
} | ||
|
||
@Test | ||
fun underscore() { | ||
val code = """ | ||
val `_` = 1 | ||
val `__` = 2 | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).isEmpty() | ||
} | ||
|
||
@Test | ||
fun import() { | ||
val code = """ | ||
package test | ||
import test.`Foo Bar` | ||
class `Foo Bar` | ||
""".trimIndent() | ||
assertThat(subject.lint(code)).hasSize(0) | ||
} | ||
|
||
@Test | ||
fun `in string template`() { | ||
val code = """ | ||
val foo = "" | ||
val x = "${'$'}`foo`bar" | ||
val `bar baz` = "" | ||
val y = "${'$'}`bar baz`" | ||
""".trimIndent() | ||
assertThat(subject.compileAndLint(code)).hasSize(0) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
--- | ||
title: Comments Rule Set | ||
sidebar: home_sidebar | ||
keywords: rules, comments | ||
permalink: comments.html | ||
toc: true | ||
folder: documentation | ||
--- | ||
This rule set provides rules that address issues in comments and documentation | ||
of the code. | ||
|
||
### AbsentOrWrongFileLicense | ||
|
||
This rule will report every Kotlin source file which doesn't have the required license header. | ||
The rule validates each Kotlin source and operates in two modes: if `licenseTemplateIsRegex = false` (or missing) | ||
the rule checks whether the input file header starts with the read text from the passed file in the | ||
`licenseTemplateFile` configuration option. If `licenseTemplateIsRegex = true` the rule matches the header with | ||
a regular expression produced from the passed template license file (defined via `licenseTemplateFile` configuration | ||
option). | ||
|
||
**Active by default**: No | ||
|
||
**Debt**: 5min | ||
|
||
#### Configuration options: | ||
|
||
* ``licenseTemplateFile`` (default: ``'license.template'``) | ||
|
||
path to file with license header template resolved relatively to config file | ||
|
||
* ``licenseTemplateIsRegex`` (default: ``false``) | ||
|
||
whether or not the license header template is a regex template | ||
|
||
### CommentOverPrivateFunction | ||
|
||
This rule reports comments and documentation that has been added to private functions. These comments get reported | ||
because they probably explain the functionality of the private function. However private functions should be small | ||
enough and have an understandable name so that they are self-explanatory and do not need this comment in the first | ||
place. | ||
|
||
Instead of simply removing this comment to solve this issue prefer to split up the function into smaller functions | ||
with better names if necessary. Giving the function a better, more descriptive name can also help in | ||
solving this issue. | ||
|
||
**Active by default**: No | ||
|
||
**Debt**: 20min | ||
|
||
### CommentOverPrivateProperty | ||
|
||
This rule reports comments and documentation above private properties. This can indicate that the property has a | ||
confusing name or is not in a small enough context to be understood. | ||
Private properties should be named in a self-explanatory way and readers of the code should be able to understand | ||
why the property exists and what purpose it solves without the comment. | ||
|
||
Instead of simply removing the comment to solve this issue prefer renaming the property to a more self-explanatory | ||
name. If this property is inside a bigger class it could make senes to refactor and split up the class. This can | ||
increase readability and make the documentation obsolete. | ||
|
||
**Active by default**: No | ||
|
||
**Debt**: 20min | ||
|
||
### DeprecatedBlockTag | ||
|
||
This rule reports use of the `@deprecated` block tag in KDoc comments. Deprecation must be specified using a | ||
`@Deprecated` annotation as adding a `@deprecated` block tag in KDoc comments | ||
[has no effect and is not supported](https://kotlinlang.org/docs/kotlin-doc.html#suppress). The `@Deprecated` | ||
annotation constructor has dedicated fields for a message and a type (warning, error, etc.). You can also use the | ||
`@ReplaceWith` annotation to specify how to solve the deprecation automatically via the IDE. | ||
|
||
**Active by default**: No | ||
|
||
**Debt**: 5min | ||
|
||
#### Noncompliant Code: | ||
|
||
```kotlin | ||
/** | ||
* This function prints a message followed by a new line. | ||
* | ||
* @deprecated Useless, the Kotlin standard library can already do this. Replace with println. | ||
*/ | ||
fun printThenNewline(what: String) { | ||
// ... | ||
} | ||
``` | ||
|
||
#### Compliant Code: | ||
|
||
```kotlin | ||
/** | ||
* This function prints a message followed by a new line. | ||
*/ | ||
@Deprecated("Useless, the Kotlin standard library can already do this.") | ||
@ReplaceWith("println(what)") | ||
fun printThenNewline(what: String) { | ||
// ... | ||
} | ||
``` | ||
|
||
### EndOfSentenceFormat | ||
|
||
This rule validates the end of the first sentence of a KDoc comment. | ||
It should end with proper punctuation or with a correct URL. | ||
|
||
**Active by default**: No | ||
|
||
**Debt**: 5min | ||
|
||
#### Configuration options: | ||
|
||
* ``endOfSentenceFormat`` (default: ``'([.?!][ \t\n\r\f<])|([.?!:]$)'``) | ||
|
||
regular expression which should match the end of the first sentence in the KDoc | ||
|
||
### UndocumentedPublicClass | ||
|
||
This rule reports public classes, objects and interfaces which do not have the required documentation. | ||
Enable this rule if the codebase should have documentation on every public class, interface and object. | ||
|
||
By default this rule also searches for nested and inner classes and objects. This default behavior can be changed | ||
with the configuration options of this rule. | ||
|
||
**Active by default**: No | ||
|
||
**Debt**: 20min | ||
|
||
#### Configuration options: | ||
|
||
* ``searchInNestedClass`` (default: ``true``) | ||
|
||
if nested classes should be searched | ||
|
||
* ``searchInInnerClass`` (default: ``true``) | ||
|
||
if inner classes should be searched | ||
|
||
* ``searchInInnerObject`` (default: ``true``) | ||
|
||
if inner objects should be searched | ||
|
||
* ``searchInInnerInterface`` (default: ``true``) | ||
|
||
if inner interfaces should be searched | ||
|
||
### UndocumentedPublicFunction | ||
|
||
This rule will report any public function which does not have the required documentation. | ||
If the codebase should have documentation on all public functions enable this rule to enforce this. | ||
Overridden functions are excluded by this rule. | ||
|
||
**Active by default**: No | ||
|
||
**Debt**: 20min | ||
|
||
### UndocumentedPublicProperty | ||
|
||
This rule will report any public property which does not have the required documentation. | ||
This also includes public properties defined in a primary constructor. | ||
If the codebase should have documentation on all public properties enable this rule to enforce this. | ||
Overridden properties are excluded by this rule. | ||
|
||
**Active by default**: No | ||
|
||
**Debt**: 20min |
Oops, something went wrong.