Skip to content

Commit 1d898d0

Browse files
authored
Merge branch 'main' into fix-expand-wildcard-jdk-xml-types
2 parents f0930b5 + a2acb39 commit 1d898d0

13 files changed

Lines changed: 92 additions & 17 deletions

File tree

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
1414
- Add `versionCatalog` step for formatting and sorting Gradle version catalog (`.toml`) files. ([#2916](https://github.com/diffplug/spotless/issues/2916))
1515
- Add `javaparserVersion` option to the Cleanthat step, allowing callers to override the JavaParser version pulled in transitively by Cleanthat. ([#2903](https://github.com/diffplug/spotless/pull/2903))
1616
### Fixed
17+
- Preserve case of JDBI named bind params that collide with SQL keywords (e.g. `:limit`, `:offset`) in the DBeaver SQL formatter. ([#2899](https://github.com/diffplug/spotless/pull/2899))
1718
- Fix non-idempotent formatting when `importOrder()` is combined with `greclipse()`: a single catch-all group no longer strips blank lines that `greclipse()` independently inserted between import groups. ([#2914](https://github.com/diffplug/spotless/pull/2914))
1819
### Changes
1920
- Fix `expandWildcardImports` failing on JDK XML types such as `org.xml.sax.InputSource`. ([#2921](https://github.com/diffplug/spotless/pull/2921))
21+
- Use Eclipse JDT's collator-based comparison when sorting Java members to better match Eclipse save actions. ([#2920](https://github.com/diffplug/spotless/pull/2920))
2022
- Bump default `cleanthat` version `2.24` -> `2.25`. ([#2903](https://github.com/diffplug/spotless/pull/2903))
2123
- Bump default `eclipse-jdt` version from `4.35` to `4.39`. ([#2912](https://github.com/diffplug/spotless/pull/2912))
2224

lib-extra/src/jdt/java/com/diffplug/spotless/extra/glue/jdt/DefaultJavaElementComparator.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024-2025 DiffPlug
2+
* Copyright 2024-2026 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
1515
*/
1616
package com.diffplug.spotless.extra.glue.jdt;
1717

18+
import java.text.Collator;
1819
import java.util.Comparator;
1920
import java.util.List;
2021
import java.util.StringTokenizer;
@@ -61,6 +62,7 @@ class DefaultJavaElementComparator implements Comparator<BodyDeclaration> {
6162
private final int[] memberCategoryOffsets;
6263
private final boolean sortByVisibility;
6364
private final int[] visibilityOffsets;
65+
private final Collator collator;
6466

6567
static DefaultJavaElementComparator of(
6668
boolean doNotSortFields,
@@ -95,6 +97,7 @@ static DefaultJavaElementComparator of(
9597
this.memberCategoryOffsets = memberCategoryOffsets;
9698
this.sortByVisibility = sortByVisibility;
9799
this.visibilityOffsets = visibilityOffsets;
100+
this.collator = Collator.getInstance();
98101
}
99102

100103
@SuppressFBWarnings(value = "SF_SWITCH_NO_DEFAULT", justification = "we only accept valid tokens in the order string, otherwise we fall back to default value")
@@ -271,7 +274,7 @@ public int compare(BodyDeclaration bodyDeclaration1, BodyDeclaration bodyDeclara
271274
String name2 = method2.getName().getIdentifier();
272275

273276
// method declarations (constructors) are sorted by name
274-
int cmp = name1.compareTo(name2);
277+
int cmp = collator.compare(name1, name2);
275278
if (cmp != 0) {
276279
return cmp;
277280
}
@@ -286,7 +289,7 @@ public int compare(BodyDeclaration bodyDeclaration1, BodyDeclaration bodyDeclara
286289
for (int i = 0; i < len; i++) {
287290
SingleVariableDeclaration param1 = parameters1.get(i);
288291
SingleVariableDeclaration param2 = parameters2.get(i);
289-
cmp = buildSignature(param1.getType()).compareTo(buildSignature(param2.getType()));
292+
cmp = collator.compare(buildSignature(param1.getType()), buildSignature(param2.getType()));
290293
if (cmp != 0) {
291294
return cmp;
292295
}
@@ -377,7 +380,7 @@ private int preserveRelativeOrder(BodyDeclaration bodyDeclaration1, BodyDeclarat
377380
}
378381

379382
private int compareNames(BodyDeclaration bodyDeclaration1, BodyDeclaration bodyDeclaration2, String name1, String name2) {
380-
int cmp = name1.compareTo(name2);
383+
int cmp = collator.compare(name1, name2);
381384
if (cmp != 0) {
382385
return cmp;
383386
}

lib-extra/src/test/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStepSpecialCaseTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,12 @@ void sort_members_local_enabled_true() {
107107
StepHarness.forStep(builder.build())
108108
.testResource("java/eclipse/SortExample.localEnabledTrue.test", "java/eclipse/SortExample.localEnabledTrue.clean");
109109
}
110+
111+
@Test
112+
void sort_members_uses_collator() {
113+
EclipseJdtFormatterStep.Builder builder = EclipseJdtFormatterStep.createBuilder(TestProvisioner.mavenCentral(), TestP2Provisioner.defaultProvisioner());
114+
builder.sortMembersEnabled(true);
115+
StepHarness.forStep(builder.build())
116+
.testResource("java/eclipse/SortExample.collator.test", "java/eclipse/SortExample.collator.clean");
117+
}
110118
}

lib/src/main/java/com/diffplug/spotless/sql/dbeaver/SQLTokenizedFormatter.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2025 DiffPlug
2+
* Copyright 2016-2026 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -95,9 +95,13 @@ private List<FormatterToken> format(final List<FormatterToken> argList) {
9595
}
9696

9797
final KeywordCase keywordCase = formatterCfg.getKeywordCase();
98-
for (FormatterToken anArgList : argList) {
99-
token = anArgList;
98+
for (int index = 0; index < argList.size(); index++) {
99+
token = argList.get(index);
100100
if (token.getType() == TokenType.KEYWORD) {
101+
// Do not transform case for JDBI named bind params (e.g. :limit, :offset)
102+
if (index > 0 && isEmbeddedToken(argList.get(index - 1))) {
103+
continue;
104+
}
101105
token.setString(keywordCase.transform(token.getString()));
102106
}
103107
}
@@ -323,8 +327,10 @@ private List<FormatterToken> format(final List<FormatterToken> argList) {
323327
continue;
324328
}
325329
if (token.getType() == TokenType.SYMBOL && isEmbeddedToken(token)
330+
&& (!":".equals(token.getString()) || prev.getType() == TokenType.SYMBOL)
326331
|| prev.getType() == TokenType.SYMBOL && isEmbeddedToken(prev)) {
327-
// Do not insert spaces around colons
332+
// Do not insert spaces around embedded tokens (colons, dots),
333+
// except before JDBI named bind params (e.g. :limit) preceded by a keyword or name
328334
continue;
329335
}
330336
if (token.getType() == TokenType.SYMBOL && prev.getType() == TokenType.SYMBOL) {

plugin-gradle/CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
99
- Add `javaparserVersion(...)` to `cleanthat`, allowing users to override the JavaParser version pulled in transitively by Cleanthat. ([#2903](https://github.com/diffplug/spotless/pull/2903))
1010
### Fixed
1111
- Fix `tableTestFormatter` editorconfig cache not honoring `.editorconfig` changes across Gradle daemon runs due to a shared static `EditorConfigProvider`. ([#2893](https://github.com/diffplug/spotless/pull/2893))
12+
- Preserve case of JDBI named bind params that collide with SQL keywords (e.g. `:limit`, `:offset`) in the DBeaver SQL formatter. ([#2899](https://github.com/diffplug/spotless/pull/2899))
1213
- Fix non-idempotent formatting when `importOrder()` is combined with `greclipse()`: a single catch-all group no longer strips blank lines that `greclipse()` independently inserted between import groups. ([#2914](https://github.com/diffplug/spotless/pull/2914))
1314
- Fix `predeclareDepsFromBuildscript()` on Gradle 9 by avoiding mutation of the root buildscript configuration container. ([#2929](https://github.com/diffplug/spotless/pull/2929), fixes [#2599](https://github.com/diffplug/spotless/issues/2599))
1415
### Changes
1516
- Fix `expandWildcardImports` failing on JDK XML types such as `org.xml.sax.InputSource`. ([#2921](https://github.com/diffplug/spotless/pull/2921))
17+
- Use Eclipse JDT's collator-based comparison when sorting Java members to better match Eclipse save actions. ([#2920](https://github.com/diffplug/spotless/pull/2920))
1618
- Bump default `cleanthat` version `2.24` -> `2.25`. ([#2903](https://github.com/diffplug/spotless/pull/2903))
1719
- Bump default `eclipse-jdt` version from `4.35` to `4.39`. ([#2912](https://github.com/diffplug/spotless/pull/2912))
1820
- Make `spotlessPredeclare` visible to Gradle Kotlin DSL type-safe accessors. ([#2925](https://github.com/diffplug/spotless/pull/2925))

plugin-maven/CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
77
- Add `<toml>` format type with `<versionCatalog>` step for formatting and sorting Gradle version catalog files. ([#2916](https://github.com/diffplug/spotless/issues/2916))
88
- Add `<javaparserVersion>` option to `<cleanthat>`, allowing users to override the JavaParser version pulled in transitively by Cleanthat. ([#2903](https://github.com/diffplug/spotless/pull/2903))
99
### Fixed
10+
- Preserve case of JDBI named bind params that collide with SQL keywords (e.g. `:limit`, `:offset`) in the DBeaver SQL formatter. ([#2899](https://github.com/diffplug/spotless/pull/2899))
11+
- The `-Dspotless.ratchetFrom=...` user property now takes priority over `<ratchetFrom>` configured in the plugin or in individual formatters, instead of being overridden by them. ([#2896](https://github.com/diffplug/spotless/pull/2896), fixes [#2842](https://github.com/diffplug/spotless/issues/2842))
1012
- Fix non-idempotent formatting when `importOrder()` is combined with `greclipse()`: a single catch-all group no longer strips blank lines that `greclipse()` independently inserted between import groups. ([#2914](https://github.com/diffplug/spotless/pull/2914))
1113
### Changes
1214
- Fix `expandWildcardImports` failing on JDK XML types such as `org.xml.sax.InputSource`. ([#2921](https://github.com/diffplug/spotless/pull/2921))
15+
- Use Eclipse JDT's collator-based comparison when sorting Java members to better match Eclipse save actions. ([#2920](https://github.com/diffplug/spotless/pull/2920))
1316
- Bump default `cleanthat` version `2.24` -> `2.25`. ([#2903](https://github.com/diffplug/spotless/pull/2903))
1417
- Bump default `eclipse-jdt` version from `4.35` to `4.39`. ([#2912](https://github.com/diffplug/spotless/pull/2912))
1518

plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.stream.Stream;
4040
import java.util.stream.StreamSupport;
4141

42+
import org.apache.maven.execution.MavenSession;
4243
import org.apache.maven.plugin.AbstractMojo;
4344
import org.apache.maven.plugin.MojoExecutionException;
4445
import org.apache.maven.plugins.annotations.Component;
@@ -108,6 +109,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
108109
@Component
109110
protected BuildContext buildContext;
110111

112+
@Component
113+
private MavenSession mavenSession;
114+
111115
@Parameter(defaultValue = "${mojoExecution.goal}", required = true, readonly = true)
112116
private String goal;
113117

@@ -405,9 +409,10 @@ private FormatterConfig getFormatterConfig() {
405409
P2Provisioner p2Provisioner = P2Provisioner.createDefault();
406410
List<FormatterStepFactory> formatterStepFactories = getFormatterStepFactories();
407411
FileLocator fileLocator = getFileLocator();
412+
final Optional<String> userRatchetFrom = Optional.ofNullable((String) mavenSession.getUserProperties().get("ratchetFrom"));
408413
final Optional<String> optionalRatchetFrom = Optional.ofNullable(this.ratchetFrom)
409414
.filter(ratchet -> !RATCHETFROM_NONE.equals(ratchet));
410-
return new FormatterConfig(baseDir, encoding, lineEndings, optionalRatchetFrom, provisioner, p2Provisioner, fileLocator, formatterStepFactories, Optional.ofNullable(setLicenseHeaderYearsFromGitHistory), lintSuppressions);
415+
return new FormatterConfig(baseDir, encoding, lineEndings, userRatchetFrom, optionalRatchetFrom, provisioner, p2Provisioner, fileLocator, formatterStepFactories, Optional.ofNullable(setLicenseHeaderYearsFromGitHistory), lintSuppressions);
411416
}
412417

413418
private FileLocator getFileLocator() {

plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class FormatterConfig {
3030

3131
private final String encoding;
3232
private final LineEnding lineEndings;
33+
private final Optional<String> userRatchetFrom;
3334
private final Optional<String> ratchetFrom;
3435
private final Provisioner provisioner;
3536
private final P2Provisioner p2Provisioner;
@@ -38,10 +39,11 @@ public class FormatterConfig {
3839
private final Optional<String> spotlessSetLicenseHeaderYearsFromGitHistory;
3940
private final List<LintSuppression> lintSuppressions;
4041

41-
public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Optional<String> ratchetFrom, Provisioner provisioner,
42+
public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Optional<String> userRatchetFrom, Optional<String> ratchetFrom, Provisioner provisioner,
4243
P2Provisioner p2Provisioner, FileLocator fileLocator, List<FormatterStepFactory> globalStepFactories, Optional<String> spotlessSetLicenseHeaderYearsFromGitHistory, List<LintSuppression> lintSuppressions) {
4344
this.encoding = encoding;
4445
this.lineEndings = lineEndings;
46+
this.userRatchetFrom = userRatchetFrom;
4547
this.ratchetFrom = ratchetFrom;
4648
this.provisioner = provisioner;
4749
this.p2Provisioner = p2Provisioner;
@@ -59,6 +61,10 @@ public LineEnding getLineEndings() {
5961
return lineEndings;
6062
}
6163

64+
public Optional<String> getUserRatchetFrom() {
65+
return userRatchetFrom;
66+
}
67+
6268
public Optional<String> getRatchetFrom() {
6369
return ratchetFrom;
6470
}

plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,15 @@ private LineEnding lineEndings(FormatterConfig config) {
175175
}
176176

177177
Optional<String> ratchetFrom(FormatterConfig config) {
178-
if (RATCHETFROM_NOT_SET_AT_FORMAT_LEVEL.equals(ratchetFrom)) {
179-
return config.getRatchetFrom();
180-
} else if (RATCHETFROM_NONE.equals(ratchetFrom)) {
181-
return Optional.empty();
182-
} else {
183-
return Optional.ofNullable(ratchetFrom);
184-
}
178+
return config.getUserRatchetFrom()
179+
.or(this::optionalRatchetFrom)
180+
.or(config::getRatchetFrom)
181+
.filter(ratchet -> !RATCHETFROM_NONE.equals(ratchet));
182+
}
183+
184+
private Optional<String> optionalRatchetFrom() {
185+
return Optional.ofNullable(ratchetFrom)
186+
.filter(ratchet -> !RATCHETFROM_NOT_SET_AT_FORMAT_LEVEL.equals(ratchet));
185187
}
186188

187189
private FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.diffplug.spotless.extra.glue.jdt;
2+
3+
public class SortExample {
4+
private static void mab() {
5+
}
6+
7+
private static void mAc() {
8+
}
9+
10+
private static void mp(String a, String b, int a) {
11+
}
12+
13+
private static void mp(String a, String b, String p) {
14+
}
15+
}

0 commit comments

Comments
 (0)