Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add rule to migrate away from ktlint-disable directives #2068

Merged
merged 28 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
437a428
Fix max line length for markdown files
paul-dingemans Jun 5, 2023
5031bad
Fix wildcard imports settings
paul-dingemans Jun 5, 2023
675b708
Improve trace logging by printing a lint error directly when it is em…
paul-dingemans Jun 5, 2023
428d52e
Add rule to migrate ktlint-disable directives from comments to @Suppr…
paul-dingemans Jun 5, 2023
e2422c8
Fix lint violations
paul-dingemans Jun 5, 2023
fea7170
Improve description of rule
paul-dingemans Jun 6, 2023
a973293
Support array annotations
paul-dingemans Jun 6, 2023
b84d8a8
Support annotations with named argument initialized with array (squar…
paul-dingemans Jun 6, 2023
a40c27e
Add test case for adding a rule id to a Suppress annotation without p…
paul-dingemans Jun 6, 2023
11861fe
Fix lint violations
paul-dingemans Jun 6, 2023
ec099d5
- Fix rule suppressions on a class initializer
paul-dingemans Jun 8, 2023
ad9ac65
fix lint violation
paul-dingemans Jun 8, 2023
51a8b3e
- Convert a top level block comment with a ktlint-disable directive t…
paul-dingemans Jun 10, 2023
4b0b4e8
- Move KtlintSuppressionRule from standard ruleset to an internal rul…
paul-dingemans Jun 11, 2023
05bdaa2
fix lint violation
paul-dingemans Jun 13, 2023
7fa8d3f
Fix typo
paul-dingemans Jun 23, 2023
5094565
Map to mutable set as an additional element will be added to it always
paul-dingemans Jun 23, 2023
a165c3a
Extract duplicated logic to removePrecedingWhitespace
paul-dingemans Jun 23, 2023
be43f54
Do not add an empty '@Suppress()' in case the ktlint rule id is unkno…
paul-dingemans Jun 23, 2023
cb8e15c
Fix duplicate @Suppress annotation on property accessor
paul-dingemans Jun 24, 2023
d87ec58
Create suppress annotaion on class if ktlint-disable directive found …
paul-dingemans Jun 24, 2023
e091cbc
Promote a matching pair of ktlint-disable and ktlint-enable directive…
paul-dingemans Jun 24, 2023
1e2ffb9
Merge new ktlint rule suppression with existing suppression using a n…
paul-dingemans Jun 24, 2023
681d8ec
Propagate the rule suppression in an expression to the outermost expr…
paul-dingemans Jun 24, 2023
76af1d1
Ensure that ktlint-suppression runs before any other rule
paul-dingemans Jun 24, 2023
73e3d4e
Fix lint violation
paul-dingemans Jun 24, 2023
4d5b734
Merge remote-tracking branch 'origin/master' into 1947-ktlint-disable
paul-dingemans Jun 25, 2023
37b6f3c
Merge branch 'master' into 1947-ktlint-disable
paul-dingemans Jun 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ root = true
[*]
indent_style = space
indent_size = 2
max_line_length = 140

end_of_line = lf
charset = utf-8
Expand All @@ -26,8 +27,13 @@ ktlint_experimental = enabled
# Don't allow any wildcard imports
ij_kotlin_packages_to_use_import_on_demand = unset

# Prevent wildcard imports
ij_kotlin_name_count_to_use_star_import = 99
ij_kotlin_name_count_to_use_star_import_for_members = 99

[*.md]
trim_trailing_whitespace = false
max_line_length = unset

[gradle/verification-metadata.xml]
indent_size = 3
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ This project adheres to [Semantic Versioning](https://semver.org/).

## Unreleased

### Deprecation of ktlint-enable and ktlint-disable directives

The `ktlint-disable` and `ktlint-enable` directives are no longer supported. Ktlint rules can now only be suppressed using the `@Suppress` or `@SuppressWarnings` annotations. A new rule, `internal:ktlint-suppression`, is provided to replace the directives with annotations.

API consumers do not need to provide this rule, but it does no harm when done.

The `internal:ktlint-suppression` rule can not be disabled via the `.editorconfig` nor via `@Suppress` or `@SuppressWarnings` annotations.

### Custom Rule Providers need to prepare for Kotlin 1.9

In Kotlin 1.9 the extension points of the embedded kotlin compiler will change. Ktlint only uses the `org.jetbrains.kotlin.com.intellij.treeCopyHandler` extension point. This extension is not yet supported in 1.9, neither is it documented ([#KT-58704](https://youtrack.jetbrains.com/issue/KT-58704/Support-and-document-extension-point-org.jetbrains.kotlin.com.intellij.treeCopyHandler)). Without this extension point it might happen that your custom rules will throw exceptions during runtime. See [#1981](https://github.com/pinterest/ktlint/issues/1981).
Expand Down Expand Up @@ -31,6 +39,7 @@ At this point in time, it is not yet decided what the next steps will be. Ktlint
* Add new experimental rule `no-empty-file` for all code styles. A kotlin (script) file may not be empty ([#1074](https://github.com/pinterest/ktlint/issues/1074))
* Add new experimental rule `statement-wrapping` which ensures function, class, or other blocks statement body doesn't start or end at starting or ending braces of the block ([#1938](https://github.com/pinterest/ktlint/issues/1938))
* Add new experimental rule `blank-line-before-declaration`. This rule requires a blank line before class, function or property declarations ([#1939](https://github.com/pinterest/ktlint/issues/1939))
* Add new rule `ktlint-suppression` to replace the `ktlint-disable` and `ktlint-enable` directives with annotations. This rule can not be disabled via the `.editorconfig` ([#1947](https://github.com/pinterest/ktlint/issues/1947))

### Removed

Expand Down
49 changes: 4 additions & 45 deletions documentation/snapshot/docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,17 @@ See [adding a custom rule set](../api/custom-rule-set/) for more information.
!!! tip
Suppressing a `ktlint` violation is meant primarily as an escape latch for the rare cases when **ktlint** is not able to produce the correct result. Please report any such instances using [GitHub Issues](https://github.com/pinterest/ktlint/issues)).

To disable a specific rule you'll need the rule identifier which is displayed at the end of the lint error.
To disable a specific rule you'll need the fully qualified rule identifier. This identifier is displayed at the end of the lint error. In case your code was autocorrected, you need to revert the code and run the `lint` task instead of the `format` to find the rule identifier.

An error can be suppressed using:
As of Ktlint 0.50, an error can only be suppressed using @Suppress or @SuppressWarnings annotations

* EOL comments
* Block comments
* @Suppress annotations

=== "[:material-heart:](#) Suppress annotation"
=== "[:material-heart:](#) Allowed"

```kotlin
// Suppressing all rules for the entire file
@file:Suppress("ktlint")

// Suppress a single rule (with id 'rule-id', defined in rule set with id 'rule-set-id') from the annotated construct
// Suppress a single rule (with id 'rule-id', defined in rule set with id 'rule-set-id') in the scope of the annotated construct
@Suppress("ktlint:rule-set-id:rule-id")
class Foo {}

Expand All @@ -69,43 +65,6 @@ An error can be suppressed using:
@Suppress("ktlint")
import foo.*
```
=== "[:material-heart:](#) EOL comments"

```kotlin
// Suppress a single rule for the commented line
import foo.* // ktlint-disable standard_no-wildcard-imports

// Suppress multiple rules for the commented line
import foo.* // ktlint-disable standard_no-wildcard-imports standard_other-rule-id

// Suppress all rules for the commented line
import foo.* // ktlint-disable
```

=== "[:material-heart-off-outline:](#) Block comments"

```kotlin
// Suppress a single rule for all code between the start and end tag
/* ktlint-disable standard_no-wildcard-imports */
import foo.*
/* ktlint-disable standard_no-wildcard-imports */

// Suppress multiple rules for all code between the start and end tag
/* ktlint-disable standard_no-wildcard-imports standard_no-wildcard-imports */
import foo.*
/* ktlint-enable standard_no-wildcard-imports standard_no-wildcard-imports */

// Suppress all rules for all code between the start and end tag
/* ktlint-disable */
import foo.*
/* ktlint-enable */
```

!!! important
When using the block comments, the `ktlint-enable` directive needs to specify the exact same rule-id's and in the same order as the `ktlint-disable` directive.

!!! warning
From a consistency perspective seen, it might be best to **not** mix the (EOL/Block) comment style with the annotation style in the same project.

## How do I globally disable a rule without `.editorconfig`?

Expand Down
4 changes: 0 additions & 4 deletions documentation/snapshot/docs/rules/experimental.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,10 +452,6 @@ A single line block comment should be replaced with an EOL comment when possible
*/
val foo = "foo" // Some comment
val foo = { /* no-op */ }

/* ktlint-disable foo-rule-id bar-rule-id */
val foo = "foo"
/* ktlint-enable foo-rule-id bar-rule-id */
```
=== "[:material-heart-off-outline:](#) Disallowed"

Expand Down
48 changes: 48 additions & 0 deletions documentation/snapshot/docs/rules/standard.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,54 @@ Indentation formatting - respects `.editorconfig` `indent_size` with no continua

Rule id: `indent` (`standard` rule set)

## Ktlint-suppression rule

The `ktlint-disable` and `ktlint-enable` directives are no longer supported as of ktlint version `0.50.0`. This rule migrates the directives to Suppress or SuppressWarnings annotations.

Identifiers in the @Suppress and @SuppressWarnings annotations to suppress ktlint rules are checked for validity and autocorrected when possible.

=== "[:material-heart:](#) Ktlint"

```kotlin
@file:Suppress("ktlint:standard:no-wildcard-imports")

class FooBar {
@Suppress("ktlint:standard:max-line-length")
val foo = "some longggggggggggggggggggg text"

fun bar() =
@Suppress("ktlint:standard:no-multi-spaces")
listOf(
"1 One",
"10 Ten",
"100 Hundred",
)
}
```
=== "[:material-heart-off-outline:](#) Disallowed"

```kotlin
/* ktlint-disable standard:no-wildcard-imports */

class FooBar {
val foo = "some longggggggggggggggggggg text" // ktlint-disable standard:max-line-length

fun bar() =
listOf(
/* ktlint-disable standard:no-multi-spaces */
"1 One",
"10 Ten",
"100 Hundred",
/* ktlint-enable standard:no-multi-spaces */
)
}
```

Rule id: `ktlint-suppression` (`standard` rule set)

!!! note
This rule can not be disabled in the `.editorconfig`.
paul-dingemans marked this conversation as resolved.
Show resolved Hide resolved

## Max line length

Ensures that lines do not exceed the given length of `.editorconfig` property `max_line_length` (see [EditorConfig](../configuration-ktlint/) section for more). This rule does not apply in a number of situations. For example, in the case a line exceeds the maximum line length due to a comment that disables ktlint rules then that comment is being ignored when validating the length of the line. The `.editorconfig` property `ktlint_ignore_back_ticked_identifier` can be set to ignore identifiers which are enclosed in backticks, which for example is very useful when you want to allow longer names for unit tests.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,29 @@ class CheckStyleReporterTest {
val reporter = CheckStyleReporter(PrintStream(out, true))
reporter.onLintError(
"/one-fixed-and-one-not.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 1, "rule-1", "<\"&'>", LINT_CAN_BE_AUTOCORRECTED),
)
reporter.onLintError(
"/one-fixed-and-one-not.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(2, 1, "rule-2", "And if you see my friend", FORMAT_IS_AUTOCORRECTED),
)

reporter.onLintError(
"/two-not-fixed.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 10, "rule-1", "I thought I would again", LINT_CAN_BE_AUTOCORRECTED),
)
reporter.onLintError(
"/two-not-fixed.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(2, 20, "rule-2", "A single thin straight line", LINT_CAN_BE_AUTOCORRECTED),
)

reporter.onLintError(
"/all-corrected.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 1, "rule-1", "I thought we had more time", FORMAT_IS_AUTOCORRECTED),
)
reporter.afterAll()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ class FormatReporterTest {
}

companion object {
@Suppress("ktlint:argument-list-wrapping", "ktlint:max-line-length")
@Suppress("ktlint:standard:argument-list-wrapping", "ktlint:standard:max-line-length")
val SOME_LINT_ERROR_CAN_BE_AUTOCORRECTED =
KtlintCliError(1, 1, "some-rule", "This error can be autocorrected", LINT_CAN_BE_AUTOCORRECTED)

@Suppress("ktlint:argument-list-wrapping", "ktlint:max-line-length")
@Suppress("ktlint:standard:argument-list-wrapping", "ktlint:standard:max-line-length")
val SOME_LINT_ERROR_CAN_NOT_BE_AUTOCORRECTED =
KtlintCliError(1, 1, "rule-1", "This error can *not* be autocorrected", LINT_CAN_NOT_BE_AUTOCORRECTED)

@Suppress("ktlint:argument-list-wrapping", "ktlint:max-line-length")
@Suppress("ktlint:standard:argument-list-wrapping", "ktlint:standard:max-line-length")
val SOME_FORMAT_ERROR_IS_AUTOCORRECTED =
KtlintCliError(1, 1, "rule-1", "This error can *not* be autocorrected", FORMAT_IS_AUTOCORRECTED)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,13 @@ class HtmlReporterTest {
val out = ByteArrayOutputStream()
val reporter = HtmlReporter(PrintStream(out, true))

@Suppress("ktlint:argument-list-wrapping", "ktlint:max-line-length")
@Suppress("ktlint:standard:argument-list-wrapping", "ktlint:standard:max-line-length")
reporter.onLintError(
"/file1.kt",
KtlintCliError(1, 1, "rule-1", "Error message contains a generic type like List<Int> (cannot be auto-corrected)", LINT_CAN_BE_AUTOCORRECTED),
)

@Suppress("ktlint:argument-list-wrapping", "ktlint:max-line-length")
@Suppress("ktlint:standard:argument-list-wrapping", "ktlint:standard:max-line-length")
reporter.onLintError(
"/file1.kt",
KtlintCliError(2, 1, "rule-2", "Error message contains special html symbols like a<b>c\"d'e&f (cannot be auto-corrected)", LINT_CAN_BE_AUTOCORRECTED),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,29 @@ class JsonReporterTest {
val reporter = JsonReporter(PrintStream(out, true))
reporter.onLintError(
"/one-fixed-and-one-not.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 1, "rule-1", "<\"&'>", LINT_CAN_BE_AUTOCORRECTED),
)
reporter.onLintError(
"/one-fixed-and-one-not.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(2, 1, "rule-2", "And if you see my friend", FORMAT_IS_AUTOCORRECTED),
)

reporter.onLintError(
"/two-not-fixed.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 10, "rule-1", "I thought I would again", LINT_CAN_BE_AUTOCORRECTED),
)
reporter.onLintError(
"/two-not-fixed.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(2, 20, "rule-2", "A single thin straight line", LINT_CAN_BE_AUTOCORRECTED),
)

reporter.onLintError(
"/all-corrected.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 1, "rule-1", "I thought we had more time", FORMAT_IS_AUTOCORRECTED),
)
reporter.afterAll()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,29 @@ class PlainSummaryReporterTest {
).apply {
onLintError(
"file-1.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 1, "rule-1", "description-error-at-position-1:1 (cannot be auto-corrected)", LINT_CAN_BE_AUTOCORRECTED),
)
onLintError(
"file-1.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(2, 1, "rule-2", "description-error-at-position-2:1", FORMAT_IS_AUTOCORRECTED),
)

onLintError(
"file-2.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 10, "rule-1", "description-error-at-position-1:10 (cannot be auto-corrected)", LINT_CAN_BE_AUTOCORRECTED),
)
onLintError(
"file-2.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(2, 20, "rule-2", "description-error-at-position-2:20 (cannot be auto-corrected)", LINT_CAN_BE_AUTOCORRECTED),
)

onLintError(
"file-3.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(1, 1, "rule-1", "description-error-at-position-1:1", FORMAT_IS_AUTOCORRECTED),
)

Expand Down Expand Up @@ -72,17 +72,17 @@ class PlainSummaryReporterTest {
val reporter = PlainSummaryReporter(PrintStream(out, true))
reporter.onLintError(
"file-1.kt",
@Suppress("ktlint:argument-list-wrapping", "ktlint:max-line-length")
@Suppress("ktlint:standard:argument-list-wrapping", "ktlint:standard:max-line-length")
KtlintCliError(18, 51, "", "Not a valid Kotlin file (18:51 unexpected tokens (use ';' to separate expressions on the same line)) (cannot be auto-corrected) ()", KOTLIN_PARSE_EXCEPTION),
)
reporter.onLintError(
"file-2.kt",
@Suppress("ktlint:argument-list-wrapping", "ktlint:max-line-length")
@Suppress("ktlint:standard:argument-list-wrapping", "ktlint:standard:max-line-length")
KtlintCliError(18, 51, "", "Not a valid Kotlin file (18:51 unexpected tokens (use ';' to separate expressions on the same line)) (cannot be auto-corrected) ()", KOTLIN_PARSE_EXCEPTION),
)
reporter.onLintError(
"file-3.kt",
@Suppress("ktlint:argument-list-wrapping")
@Suppress("ktlint:standard:argument-list-wrapping")
KtlintCliError(18, 51, "", "Something else", LINT_CAN_BE_AUTOCORRECTED),
)
reporter.afterAll()
Expand Down
Loading