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

Update Ktlint to v0.49.1 #1683

Merged
merged 12 commits into from
Jun 7, 2023
39 changes: 13 additions & 26 deletions diktat-api/src/main/kotlin/org/cqfn/diktat/api/DiktatError.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,17 @@ package org.cqfn.diktat.api

/**
* Error found by `diktat`
*
* @property line line number (one-based)
* @property col column number (one-based)
* @property ruleId rule id
* @property detail error message
* @property canBeAutoCorrected true if the found error can be fixed
*/
interface DiktatError {
/**
* @return line number (one-based)
*/
fun getLine(): Int

/**
* @return column number (one-based)
*/
fun getCol(): Int

/**
* @return rule id
*/
fun getRuleId(): String

/**
* @return error message
*/
fun getDetail(): String

/**
* @return true if the found error can be fixed
*/
fun canBeAutoCorrected(): Boolean
}
data class DiktatError(
val line: Int,
val col: Int,
val ruleId: String,
val detail: String,
val canBeAutoCorrected: Boolean = false,
)
1 change: 1 addition & 0 deletions diktat-cli/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies {
implementation(projects.diktatKtlintEngine)
implementation(projects.diktatRules)
implementation(libs.kotlinx.cli)
implementation(libs.kotlin.logging)
implementation(libs.log4j2.core)
implementation(libs.log4j2.slf4j2)

Expand Down
7 changes: 4 additions & 3 deletions diktat-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ dependencies {
implementation(libs.kotlinx.serialization.json)
testImplementation(libs.junit.jupiter.api)
testRuntimeOnly(libs.junit.jupiter.engine)
testImplementation(libs.ktlint.reporter.json)
testImplementation(libs.ktlint.reporter.plain)
testImplementation(libs.ktlint.reporter.sarif)
testImplementation(libs.ktlint.cli.reporter)
testImplementation(libs.ktlint.cli.reporter.json)
testImplementation(libs.ktlint.cli.reporter.plain)
testImplementation(libs.ktlint.cli.reporter.sarif)
}

tasks.withType<KotlinCompile> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package org.cqfn.diktat.plugin.gradle

import org.cqfn.diktat.ktlint.DiktatReporterImpl.Companion.unwrap
import org.cqfn.diktat.plugin.gradle.tasks.DiktatCheckTask
import com.pinterest.ktlint.reporter.json.JsonReporter
import com.pinterest.ktlint.reporter.plain.PlainReporter
import com.pinterest.ktlint.reporter.sarif.SarifReporter
import com.pinterest.ktlint.cli.reporter.json.JsonReporter
import com.pinterest.ktlint.cli.reporter.plain.PlainReporter
import com.pinterest.ktlint.cli.reporter.sarif.SarifReporter

import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
Expand Down
17 changes: 9 additions & 8 deletions diktat-ktlint-engine/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ project.description = "This module builds diktat-api implementation using ktlint
dependencies {
api(projects.diktatApi)
implementation(projects.diktatCommon)
// a temporary solution to avoid a lot of changes in diktat-rules
api(libs.ktlint.core)
implementation(libs.ktlint.reporter.baseline)
implementation(libs.ktlint.reporter.checkstyle)
implementation(libs.ktlint.reporter.html)
implementation(libs.ktlint.reporter.json)
implementation(libs.ktlint.reporter.plain)
implementation(libs.ktlint.reporter.sarif)
implementation(libs.ktlint.core)
implementation(libs.ktlint.cli.reporter)
implementation(libs.ktlint.rule.engine)
implementation(libs.ktlint.cli.reporter.baseline)
implementation(libs.ktlint.cli.reporter.checkstyle)
implementation(libs.ktlint.cli.reporter.html)
implementation(libs.ktlint.cli.reporter.json)
implementation(libs.ktlint.cli.reporter.plain)
implementation(libs.ktlint.cli.reporter.sarif)

testImplementation(libs.log4j2.slf4j2)
testImplementation(libs.junit.jupiter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import org.cqfn.diktat.api.DiktatBaseline
import org.cqfn.diktat.api.DiktatBaselineFactory
import org.cqfn.diktat.api.DiktatProcessorListener
import org.cqfn.diktat.api.DiktatProcessorListener.Companion.closeAfterAllAsProcessorListener
import org.cqfn.diktat.ktlint.DiktatErrorImpl.Companion.wrap
import org.cqfn.diktat.ktlint.DiktatReporterImpl.Companion.wrap
import com.pinterest.ktlint.core.api.Baseline
import com.pinterest.ktlint.core.api.loadBaseline
import com.pinterest.ktlint.reporter.baseline.BaselineReporter

import com.pinterest.ktlint.cli.reporter.baseline.Baseline
import com.pinterest.ktlint.cli.reporter.baseline.BaselineReporter
import com.pinterest.ktlint.cli.reporter.baseline.loadBaseline

import java.io.PrintStream
import java.nio.file.Path

import kotlin.io.path.absolutePathString
import kotlin.io.path.outputStream

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import org.cqfn.diktat.DiktatProcessor
import org.cqfn.diktat.DiktatProcessorFactory
import org.cqfn.diktat.api.DiktatCallback
import org.cqfn.diktat.api.DiktatRuleSet
import org.cqfn.diktat.ktlint.DiktatErrorImpl.Companion.wrap
import org.cqfn.diktat.ktlint.KtLintRuleWrapper.Companion.toKtLint
import com.pinterest.ktlint.core.Code
import com.pinterest.ktlint.core.KtLintRuleEngine
import com.pinterest.ktlint.core.LintError
import com.pinterest.ktlint.rule.engine.api.Code
import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine
import com.pinterest.ktlint.rule.engine.api.LintError
import java.nio.file.Path

private typealias FormatCallback = (LintError, Boolean) -> Unit
Expand Down Expand Up @@ -45,9 +44,9 @@ class DiktatProcessorFactoryImpl : DiktatProcessorFactory {
companion object {
private fun DiktatRuleSet.toKtLintEngine(): KtLintRuleEngine = KtLintRuleEngine(ruleProviders = toKtLint())

private fun Path.toKtLint(): Code = Code.CodeFile(this.toFile())
private fun Path.toKtLint(): Code = Code.fromFile(this.toFile())

private fun String.toKtLint(isScript: Boolean): Code = Code.CodeSnippet(this, isScript)
private fun String.toKtLint(isScript: Boolean): Code = Code.fromSnippet(this, isScript)

private fun DiktatCallback.toKtLintForFormat(): FormatCallback = { error, isCorrected ->
this(error.wrap(), isCorrected)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ package org.cqfn.diktat.ktlint
import org.cqfn.diktat.api.DiktatReporter
import org.cqfn.diktat.api.DiktatReporterFactory
import org.cqfn.diktat.ktlint.DiktatReporterImpl.Companion.wrap
import com.pinterest.ktlint.core.ReporterProvider
import com.pinterest.ktlint.reporter.checkstyle.CheckStyleReporterProvider
import com.pinterest.ktlint.reporter.html.HtmlReporterProvider
import com.pinterest.ktlint.reporter.json.JsonReporterProvider
import com.pinterest.ktlint.reporter.plain.Color
import com.pinterest.ktlint.reporter.plain.PlainReporterProvider
import com.pinterest.ktlint.reporter.sarif.SarifReporterProvider
import com.pinterest.ktlint.cli.reporter.checkstyle.CheckStyleReporterProvider
import com.pinterest.ktlint.cli.reporter.html.HtmlReporterProvider
import com.pinterest.ktlint.cli.reporter.json.JsonReporterProvider
import com.pinterest.ktlint.cli.reporter.plain.Color
import com.pinterest.ktlint.cli.reporter.plain.PlainReporterProvider
import com.pinterest.ktlint.cli.reporter.sarif.SarifReporterProvider
import java.io.OutputStream
import java.io.PrintStream
import java.nio.file.Path
Expand All @@ -22,7 +21,7 @@ class DiktatReporterFactoryImpl : DiktatReporterFactory {
private val plainReporterProvider = PlainReporterProvider()

/**
* All [ReporterProvider] which __KtLint__ provides
* All reporters which __KtLint__ provides
*/
private val reporterProviders = setOf(
plainReporterProvider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package org.cqfn.diktat.ktlint

import org.cqfn.diktat.api.DiktatError
import org.cqfn.diktat.api.DiktatReporter
import org.cqfn.diktat.ktlint.DiktatErrorImpl.Companion.unwrap
import com.pinterest.ktlint.core.Reporter
import com.pinterest.ktlint.cli.reporter.core.api.ReporterV2
import java.nio.file.Path

/**
* [DiktatReporter] using __KtLint__
*/
class DiktatReporterImpl(
private val ktLintReporter: Reporter,
private val ktLintReporter: ReporterV2,
private val sourceRootDir: Path,
) : DiktatReporter {
override fun beforeAll(files: Collection<Path>): Unit = ktLintReporter.beforeAll()
Expand All @@ -19,21 +18,21 @@ class DiktatReporterImpl(
file: Path,
error: DiktatError,
isCorrected: Boolean,
): Unit = ktLintReporter.onLintError(file.relativePathStringTo(sourceRootDir), error.unwrap(), isCorrected)
): Unit = ktLintReporter.onLintError(file.relativePathStringTo(sourceRootDir), error.toKtLintForCli())
override fun after(file: Path): Unit = ktLintReporter.after(file.relativePathStringTo(sourceRootDir))
override fun afterAll(): Unit = ktLintReporter.afterAll()

companion object {
/**
* @param sourceRootDir
* @return [DiktatReporter] which wraps __KtLint__'s [Reporter]
* @return [DiktatReporter] which wraps __KtLint__'s [ReporterV2]
*/
fun Reporter.wrap(sourceRootDir: Path): DiktatReporter = DiktatReporterImpl(this, sourceRootDir)
fun ReporterV2.wrap(sourceRootDir: Path): DiktatReporter = DiktatReporterImpl(this, sourceRootDir)

/**
* @return __KtLint__'s [Reporter]
* @return __KtLint__'s [ReporterV2]
*/
fun DiktatReporter.unwrap(): Reporter = (this as? DiktatReporterImpl)?.ktLintReporter
fun DiktatReporter.unwrap(): ReporterV2 = (this as? DiktatReporterImpl)?.ktLintReporter
?: error("Unsupported wrapper of ${DiktatReporter::class.java.simpleName}: ${this::class.java.canonicalName}")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package org.cqfn.diktat.ktlint
import org.cqfn.diktat.api.DiktatRule
import org.cqfn.diktat.api.DiktatRuleSet
import org.cqfn.diktat.common.config.rules.DIKTAT_RULE_SET_ID
import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.RuleProvider
import com.pinterest.ktlint.rule.engine.core.api.Rule
import com.pinterest.ktlint.rule.engine.core.api.Rule.VisitorModifier.RunAfterRule.Mode
import com.pinterest.ktlint.rule.engine.core.api.RuleId
import com.pinterest.ktlint.rule.engine.core.api.RuleProvider
import org.jetbrains.kotlin.com.intellij.lang.ASTNode

private typealias EmitType = (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit
Expand All @@ -15,57 +17,61 @@ private typealias EmitType = (offset: Int, errorMessage: String, canBeAutoCorrec
*/
class KtLintRuleWrapper(
val rule: DiktatRule,
prevRule: KtLintRuleWrapper? = null,
prevRuleId: RuleId? = null,
) : Rule(
id = rule.id.qualifiedWithRuleSetId(DIKTAT_RULE_SET_ID),
visitorModifiers = createVisitorModifiers(rule, prevRule),
ruleId = rule.id.toRuleId(DIKTAT_RULE_SET_ID),
about = about,
visitorModifiers = createVisitorModifiers(rule, prevRuleId),
) {
override fun beforeVisitChildNodes(
node: ASTNode,
autoCorrect: Boolean,
emit: EmitType,
) = rule.invoke(node, autoCorrect, emit)
) = rule.invoke(node, autoCorrect) { offset, errorMessage, canBeAutoCorrected ->
emit.invoke(offset, errorMessage.correctErrorDetail(canBeAutoCorrected), canBeAutoCorrected)
}

companion object {
private fun Sequence<DiktatRule>.wrapRules(): Sequence<Rule> = runningFold(null as KtLintRuleWrapper?) { prevRule, diktatRule ->
KtLintRuleWrapper(diktatRule, prevRule)
private val about: About = About(
maintainer = "Diktat",
repositoryUrl = "https://github.com/saveourtool/diktat",
issueTrackerUrl = "https://github.com/saveourtool/diktat/issues",
)

private fun Sequence<DiktatRule>.wrapRulesToProviders(): Sequence<RuleProvider> = runningFold(null as RuleProvider?) { prevRuleProvider, diktatRule ->
val prevRuleId = prevRuleProvider?.ruleId?.value?.toRuleId(DIKTAT_RULE_SET_ID)
RuleProvider(
provider = { KtLintRuleWrapper(diktatRule, prevRuleId) },
)
}.filterNotNull()

/**
* @return [Set] of __KtLint__'s [RuleProvider]s created from [DiktatRuleSet]
*/
fun DiktatRuleSet.toKtLint(): Set<RuleProvider> = rules
.asSequence()
.wrapRules()
.map { it.asProvider() }
.wrapRulesToProviders()
.toSet()

private fun createVisitorModifiers(
rule: DiktatRule,
prevRule: KtLintRuleWrapper?,
): Set<VisitorModifier> = prevRule?.id?.qualifiedWithRuleSetId(DIKTAT_RULE_SET_ID)
?.let { previousRuleId ->
val ruleId = rule.id.qualifiedWithRuleSetId(DIKTAT_RULE_SET_ID)
require(ruleId != previousRuleId) {
"PrevRule has same ID as rule: $ruleId"
}
setOf(
VisitorModifier.RunAfterRule(
ruleId = previousRuleId,
loadOnlyWhenOtherRuleIsLoaded = false,
runOnlyWhenOtherRuleIsEnabled = false
)
prevRuleId: RuleId?,
): Set<VisitorModifier> = prevRuleId?.run {
val ruleId = rule.id.toRuleId(DIKTAT_RULE_SET_ID)
require(ruleId != prevRuleId) {
"PrevRule has same ID as rule: $ruleId"
}
setOf(
VisitorModifier.RunAfterRule(
ruleId = prevRuleId,
mode = Mode.REGARDLESS_WHETHER_RUN_AFTER_RULE_IS_LOADED_OR_DISABLED
)
} ?: emptySet()
)
} ?: emptySet()

/**
* @return a rule to which a logic is delegated
*/
internal fun Rule.unwrap(): DiktatRule = (this as? KtLintRuleWrapper)?.rule ?: error("Provided rule ${javaClass.simpleName} is not wrapped by diktat")

/**
* @return wraps [Rule] to [RuleProvider]
*/
internal fun Rule.asProvider(): RuleProvider = RuleProvider { this }
}
}
Loading