diff --git a/lib/build.gradle b/lib/build.gradle index e398e80d23..8a816c61aa 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -34,6 +34,7 @@ versionCompatibility { '0.45.2', '0.46.0', '0.47.0', + '0.48.0', ] targetSourceSetName = 'ktlint' } @@ -90,6 +91,9 @@ dependencies { compatKtLint0Dot47Dot0CompileOnly 'com.pinterest.ktlint:ktlint-core:0.47.0' compatKtLint0Dot47Dot0CompileOnly 'com.pinterest.ktlint:ktlint-ruleset-experimental:0.47.0' compatKtLint0Dot47Dot0CompileOnly 'com.pinterest.ktlint:ktlint-ruleset-standard:0.47.0' + compatKtLint0Dot48Dot0CompileOnly 'com.pinterest.ktlint:ktlint-core:0.48.0' + compatKtLint0Dot48Dot0CompileOnly 'com.pinterest.ktlint:ktlint-ruleset-experimental:0.48.0' + compatKtLint0Dot48Dot0CompileOnly 'com.pinterest.ktlint:ktlint-ruleset-standard:0.48.0' String VER_SCALAFMT="3.6.1" scalafmtCompileOnly "org.scalameta:scalafmt-core_2.13:$VER_SCALAFMT" diff --git a/lib/src/compatKtLint0Dot48Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot48Dot0Adapter.java b/lib/src/compatKtLint0Dot48Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot48Dot0Adapter.java new file mode 100644 index 0000000000..921079b3e7 --- /dev/null +++ b/lib/src/compatKtLint0Dot48Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot48Dot0Adapter.java @@ -0,0 +1,126 @@ +/* + * Copyright 2022 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.glue.ktlint.compat; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.pinterest.ktlint.core.KtLint; +import com.pinterest.ktlint.core.LintError; +import com.pinterest.ktlint.core.Rule; +import com.pinterest.ktlint.core.RuleProvider; +import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties; +import com.pinterest.ktlint.core.api.EditorConfigDefaults; +import com.pinterest.ktlint.core.api.EditorConfigOverride; +import com.pinterest.ktlint.core.api.UsesEditorConfigProperties; +import com.pinterest.ktlint.core.api.editorconfig.EditorConfigProperty; +import com.pinterest.ktlint.ruleset.experimental.ExperimentalRuleSetProvider; +import com.pinterest.ktlint.ruleset.standard.StandardRuleSetProvider; + +import kotlin.Pair; +import kotlin.Unit; +import kotlin.jvm.functions.Function2; + +public class KtLintCompat0Dot48Dot0Adapter implements KtLintCompatAdapter { + + static class FormatterCallback implements Function2 { + @Override + public Unit invoke(LintError lint, Boolean corrected) { + if (!corrected) { + KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail()); + } + return null; + } + } + + @Override + public String format(final String text, final String name, final boolean isScript, + final boolean useExperimental, + final Map userData, + final Map editorConfigOverrideMap) { + final FormatterCallback formatterCallback = new FormatterCallback(); + + Set allRuleProviders = new LinkedHashSet<>( + new StandardRuleSetProvider().getRuleProviders()); + if (useExperimental) { + allRuleProviders.addAll(new ExperimentalRuleSetProvider().getRuleProviders()); + } + + EditorConfigOverride editorConfigOverride; + if (editorConfigOverrideMap.isEmpty()) { + editorConfigOverride = EditorConfigOverride.Companion.getEmptyEditorConfigOverride(); + } else { + editorConfigOverride = createEditorConfigOverride(allRuleProviders.stream().map( + RuleProvider::createNewRuleInstance).collect( + Collectors.toList()), + editorConfigOverrideMap); + } + + return KtLint.INSTANCE.format(new KtLint.ExperimentalParams( + name, + text, + allRuleProviders, + userData, + formatterCallback, + isScript, + false, + EditorConfigDefaults.Companion.getEmptyEditorConfigDefaults(), + editorConfigOverride, + false)); + } + + /** + * Create EditorConfigOverride from user provided parameters. + */ + private static EditorConfigOverride createEditorConfigOverride(final List rules, Map editorConfigOverrideMap) { + // Get properties from rules in the rule sets + Stream> ruleProperties = rules.stream() + .filter(rule -> rule instanceof UsesEditorConfigProperties) + .flatMap(rule -> ((UsesEditorConfigProperties) rule).getEditorConfigProperties().stream()); + + // get complete list of supported properties in DefaultEditorConfigProperties.INSTANCE + List> editorConfigProperties = new ArrayList<>(DefaultEditorConfigProperties.INSTANCE.getEditorConfigProperties()); + editorConfigProperties.add(DefaultEditorConfigProperties.INSTANCE.getKtlintDisabledRulesProperty()); + + // Create a mapping of properties to their names based on rule properties and default properties + Map> supportedProperties = Stream + .concat(ruleProperties, editorConfigProperties.stream()) + .distinct() + .collect(Collectors.toMap(EditorConfigProperty::getName, property -> property)); + + // Create config properties based on provided property names and values + @SuppressWarnings("unchecked") + Pair, ?>[] properties = editorConfigOverrideMap.entrySet().stream() + .map(entry -> { + EditorConfigProperty property = supportedProperties.get(entry.getKey()); + if (property != null) { + return new Pair<>(property, entry.getValue()); + } else { + return null; + } + }) + .filter(Objects::nonNull) + .toArray(Pair[]::new); + + return EditorConfigOverride.Companion.from(properties); + } +} diff --git a/lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java b/lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java index cc64eb9d66..45c5c5e4cf 100644 --- a/lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java +++ b/lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java @@ -27,6 +27,7 @@ import com.diffplug.spotless.glue.ktlint.compat.KtLintCompat0Dot45Dot2Adapter; import com.diffplug.spotless.glue.ktlint.compat.KtLintCompat0Dot46Dot0Adapter; import com.diffplug.spotless.glue.ktlint.compat.KtLintCompat0Dot47Dot0Adapter; +import com.diffplug.spotless.glue.ktlint.compat.KtLintCompat0Dot48Dot0Adapter; import com.diffplug.spotless.glue.ktlint.compat.KtLintCompatAdapter; public class KtlintFormatterFunc implements FormatterFunc.NeedsFile { @@ -41,7 +42,10 @@ public class KtlintFormatterFunc implements FormatterFunc.NeedsFile { public KtlintFormatterFunc(String version, boolean isScript, boolean useExperimental, Map userData, Map editorConfigOverrideMap) { int minorVersion = Integer.parseInt(version.split("\\.")[1]); - if (minorVersion >= 47) { + if (minorVersion >= 48) { + // ExperimentalParams lost two constructor arguments, EditorConfigProperty moved to its own class + this.adapter = new KtLintCompat0Dot48Dot0Adapter(); + } else if (minorVersion == 47) { // rename RuleSet to RuleProvider this.adapter = new KtLintCompat0Dot47Dot0Adapter(); } else if (minorVersion >= 46) { diff --git a/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java b/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java index 5627913e4a..f62c62b05b 100644 --- a/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java +++ b/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java @@ -33,7 +33,7 @@ public class KtLintStep { // prevent direct instantiation private KtLintStep() {} - private static final String DEFAULT_VERSION = "0.47.1"; + private static final String DEFAULT_VERSION = "0.48.0"; static final String NAME = "ktlint"; static final String PACKAGE_PRE_0_32 = "com.github.shyiko"; static final String PACKAGE = "com.pinterest"; diff --git a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java index 71a0979422..3a55a19e92 100644 --- a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java @@ -144,6 +144,19 @@ void works0_47_1() throws Exception { }); } + @Test + void works0_48_0() throws Exception { + FormatterStep step = KtLintStep.create("0.48.0", TestProvisioner.mavenCentral()); + StepHarness.forStep(step) + .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") + .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { + assertion.isInstanceOf(AssertionError.class); + assertion.hasMessage("Error on line: 1, column: 1\n" + + "rule: no-wildcard-imports\n" + + "Wildcard import"); + }); + } + @Test void equality() throws Exception { new SerializableEqualityTester() {