Skip to content

Commit

Permalink
Support of Kotlin 2.1 and corresponding Ktlint 1.5 update
Browse files Browse the repository at this point in the history
### What's done:
- Occasionally Kotlin decided to remove several AST Nodes JetBrains/kotlin@76592dc

- There also was such kind of bug caused by Kotlin2 in ktlint pinterest/ktlint#2857

- Also removed Werror flag due to one deprecation warning which we are not able to fix

- Updated tests and Kotlin version to 2.1 in resources

- Fixed some detekt deprecation warnings

- Replaced gradle configuration with new compilerOptions API
  • Loading branch information
orchestr7 committed Dec 7, 2024
1 parent 565f00e commit cbb5506
Show file tree
Hide file tree
Showing 19 changed files with 31 additions and 107 deletions.
23 changes: 2 additions & 21 deletions detekt-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ complexity:
threshold: 10
includeStaticDeclarations: false
includePrivateDeclarations: false
ComplexMethod:
CyclomaticComplexMethod:
active: true
threshold: 15
ignoreSingleWhenExpression: false
Expand Down Expand Up @@ -253,7 +253,6 @@ naming:
parameterPattern: '[a-z][A-Za-z0-9]*'
privateParameterPattern: '[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
ignoreOverridden: true
EnumNaming:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
Expand All @@ -275,14 +274,12 @@ naming:
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)'
excludeClassPattern: '$^'
ignoreOverridden: true
ignoreAnnotated: ['Composable']
FunctionParameterNaming:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
parameterPattern: '[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
ignoreOverridden: true
InvalidPackageDeclaration:
active: false
excludes: ['*.kts']
Expand Down Expand Up @@ -328,7 +325,6 @@ naming:
variablePattern: '[a-z][A-Za-z0-9]*'
privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
ignoreOverridden: true

performance:
active: true
Expand All @@ -351,8 +347,6 @@ potential-bugs:
active: true
DontDowncastCollectionTypes:
active: true
DuplicateCaseInWhenExpression:
active: true
EqualsAlwaysReturnsTrueOrFalse:
active: true
EqualsWithHashCodeExist:
Expand All @@ -365,7 +359,7 @@ potential-bugs:
active: false
IgnoredReturnValue:
active: true
restrictToAnnotatedMethods: true
restrictToConfig: true
returnValueAnnotations: ['*.CheckReturnValue', '*.CheckResult']
ImplicitDefaultLocale:
active: false
Expand All @@ -384,13 +378,8 @@ potential-bugs:
ignoreOnClassesPattern: ''
MapGetWithNotNullAssertionOperator:
active: false
MissingWhenCase:
active: true
allowElseExpression: true
NullableToStringCall:
active: false
RedundantElseInWhen:
active: true
UnconditionalJumpStatementInLoop:
active: false
UnnecessaryNotNullOperator:
Expand Down Expand Up @@ -437,10 +426,6 @@ style:
ExpressionBodySyntax:
active: false
includeLineWrapping: false
ForbiddenComment:
active: true
values: ['TODO:', 'STOPSHIP:']
allowedPatterns: ''
ForbiddenImport:
active: false
imports: []
Expand Down Expand Up @@ -486,8 +471,6 @@ style:
ignoreEnums: false
ignoreRanges: false
ignoreExtensionFunctions: true
MandatoryBracesIfStatements:
active: false
MandatoryBracesLoops:
active: false
MaxLineLength:
Expand All @@ -512,8 +495,6 @@ style:
active: true
OptionalUnit:
active: false
OptionalWhenBraces:
active: false
PreferToOverPairSyntax:
active: false
ProtectedMemberInFinalClass:
Expand Down
2 changes: 1 addition & 1 deletion diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# or: "1, 2, 3, 4, 5, 6"
disabledChapters: ""
testDirs: test
kotlinVersion: 1.9
kotlinVersion: 2.1
srcDirectories: "main"
# Checks that the Class/Enum/Interface name matches Pascal case
- name: CLASS_NAME_INCORRECT
Expand Down
11 changes: 6 additions & 5 deletions diktat-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import com.saveourtool.diktat.buildutils.configurePom

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.getCurrentOperatingSystem
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

@Suppress("DSL_SCOPE_VIOLATION", "RUN_IN_SCRIPT") // https://github.com/gradle/gradle/issues/22797
Expand Down Expand Up @@ -31,13 +33,12 @@ dependencies {
}

tasks.withType<KotlinCompile> {
kotlinOptions {
compilerOptions {
// kotlin 1.4 api is the latest support version in kotlin 1.9
// min supported Gradle is 7.0
languageVersion = "1.4"
apiVersion = "1.4"
jvmTarget = "1.8"
freeCompilerArgs = freeCompilerArgs - "-Werror"
languageVersion.set(KotlinVersion.KOTLIN_2_0)
apiVersion.set(KotlinVersion.KOTLIN_2_0)
jvmTarget.set(JvmTarget.JVM_1_8)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.saveourtool.diktat.api.DiktatProcessorListener
import com.saveourtool.diktat.ktlint.DiktatReporterImpl.Companion.wrap

import com.pinterest.ktlint.cli.reporter.baseline.Baseline
import com.pinterest.ktlint.cli.reporter.baseline.BaselineErrorHandling
import com.pinterest.ktlint.cli.reporter.baseline.BaselineReporterProvider
import com.pinterest.ktlint.cli.reporter.baseline.loadBaseline

Expand All @@ -23,7 +24,7 @@ class DiktatBaselineFactoryImpl : DiktatBaselineFactory {
override fun tryToLoad(
baselineFile: Path,
sourceRootDir: Path?,
): DiktatBaseline? = loadBaseline(baselineFile.absolutePathString())
): DiktatBaseline? = loadBaseline(baselineFile.absolutePathString(), BaselineErrorHandling.LOG)

Check warning on line 27 in diktat-ktlint-engine/src/main/kotlin/com/saveourtool/diktat/ktlint/DiktatBaselineFactoryImpl.kt

View check run for this annotation

Codecov / codecov/patch

diktat-ktlint-engine/src/main/kotlin/com/saveourtool/diktat/ktlint/DiktatBaselineFactoryImpl.kt#L27

Added line #L27 was not covered by tests
.takeIf { it.status == Baseline.Status.VALID }
?.let { ktLintBaseline ->
DiktatBaseline { file ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class DiktatProcessorFactoryImpl : DiktatProcessorFactory {
code: Code,
callback: LintCallback,
): String {
// this API method is significantly changed in Ktlint, so -werror was disabled due to it
val formatResult = format(code)
lint(
code = Code(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class KtLintRuleWrapper(
about = about,
visitorModifiers = createVisitorModifiers(rule, prevRuleId),
) {
@Deprecated("Marked for removal in Ktlint 2.0. Please implement interface RuleAutocorrectApproveHandler.")
override fun beforeVisitChildNodes(
node: ASTNode,
autoCorrect: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ class MultipleModifiersSequence(configRules: List<RulesConfig>) : DiktatRule(
KtTokens.CROSSINLINE_KEYWORD, KtTokens.VARARG_KEYWORD, KtTokens.SUSPEND_KEYWORD, KtTokens.INNER_KEYWORD,
KtTokens.OUT_KEYWORD, KtTokens.ENUM_KEYWORD, KtTokens.ANNOTATION_KEYWORD, KtTokens.COMPANION_KEYWORD,
KtTokens.VALUE_KEYWORD, KtTokens.INLINE_KEYWORD, KtTokens.NOINLINE_KEYWORD, KtTokens.REIFIED_KEYWORD, KtTokens.INFIX_KEYWORD,
KtTokens.OPERATOR_KEYWORD, KtTokens.DATA_KEYWORD, KtTokens.IN_KEYWORD, KtTokens.HEADER_KEYWORD,
KtTokens.IMPL_KEYWORD)
KtTokens.OPERATOR_KEYWORD, KtTokens.DATA_KEYWORD, KtTokens.IN_KEYWORD)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.com.intellij.pom.PomTransaction
import org.jetbrains.kotlin.com.intellij.pom.impl.PomTransactionBase
import org.jetbrains.kotlin.com.intellij.pom.tree.TreeAspect
import org.jetbrains.kotlin.com.intellij.psi.TokenType.ERROR_ELEMENT
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.IMPORT_KEYWORD
Expand All @@ -30,7 +31,7 @@ import sun.reflect.ReflectionFactory
class KotlinParser {
private val project: Project by lazy {
val compilerConfiguration = CompilerConfiguration()
compilerConfiguration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE) // mute the output logging to process it themselves
compilerConfiguration.put(CommonConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE) // mute the output logging to process it themselves
val pomModel: PomModel = object : UserDataHolderBase(), PomModel {
override fun runTransaction(transaction: PomTransaction) {
(transaction as PomTransactionBase).run()
Expand Down
2 changes: 1 addition & 1 deletion diktat-rules/src/main/resources/diktat-analysis-huawei.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# testDirs: test
disabledChapters: ""
testDirs: test
kotlinVersion: 1.9
kotlinVersion: 2.1
srcDirectories: "main"
# Checks that the Class/Enum/Interface name matches Pascal case
- name: CLASS_NAME_INCORRECT
Expand Down
2 changes: 1 addition & 1 deletion diktat-rules/src/main/resources/diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# expected values: disabledChapters: "Naming, Comments, General, Variables, Functions, Classes"
# or: "1, 2, 3, 4, 5, 6"
disabledChapters: ""
kotlinVersion: 1.9
kotlinVersion: 2.1
srcDirectories: "main"
# Checks that the Class/Enum/Interface name matches Pascal case
- name: CLASS_NAME_INCORRECT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ import kotlin.contracts.contract

internal const val TEST_FILE_NAME = "TestFileName.kt"

private val debuggerPromptPrefixes: Array<out String> = arrayOf(
"Listening for transport dt_socket at address: ",
"Listening for transport dt_shmem at address: ",
)

/**
* Casts a nullable value to a non-`null` one, similarly to the `!!`
* operator.
Expand All @@ -43,59 +38,6 @@ internal fun <T : Any> T?.assertNotNull(lazyFailureMessage: () -> String = { "Ex
return this ?: fail(lazyFailureMessage())
}

/**
* Calls the [block] callback giving it a sequence of all the lines in this file
* and closes the reader once the processing is complete.
*
* If [filterDebuggerPrompt] is `true`, the JVM debugger prompt is filtered out
* from the sequence of lines before it is consumed by [block].
*
* If [filterDebuggerPrompt] is `false`, this function behaves exactly as the
* overloaded function from the standard library.
*
* @param filterDebuggerPrompt whether the JVM debugger prompt should be
* filtered out.
* @param block the callback which consumes the lines produced by this [Reader].
* @return the value returned by [block].
*/
@OptIn(ExperimentalContracts::class)
internal fun <T> Reader.useLines(
filterDebuggerPrompt: Boolean,
block: (Sequence<String>) -> T,
): T {
contract {
callsInPlace(block, EXACTLY_ONCE)
}

return when {
filterDebuggerPrompt -> {
/*
* Transform the line consumer.
*/
{ lines ->
lines.filterNot(String::isDebuggerPrompt).let(block)
}
}

else -> block
}.let(this::useLines)
}

private fun String.isDebuggerPrompt(printIfTrue: Boolean = true): Boolean {
val isDebuggerPrompt = debuggerPromptPrefixes.any { prefix ->
this.startsWith(prefix)
}
if (isDebuggerPrompt && printIfTrue) {
/*
* Print the prompt to the standard out,
* so that the IDE can attach to the debugger.
*/
@Suppress("DEBUG_PRINT")
println(this)
}
return isDebuggerPrompt
}

/**
* This utility function lets you run arbitrary code on every node of given [code].
* It also provides you with counter which can be incremented inside [applyToNode] and then will be compared to [expectedAsserts].
Expand Down
2 changes: 1 addition & 1 deletion examples/gradle-groovy-dsl/diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# expected values: disabledChapters: "Naming, Comments, General, Variables, Functions, Classes"
# or: "1, 2, 3, 4, 5, 6"
disabledChapters: ""
kotlinVersion: 1.9
kotlinVersion: 2.1
srcDirectories: "main"
# Checks that the Class/Enum/Interface name matches Pascal case
- name: CLASS_NAME_INCORRECT
Expand Down
2 changes: 1 addition & 1 deletion examples/gradle-kotlin-dsl-multiproject/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import com.saveourtool.diktat.plugin.gradle.DiktatExtension
import com.saveourtool.diktat.plugin.gradle.DiktatGradlePlugin

plugins {
kotlin("jvm") version "1.9.25"
kotlin("jvm") version "2.1.0"
id("com.saveourtool.diktat") version "2.0.0" apply false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# expected values: disabledChapters: "Naming, Comments, General, Variables, Functions, Classes"
# or: "1, 2, 3, 4, 5, 6"
disabledChapters: ""
kotlinVersion: 1.9
kotlinVersion: 2.1
srcDirectories: "main"
# Checks that the Class/Enum/Interface name matches Pascal case
- name: CLASS_NAME_INCORRECT
Expand Down
2 changes: 1 addition & 1 deletion examples/gradle-kotlin-dsl/diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# expected values: disabledChapters: "Naming, Comments, General, Variables, Functions, Classes"
# or: "1, 2, 3, 4, 5, 6"
disabledChapters: ""
kotlinVersion: 1.9
kotlinVersion: 2.1
srcDirectories: "main"
# Checks that the Class/Enum/Interface name matches Pascal case
- name: CLASS_NAME_INCORRECT
Expand Down
2 changes: 1 addition & 1 deletion examples/maven-multiproject/diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# expected values: disabledChapters: "Naming, Comments, General, Variables, Functions, Classes"
# or: "1, 2, 3, 4, 5, 6"
disabledChapters: ""
kotlinVersion: 1.9
kotlinVersion: 2.1
srcDirectories: "main"
# Checks that the Class/Enum/Interface name matches Pascal case
- name: CLASS_NAME_INCORRECT
Expand Down
2 changes: 1 addition & 1 deletion examples/maven/diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# expected values: disabledChapters: "Naming, Comments, General, Variables, Functions, Classes"
# or: "1, 2, 3, 4, 5, 6"
disabledChapters: ""
kotlinVersion: 1.9
kotlinVersion: 2.1
srcDirectories: "main"
# Checks that the Class/Enum/Interface name matches Pascal case
- name: CLASS_NAME_INCORRECT
Expand Down
6 changes: 3 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[versions]
kotlin = "1.9.25"
kotlin-ksp = "1.9.25-1.0.20"
kotlin = "2.1.0"
kotlin-ksp = "2.1.0-1.0.29"
serialization = "1.6.3"
ktlint = "1.0.1"
ktlint = "1.5.0"
junit = "5.10.2"
junit-platfrom = "1.10.2"
guava = "33.0.0-jre"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,17 @@ plugins {
kotlin("jvm")
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs +
"-opt-in=kotlin.RequiresOptIn" + "-Werror"
}
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(Versions.jdk))
}
}

kotlin {
compilerOptions {
optIn.add("kotlin.RequiresOptIn")
}

jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(Versions.jdk))
}
Expand Down

0 comments on commit cbb5506

Please sign in to comment.