Skip to content

Releases: pinterest/ktlint

0.49.0

21 Apr 15:27
30e20ec
Compare
Choose a tag to compare

WARNING: This version of KtLint contains a number of breaking changes in KtLint CLI and KtLint API. If you are using KtLint with custom ruleset jars or custom reporter jars, then those need to be upgraded before you can use them with this version of ktlint. Please contact the maintainers of those jars and ask them to upgrade a.s.a.p.

All rule id's in the output of Ktlint are now prefixed with a rule set. Although KtLint currently supports standard rules to be unqualified, users are encouraged to include the rule set id in all references to rules. This includes following:

  • The --disabled-rules parameter in KtLint CLI.
  • The .editorconfig properties used to enable or disable rule and rule sets. Note that properties disabled_rules and ktlint_disabled_rules have been removed in this release. See disabled rules for more information.
  • The source element in the KtLint CLI baseline.xml file. Regenerating this file, fixes all rule references automatically.
  • The KtLint disable directives ktlint-enable / ktlint-disable and the @Suppress('ktlint:...') annotations.
  • The VisitorModifier.RunAfterRule.

Moving experimental rules to standard rule set

The experimental rule set has been merged with standard rule set. The rules which formerly were part of the experimental rule set are still being treated as before. The rules will only be run in case .editorconfig property ktlint_experimental is enabled or in case the rule is explicitly enabled.

Note that the prefix experimental: has to be removed from all references to this rule. Check references in:

  • The --disabled-rules parameter in KtLint CLI.
  • The .editorconfig properties used to enable or disable rule and rule sets. Note that properties disabled_rules and ktlint_disabled_rules have been removed in this release. See disabled rules for more information.
  • The KtLint disable directives ktlint-enable / ktlint-disable and the @Suppress('ktlint:...') annotations.
  • The VisitorModifier.RunAfterRule.

Promote experimental rules to non-experimental

The rules below have been promoted to non-experimental rules:

Note that this only affects users that have enabled the standard ruleset while having the experimental rules disabled.

API Changes & RuleSet providers & Reporter Providers

This release is intended to be the last release before the 1.0.x release of ktlint. If all goes as planned, the 1.0.x release does not contain any new breaking changes with except of removal of functionality which is deprecated in this release.

This release contains a lot of breaking changes which aims to improve the future maintainability of Ktlint. If you get stuck while migrating, please reach out to us by creating an issue.

Experimental rules

Rules in custom rule sets can now be marked as experimental by implementing the Rule.Experimental interface on the rule. Rules marked with this interface will only be executed by Ktlint if .editorconfig property ktlint_experimental is enabled or if the rule itself has been enabled explicitly.

When using this feature, experimental rules should not be defined in a separate rule set as that would require a distinct rule set id. When moving a rule from an experimental rule set to a non-experimental rule set this would mean that the qualified rule id changes. For users of such rules this means that ktlint directives to suppress the rule and properties in the .editorconfig files have to be changed.

EditorConfig

Field defaultAndroidValue in class EditorConfigProperty has been renamed to androidStudioCodeStyleDefaultValue. New fields ktlintOfficialCodeStyleDefaultValue and intellijIdeaCodeStyleDefaultValue have been added. Read more about this in the section "Ktlint Official code style".

The .editorconfig properties disabled_rules and ktlint_disabled_rules are no longer supported. Specifying those properties in the editorConfigOverride or editorConfigDefaults result in warnings at runtime.

'Ktlint Official` code style and renaming of existing code styles

A new code style ktlint_official is introduced. This code style is work in progress but will become the default code style in the 1.0 release. Please try out the new code style and provide your feedback via the issue tracker.

This ktlint_official code style combines the best elements from the Kotlin Coding conventions and Android's Kotlin styleguide. This code style also provides additional formatting on topics which are not (explicitly) mentioned in those conventions and style guide. But do note that this code style sometimes formats code in a way which is not accepted by the default code formatters in IntelliJ IDEA and Android Studio. The formatters of those editors produce nicely formatted code in the vast majority of cases. But in a number of edge cases, the formatting contains bugs which are waiting to be fixed for several years. The new code style formats code in a way which is compatible with the default formatting of the editors whenever possible. When using this codestyle, it is best to disable (e.g. not use) code formatting in the editor.

The existing code styles have been renamed to make more clear what the basis of the code style is.

The official code style has been renamed to intellij_idea. Code formatted with this code style aims to be compatible with default formatter of IntelliJ IDEA. This code style is based on Kotlin Coding conventions. If .editorconfig property ktlint_code_style has been set to android then do not forget to change the value of that property to intellij_idea. When not set, this is still the default code style of ktlint 0.49. Note that the default code style will be changed to ktlint_official in the 1.0 release.

Code style android has been renamed to android_studio. Code formatted with this code style aims to be compatible with default formatter of Android Studio. This code style is based on Android's Kotlin styleguide. If .editorconfig property ktlint_code_style has been set to android then do not forget to change the value of that property to android_studio.

Package restructuring and class relocation

The internal structure of the Ktlint project has been revised. The Ktlint CLI and KtLint API modules have been decoupled where possible. Modules have been restructured and renamed. See API Overview for more information.

This is the last release that contains module ktlint-core as it had too many responsibilities. All classes in this module are relocated to other modules. Some classes have also been renamed. See tables below for details. Classes that are left behind in the ktlint-core module are deprecated and were kept in this version for backwards compatibility only. The ktlint-core module will be removed in Ktlint 0.50.x.

Classes below have been moved from module ktlint-core to the new module ktlint-rule-engine-core:

Old class/package name in ktlint-core New class/package name in ktlint-rule-engine-core
com.pinterest.ktlint.core.api.editorconfig com.pinterest.ktlint.rule.engine.core.api.editorconfig
com.pinterest.ktlint.core.api.EditorConfigProperties com.pinterest.ktlint.rule.engine.core.api.EditorConfig
com.pinterest.ktlint.core.api.OptInFeatures com.pinterest.ktlint.rule.engine.core.api.OptInFeatures
com.pinterest.ktlint.core.ast.ElementType com.pinterest.ktlint.rule.engine.core.api.ElementType
com.pinterest.ktlint.core.ast.package com.pinterest.ktlint.rule.engine.core.api.ASTNodeExtension
com.pinterest.ktlint.core.IndentConfig com.pinterest.ktlint.rule.engine.core.api.IndentConfig
com.pinterest.ktlint.core.Rule ...
Read more

0.48.2

23 Jan 20:30
2642124
Compare
Choose a tag to compare

Additional clarification on API Changes in 0.48.0 and 0.48.1

Starting with Ktlint 0.48.x, rule and rule sets can be enabled/disabled with a separate property per rule (set). Please read deprecation of (ktlint_)disable_rules property for more information.

API Consumers that provide experimental rules to the KtLintRuleEngine, must also enable the experimental rules or instruct their users to do so in the .editorconfig file. From the perspective of the API Consumer it might be confusing or unnecessary to do so as the experimental rule was already provided explicitly.

Ktlint wants to provide the user (e.g. a developer) a uniform and consistent user experience. The .editorconfig becomes more and more central to store configuration for Ktlint. This to ensure that all team members use the exact same configuration when running ktlint regardless whether the Ktlint CLI or an API Consumer is being used.

The .editorconfig is a powerful configuration tool which can be used in very different ways. Most projects use a single .editorconfig file containing one common section for kotlin and kotlin scripts files. For example, the .editorconfig file of the Ktlint project contains following section:

[*.{kt,kts}]
ij_kotlin_imports_layout = *
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true

Other projects might contain multiple .editorconfig files for different parts of the project directory hierarchy. Or, use a single .editorconfig file containing multiple sections with different globs. Like all other configuration settings in Ktlint, the user should be able to enable and disable the experimental rules. Both for the entire set of experimental rules and for individual experimental rules.

Ktlint allows API Consumers to set default values and override values for the .editorconfig. Specifying a default value means that the user does not need to define the property in the .editorconfig file but if the user specifies the value, it will take precedence. Specifying the override value ensures that this takes precedence on a value specified by the user in the .editorconfig.

From the Ktlint perspective, it is advised that API Consumers provide the default value. See example below, for how to specify the editorConfigDefault property:

KtLintRuleEngine(
    ruleProviders = ruleProviders,
    editorConfigDefaults = EditorConfigDefaults(
        EditorConfig
            .builder()
            .section(
                Section
                    .builder()
                    .glob(Glob("*.{kt,kts}"))
                    .properties(
                        Property
                            .builder()
                            .name("ktlint_experimental")
                            .value("enabled"),
                    ),
            )
            .build()
    )
)

If the user has set property ktlint_experimental explicitly than that value will be used. If the value is not defined, the value provided via editorConfigDefaults will be used.

If you do want to ignore the value of ktlint_experimental as set by the user, than you can set the EditorConfigOverride property. But as said before that is discouraged as the user might not understand why the .editorconfig property is being ignored (provided that the value set is not equal to the value provided by the API Consumer).

Added

Removed

Fixed

  • Fix with array-syntax annotations on the same line as other annotations annotation (#1765)
  • Do not enable the experimental rules by default when .editorconfig properties disabled_rules or ktlint_disabled_rules are set. (#1771)
  • A function signature not having any parameters which exceeds the max-line-length should be ignored by rule function-signature (#1773)
  • Allow diacritics in names of classes, functions packages, and properties class-naming, function-naming, package-name, property-naming (#1757)
  • Prevent violation of file-name rule on code snippets (#1768)
  • Clarify that API Consumers have to enable experimental rules (#1768)
  • Trim spaces in the .editorconfig property ij_kotlin_imports_layout's entries (#1770)

Changed

0.48.1

03 Jan 18:23
335e653
Compare
Choose a tag to compare

Added

Removed

Fixed

  • An enumeration class having a primary constructor and in which the list of enum entries is followed by a semicolon then do not remove the semicolon in case it is followed by code element no-semi (#1733)
  • Add API so that KtLint API consumer is able to process a Kotlin script snippet without having to specify a file path (#1738)
  • Disable the standard:filename rule whenever Ktlint CLI is run with option --stdin (#1742)
  • Fix initialization of the logger when --log-level is specified. Throw exception when an invalid value is passed. (#1749)
  • Fix loading of custom rule set JARs.
  • Rules provided via a custom rule set JAR (Ktlint CLI) or by an API provider are enabled by default. Only rules in the experimental rule set are disabled by default. (#1747)

Changed

  • Update Kotlin development version to 1.8.0 and Kotlin version to 1.8.0.

0.48.0

15 Dec 21:00
343cfbc
Compare
Choose a tag to compare

[0.48.0] - 2022-12-15

Indent rule

The indent rule has been rewritten from scratch. Solving problems in the old algorithm was very difficult. With the new algorithm this becomes a lot easier. Although the new implementation of the rule has been compared against several open source projects containing over 400,000 lines of code, it is still likely that new issues will be discovered. Please report your indentation issues so that these can be fixed as well.

.editorconfig property to disable rules

In the previous release (0.47.x), the .editorconfig property disabled_rules was deprecated and replaced with ktlint_disabled_rules. This latter property has now been deprecated as well in favour of a more flexible and better maintainable solution. Rule and rule sets can now be enabled/disabled with a separate property per rule (set). Please read deprecation of (ktlint_)disable_rules property for more information.

The KtLint CLI has not been changed. Although you can still use parameter --experimental to enable KtLint's Experimental rule set, you might want to set .editorconfig property ktlint_experimental = enabled instead.

API Changes & RuleSet providers

If you are not an API consumer or Rule Set provider then you can skip this section.

Class relocations

Classes below have been relocated:

  • Class com.pinterest.ktlint.core.api.UsesEditorConfigProperties.EditorConfigProperty has been replaced with com.pinterest.ktlint.core.api.editorconfig.EditorConfigProperty.
  • Class com.pinterest.ktlint.core.KtLintParseException has been replaced with com.pinterest.ktlint.core.api.KtLintParseException.
  • Class com.pinterest.ktlint.core.RuleExecutionException has been replaced with com.pinterest.ktlint.core.api.KtLintRuleException.
  • Class com.pinterest.ktlint.reporter.format.internal.Color has been moved to com.pinterest.ktlint.reporter.format.Color.
  • Class com.pinterest.ktlint.reporter.plain.internal.Color has been moved to com.pinterest.ktlint.reporter.plain.Color.

Invoking lint and format

This is the last release that supports the ExperimentalParams to invoke the lint and format functions of KtLint. The ExperimentalParams contains a mix of configuration settings which are not dependent on the file/code which is to be processed. Other parameters in that class describe the code/file to be processed but can be configured inconsistently (for example a file with name "foo.kt" could be marked as a Kotlin Script file).

The static object KtLint is deprecated and replaced by class KtLintRuleEngine which is configured with KtLintRuleEngineConfiguration. The instance of the KtLintRuleEngine is intended to be reused for scanning all files in a project and should not be recreated per file.

Both lint and format are simplified and can now be called for a code block or for an entire file.

import java.io.File

// Define a reusable instance of the KtLint Rule Engine
val ktLintRuleEngine = KtLintRuleEngine(
  // Define configuration
)


// Process a collection of files
val files: Set<File> // Collect files in a convenient way
files.forEach(file in files) {
    ktLintRuleEngine.lint(file) {
        // Handle lint violations
    }
}

// or process a code sample for a given filepath
ktLintRuleEngine.lint(
  code = "code to be linted",
  filePath = Path("/path/to/source/file")
) {
  // Handle lint violations
}

Retrieve .editorconfigs

The list of .editorconfig files which will be accessed by KtLint when linting or formatting a given path can now be retrieved with the new API KtLint.editorConfigFilePaths(path: Path): List<Path>.

This API can be called with either a file or a directory. It's intended usage is that it is called once with the root directory of a project before actually linting or formatting files of that project. When called with a directory path, all .editorconfig files in the directory or any of its subdirectories (except hidden directories) are returned. In case the given directory does not contain an .editorconfig file or if it does not contain the root=true setting, the parent directories are scanned as well until a root .editorconfig file is found.

Calling this API with a file path results in the .editorconfig files that will be accessed when processing that specific file. In case the directory in which the file resides does not contain an .editorconfig file or if it does not contain the root=true setting, the parent directories are scanned until a root .editorconfig file is found.

Psi filename replaces FILE_PATH_USER_DATA_KEY

Constant KtLint.FILE_PATH_USER_DATA_KEY is deprecated and will be removed in KtLint version 0.49.0. The file name will be passed correctly to the node with element type FILE and can be retrieved as follows:

if (node.isRoot()) {
    val fileName = (node.psi as? KtFile)?.name
    ...
}

Added

  • Wrap blocks in case the max line length is exceeded or in case the block contains a new line wrapping (#1643)
  • patterns can be read in from stdin with the --patterns-from-stdin command line options/flags (#1606)
  • Add basic formatting for context receiver in indent rule and new experimental rule context-receiver-wrapping (#1672)
  • Add naming rules for classes and objects (class-naming), functions (function-naming) and properties (property-naming) (#44)
  • Add new built-in reporter plain-summary which prints a summary the number of violation which have been autocorrected or could not be autocorrected, both split by rule.

Fixed

  • Let a rule process all nodes even in case the rule is suppressed for a node so that the rule can update the internal state (#1644)
  • Read .editorconfig when running CLI with options --stdin and --editorconfig (#1651)
  • Do not add a trailing comma in case a multiline function call argument is found but no newline between the arguments trailing-comma-on-call-site (#1642)
  • Add missing ktlint_disabled_rules to exposed editorConfigProperties (#1671)
  • Do not add a second trailing comma, if the original trailing comma is followed by a KDOC trailing-comma-on-declaration-site and trailing-comma-on-call-site (#1676)
  • A function signature preceded by an annotation array should be handled similar as function preceded by a singular annotation function-signature (#1690)
  • Fix offset of annotation violations
  • Fix line offset when blank line found between class and primary constructor
  • Remove needless blank line between class followed by EOL, and primary constructor
  • Fix offset of unexpected linebreak before assignment
  • Remove whitespace before redundant semicolon if the semicolon is followed by whitespace

Changed

  • Update Kotlin development version to 1.8.0-RC and Kotlin version to 1.7.21.
  • The default value for trailing comma's on call site is changed to true unless the android codestyle is enabled. Note that KtLint from a consistency viewpoint enforces the trailing comma on call site while default IntelliJ IDEA formatting only allows the trailing comma but leaves it up to the developer's discretion. (#1670)
  • The default value for trailing comma's on declaration site is changed to true unless the android codestyle is enabled. Note that KtLint from a consistency viewpoint enforces the trailing comma on declaration site while default IntelliJ IDEA formatting only allows the trailing comma but leaves it up to the developer's discretion. (#1669)
  • CLI options --debug, --trace, --verbose and -v are replaced with --log-level=<level> or the short version `-l=, see CLI log-level. (#1632)
  • In CLI, disable logging entirely by setting --log-level=none or -l=none (#1652)
  • Rewrite indent rule. Solving problems in the old algorithm was very difficult. With the new algorithm this becomes a lot easier. Although the new implementation of the rule has been compared against several open source projects containing over 400,000 lines of code, it is still likely that new issues will be discovered. Please report your indentation issues so that these can be fixed as well. (#1682, #1321, #1200, #1562, #1563, #1639)
  • Add methods "ASTNode.upsertWhitespaceBeforeMe" and "ASTNode.upsertWhitespaceAfterMe" as replacements for "LeafElement.upsertWhitespaceBeforeMe" and "LeafElement.upsertWhitespaceAfterMe". The new methods are more versatile and allow code to be written more readable in most places. (#1687)
  • Rewrite indent rule. Solving problems in the old algorithm was very difficult. With the new algorithm this becomes a lot easier. Although the new imp...
Read more

0.47.1

07 Sep 21:31
49d3f81
Compare
Choose a tag to compare

[0.47.1] - 2022-09-07

Fixed

  • Do not add trailing comma in empty parameter/argument list with comments (trailing-comma-on-call-site, trailing-comma-on-declaration-site) (#1602)
  • Fix class cast exception when specifying a non-string editorconfig setting in the default ".editorconfig" (#1627)
  • Fix indentation before semi-colon when it is pushed down after inserting a trailing comma (#1609)
  • Do not show deprecation warning about property "disabled_rules" when using CLi-parameter --disabled-rules (#1599)
  • Traversing directory hierarchy at Windows (#1600)
  • Ant-style path pattern support (#1601)
  • Apply @file:Suppress on all toplevel declarations (#1623)

Changed

  • Display warning instead of error when no files are matched, and return with exit code 0. (#1624)

0.47.0

19 Aug 20:01
aac71b8
Compare
Choose a tag to compare

[0.47.0] - 2022-08-19

API Changes & RuleSet providers

If you are not an API consumer nor a RuleSet provider, then you can safely skip this section. Otherwise, please read below carefully and upgrade your usage of ktlint. In this and coming releases, we are changing and adapting important parts of our API in order to increase maintainability and flexibility for future changes. Please avoid skipping a releases as that will make it harder to migrate.

Rule lifecycle hooks / deprecate RunOnRootOnly visitor modifier

Up until ktlint 0.46 the Rule class provided only one life cycle hook. This "visit" hook was called in a depth-first-approach on all nodes in the file. A rule like the IndentationRule used the RunOnRootOnly visitor modifier to call this lifecycle hook for the root node only in combination with an alternative way of traversing the ASTNodes. Downside of this approach was that suppression of the rule on blocks inside a file was not possible (#631). More generically, this applied to all rules, applying alternative traversals of the AST.

The Rule class now offers new life cycle hooks:

  • beforeFirstNode: This method is called once before the first node is visited. It can be used to initialize the state of the rule before processing of nodes starts. The ".editorconfig" properties (including overrides) are provided as parameter.
  • beforeVisitChildNodes: This method is called on a node in AST before visiting its child nodes. This is repeated recursively for the child nodes resulting in a depth first traversal of the AST. This method is the equivalent of the "visit" life cycle hooks. However, note that in KtLint 0.48, the UserData of the rootnode no longer provides access to the ".editorconfig" properties. This method can be used to emit Lint Violations and to autocorrect if applicable.
  • afterVisitChildNodes: This method is called on a node in AST after all its child nodes have been visited. This method can be used to emit Lint Violations and to autocorrect if applicable.
  • afterLastNode: This method is called once after the last node in the AST is visited. It can be used for teardown of the state of the rule.

Optionally, a rule can stop the traversal of the remainder of the AST whenever the goal of the rule has been achieved. See KDoc on Rule class for more information.

The "visit" life cycle hook will be removed in Ktlint 0.48. In KtLint 0.47 the "visit" life cycle hook will be called only when hook "beforeVisitChildNodes" is not overridden. It is recommended to migrate to the new lifecycle hooks in KtLint 0.47. Please create an issue, in case you need additional assistence to implement the new life cycle hooks in your rules.

Ruleset providing by Custom Rule Set Provider

The KtLint engine needs a more fine-grained control on the instantiation of new Rule instances. Currently, a new instance of a rule can be created only once per file. However, when formatting files the same rule instance is reused for a second processing iteration in case a Lint violation has been autocorrected. By re-using the same rule instance, state of that rule might leak from the first to the second processing iteration.

Providers of custom rule sets have to migrate the custom rule set JAR file. The current RuleSetProvider interface which is implemented in the custom rule set is deprecated and marked for removal in KtLint 0.48. Custom rule sets using the old RuleSetProvider interface will not be run in KtLint 0.48 or above.

For now, it is advised to implement the new RuleSetProviderV2 interface without removing the old RuleSetProvider interface. In this way, KtLint 0.47 and above use the RuleSetProviderV2 interface and ignore the old RuleSetProvider interface completely. KtLint 0.46 and below only use the old RuleSetProvider interface.

Adding the new interface is straight forward, as can be seen below:

// Current implementation
public class CustomRuleSetProvider : RuleSetProvider {
    override fun get(): RuleSet = RuleSet(
        "custom",
        CustomRule1(),
        CustomRule2(),
    )
}

// New implementation
public class CustomRuleSetProvider :
    RuleSetProviderV2(CUSTOM_RULE_SET_ID),
    RuleSetProvider {
    override fun get(): RuleSet =
        RuleSet(
            CUSTOM_RULE_SET_ID,
            CustomRule1(),
            CustomRule2()
        )

    override fun getRuleProviders(): Set<RuleProvider> =
        setOf(
            RuleProvider { CustomRule1() },
            RuleProvider { CustomRule2() }
        )

    private companion object {
        const val CUSTOM_RULE_SET_ID = custom"
    }
}

Also note that file 'resource/META-INF/services/com.pinterest.ktlint.core.RuleSetProviderV2' needs to be added. In case your custom rule set provider implements both RuleSetProvider and RuleSetProviderV2, the resource directory contains files for both implementation. The content of those files is identical as the interfaces are implemented on the same class.

Once above has been implemented, rules no longer have to clean up their internal state as the KtLint rule engine can request a new instance of the Rule at any time it suspects that the internal state of the Rule is tampered with (e.g. as soon as the Rule instance is used for traversing the AST).

Rule set providing by API Consumer

The KtLint engine needs a more fine-grained control on the instantiation of new Rule instances. Currently, a new instance of a rule can be created only once per file. However, when formatting files the same rule instance is reused for a second processing iteration in case a Lint violation has been autocorrected. By re-using the same rule instance, state of that rule might leak from the first to the second processing iteration.

The ExperimentalParams parameter which is used to invoke "KtLint.lint" and "KtLint.format" contains a new parameter "ruleProviders" which will replace the "ruleSets" parameter in KtLint 0.48. Exactly one of those parameters should be a non-empty set. It is preferred that API consumers migrate to using "ruleProviders".

// Old style using "ruleSets"
KtLint.format(
    KtLint.ExperimentalParams(
        ...
        ruleSets = listOf(
            RuleSet(
                "custom",
                CustomRule1(),
                CustomRule2()
            )
        ),
        ...
    )
)

// New style using "ruleProviders"
KtLint.format(
    KtLint.ExperimentalParams(
        ...
        ruleProviders = setOf(
            RuleProvider { CustomRule1() },
            RuleProvider { CustomRule2() }
        ),
        cb = { _, _ -> }
    )
)

Once above has been implemented, rules no longer have to clean up their internal state as the KtLint rule engine can request a new instance of the Rule at any time it suspects that the internal state of the Rule is tampered with (e.g. as soon as the Rule instance is used for traversing the AST).

Format callback

The callback function provided as parameter to the format function is now called for all errors regardless whether the error has been autocorrected. Existing consumers of the format function should now explicitly check the autocorrected flag in the callback result and handle it appropriately (in most case this will be ignoring the callback results for which autocorrected has value true).

CurrentBaseline

Class com.pinterest.ktlint.core.internal.CurrentBaseline has been replaced with com.pinterest.ktlint.core.api.Baseline.

Noteworthy changes:

  • Field baselineRules (nullable) is replaced with `lintErrorsPerFile (non-nullable).
  • Field baselineGenerationNeeded (boolean) is replaced with status (type Baseline.Status).

The utility functions provided via com.pinterest.ktlint.core.internal.CurrentBaseline are moved to the new class. One new method List<LintError>.doesNotContain(lintError: LintError) is added.

.editorconfig property "disabled_rules"

The .editorconfig property disabled_rules (api property DefaultEditorConfigProperties.disabledRulesProperty) has been deprecated and will be removed in a future version. Use ktlint_disabled_rules (api property DefaultEditorConfigProperties.ktlintDisabledRulesProperty) instead as it more clearly identifies that ktlint is the owner of the property. This property is to be renamed in .editorconfig files and ExperimentalParams.editorConfigOverride.

Although, Ktlint 0.47.0 falls back on property disabled_rules whenever ktlint_disabled_rules is not found, this result in a warning message being printed.

Default/alternative .editorconfig

Parameter "ExperimentalParams.editorConfigPath" is deprecated in favor of the new parameter "ExperimentalParams.editorConfigDefaults". When used in the old implementation this resulted in ignoring all ".editorconfig" files on the path to the file. The new implementation uses properties from the "editorConfigDefaults"parameter only when no ".editorconfig" files on the path to the file supplies this property for the filepath.

API consumers can easily create the EditConfigDefaults by calling
"EditConfigDefaults.load(path)" or creating it programmatically.

Reload of .editorconfig file

Some API Consumers keep a long-running instance of the KtLint engine alive. In case an .editorconfig file is changed, which was already loaded into the internal cache of the KtLint engine this change would not be taken into account by KtLint. One way to deal with this, was to clear the entire KtLint cache after each change in an .editorconfig file.

Now, the API consumer can reload an .editorconfig. If the .editorconfig with given path is actually found in the cached, it will be replaced with the new value directly. If the file is not yet loaded in the cache, loading will be deferred until the file is actually requested again.

Example:

KtLint.reloadEditorConfigFile("/some/path/to/.editorconfig")

Miscellaneous

Several methods for w...

Read more

0.46.1

21 Jun 20:56
c5b97a0
Compare
Choose a tag to compare

[0.46.1] - 2022-06-21

Minor release to address some regressions introduced in 0.46.0

Fixed

  • Remove experimental flag -Xuse-k2 as it forces API Consumers to compile their projects with this same flag (#1506).
  • Account for separating spaces when parsing the disabled rules (#1508).
  • Do not remove space before a comment in a parameter list (#1509).
  • A delegate property which starts on the same line as the property declaration should not have an extra indentation indent (#1510)

0.46.0

19 Jun 06:43
d5c97e6
Compare
Choose a tag to compare

[0.46.0] - 2022-06-18

Promoting experimental rules to standard

The rules below are promoted from the experimental ruleset to the standard ruleset.

  • annotation
  • annotation-spacing
  • argument-list-wrapping
  • double-colon-spacing
  • enum-entry-name-case
  • multiline-if-else
  • no-empty-first-line-in-method-block
  • package-name
  • trailing-comma
  • spacing-around-angle-brackets
  • spacing-between-declarations-with-annotations
  • spacing-between-declarations-with-comments
  • unary-op-spacing

Note that as a result of moving the rules that the prefix experimental: has to be removed from all references to this rule. Check references in:

  • The .editorconfig setting disabled_rules.
  • KtLint disable and enable directives.
  • The VisitorModifier.RunAfterRule.

If your project did not run with the experimental ruleset enabled before, you might expect new lint violations to be reported. Please note that rules can be disabled via the the .editorconfig in case you do not want the rules to be applied on your project.

API Changes & RuleSet providers

If you are not an API user nor a RuleSet provider, then you can safely skip this section. Otherwise, please read below carefully and upgrade your usage of ktlint. In this and coming releases, we are changing and adapting important parts of our API in order to increase maintainability and flexibility for future changes. Please avoid skipping a releases as that will make it harder to migrate.

Lint and formatting functions

The lint and formatting changes no longer accept parameters of type Params but only ExperimentalParams. Also, the VisitorProvider parameter has been removed. Because of this, your integration with KtLint breaks. Based on feedback with ktlint 0.45.x, we now prefer to break at compile time instead of trying to keep the interface backwards compatible. Please raise an issue, in case you help to convert to the new API.

Use of ".editorconfig" properties & userData

The interface UsesEditorConfigProperties provides method getEditorConfigValue to retrieve a named .editorconfig property for a given ASTNode. When implementing this interface, the value editorConfigProperties needs to be overridden. Previously it was not checked whether a retrieved property was actually recorded in this list. Now, retrieval of unregistered properties results in an exception.

Property Ktlint.DISABLED has been removed. The property value can now be retrieved as follows:

astNode
    .getEditorConfigValue(DefaultEditorConfigProperties.disabledRulesProperty)
    .split(",")

and be supplied via the ExperimentalParams as follows:

ExperimentalParams(
    ...
    editorConfigOverride =  EditorConfigOverride.from(
      DefaultEditorConfigProperties.disabledRulesProperty to "some-rule-id,experimental:some-other-rule-id"
    )
    ...
)

Property Ktlint.ANDROID_USER_DATA_KEY has been removed. The property value can now be retrieved as follows:

astNode
    .getEditorConfigValue(DefaultEditorConfigProperties.codeStyleProperty)

and be supplied via the ExperimentalParams as follows:

ExperimentalParams(
    ...
    editorConfigOverride =  EditorConfigOverride.from(
      DefaultEditorConfigProperties.codeStyleProperty to "android" 
    )
    ...
)

This property defaults to the official Kotlin code style when not set.

Testing KtLint rules

An AssertJ style API for testing KtLint rules (#1444) has been added. Usage of this API is encouraged in favor of using the old RuleExtension API. For more information, see KtLintAssertThat API

Added

  • Add experimental rule for unexpected spacing between function name and opening parenthesis (spacing-between-function-name-and-opening-parenthesis) (#1341)
  • Add experimental rule for unexpected spacing in the parameter list (parameter-list-spacing) (#1341)
  • Add experimental rule for incorrect spacing around the function return type (function-return-type-spacing) (#1341)
  • Add experimental rule for unexpected spaces in a nullable type (nullable-type-spacing) (#1341)
  • Do not add a space after the typealias name (type-parameter-list-spacing) (#1435)
  • Add experimental rule for consistent spacing before the start of the function body (function-start-of-body-spacing) (#1341)
  • Suppress ktlint rules using @Suppress (more information) (#765)
  • Add experimental rule for rewriting the function signature (function-signature) (#1341)

Fixed

  • Move disallowing blank lines in chained method calls from no-consecutive-blank-lines to new rule (no-blank-lines-in-chained-method-calls) (#1248)
  • Fix check of spacing in the receiver type of an anonymous function (#1440)
  • Allow comment on same line as super class in class declaration wrapping (#1457)
  • Respect git hooksPath setting (#1465)
  • Fix formatting of a property delegate with a dot-qualified-expression indent (#1340)
  • Keep formatting of for-loop in sync with default IntelliJ formatter (indent) and a newline in the expression in a for-statement should not force to wrap it wrapping (#1350)
  • Fix indentation of property getter/setter when the property has an initializer on a separate line indent (#1335)
  • When .editorconfig setting indentSize is set to value tab then return the default tab width as value for indentSize (#1485)
  • Allow suppressing all rules or a list of specific rules in the entire file with @file:Suppress(...) (#1029)

Changed

  • Update Kotlin development version to 1.7.0 and Kotlin version to 1.7.0.
  • Update shadow plugin to 7.1.2 release
  • Update picocli to 4.6.3 release
  • A file containing only one (non private) top level declaration (class, interface, object, type alias or function) must be named after that declaration. The name also must comply with the Pascal Case convention. The same applies to a file containing one single top level class declaration and one ore more extension functions for that class. filename (#1004)
  • Promote experimental rules to standard rules set: annotation, annotation-spacing, argument-list-wrapping, double-colon-spacing, enum-entry-name-case, multiline-if-else, no-empty-first-line-in-method-block, package-name, traling-comma, spacing-around-angle-brackets, spacing-between-declarations-with-annotations, spacing-between-declarations-with-comments, unary-op-spacing (#1481)
  • The CLI parameter --android can be omitted when the .editorconfig property ktlint_code_style = android is defined

0.45.2

06 Apr 16:13
343ccf4
Compare
Choose a tag to compare

[0.45.2] - 2022-04-06

Fixed

Changed

  • Set Kotlin development version to 1.6.20 and Kotlin version to 1.6.20.

0.45.1

21 Mar 16:34
c3ba877
Compare
Choose a tag to compare

[0.45.1] - 2022-03-21

Minor release to fix a breaking issue with ktlint API consumers

Fixed

  • Remove logback dependency from ktlint-core module (#1421)