Skip to content

Commit d026161

Browse files
authored
Serializable Groovy, Java, Kotlin, and Scala steps (#2033)
2 parents 2e33d3b + 8557a52 commit d026161

16 files changed

+328
-188
lines changed

lib-extra/src/main/java/com/diffplug/spotless/extra/EclipseBasedStepBuilder.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.diffplug.spotless.FormatterStep;
3434
import com.diffplug.spotless.JarState;
3535
import com.diffplug.spotless.Provisioner;
36+
import com.diffplug.spotless.RoundedStep;
3637
import com.diffplug.spotless.SerializedFunction;
3738

3839
/**
@@ -126,7 +127,7 @@ public void setPreferences(Iterable<File> settingsFiles) {
126127
this.settingsFiles = settingsFiles;
127128
}
128129

129-
static class EclipseStep implements Serializable {
130+
static class EclipseStep implements RoundedStep {
130131
private static final long serialVersionUID = 1;
131132
private final String semanticVersion;
132133
private final String formatterStepExt;

lib-extra/src/main/java/com/diffplug/spotless/extra/EquoBasedStepBuilder.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.diffplug.spotless.FormatterStep;
3535
import com.diffplug.spotless.JarState;
3636
import com.diffplug.spotless.Provisioner;
37+
import com.diffplug.spotless.RoundedStep;
3738
import com.diffplug.spotless.SerializedFunction;
3839

3940
import dev.equo.solstice.NestedJars;
@@ -149,7 +150,7 @@ private P2Model createModelWithMirrors() {
149150
return model;
150151
}
151152

152-
static class EquoStep implements Serializable {
153+
static class EquoStep implements RoundedStep {
153154
private static final long serialVersionUID = 1;
154155
private final String semanticVersion;
155156
private final FileSignature.Promised settingsPromise;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless;
17+
18+
import java.io.Serializable;
19+
20+
public interface RoundedStep extends Serializable {}

lib/src/main/java/com/diffplug/spotless/generic/IndentStep.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
*/
1616
package com.diffplug.spotless.generic;
1717

18-
import java.io.Serializable;
19-
2018
import com.diffplug.spotless.FormatterFunc;
2119
import com.diffplug.spotless.FormatterStep;
20+
import com.diffplug.spotless.RoundedStep;
2221
import com.diffplug.spotless.SerializedFunction;
2322

2423
/** Simple step which checks for consistent indentation characters. */
25-
public final class IndentStep implements Serializable {
24+
public final class IndentStep implements RoundedStep {
2625
private static final long serialVersionUID = 1L;
2726

2827
final Type type;

lib/src/main/java/com/diffplug/spotless/groovy/RemoveSemicolonsStep.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 DiffPlug
2+
* Copyright 2023-2024 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.
@@ -21,23 +21,25 @@
2121

2222
import com.diffplug.spotless.FormatterFunc;
2323
import com.diffplug.spotless.FormatterStep;
24+
import com.diffplug.spotless.RoundedStep;
2425

2526
/**
2627
* Removes all semicolons from the end of lines.
2728
*
2829
* @author Jose Luis Badano
2930
*/
30-
public final class RemoveSemicolonsStep {
31+
public final class RemoveSemicolonsStep implements RoundedStep {
32+
private static final long serialVersionUID = 1L;
3133
private static final String NAME = "Remove unnecessary semicolons";
3234

3335
private RemoveSemicolonsStep() {
3436
// do not instantiate
3537
}
3638

3739
public static FormatterStep create() {
38-
return FormatterStep.createLazy(NAME,
39-
State::new,
40-
RemoveSemicolonsStep.State::toFormatter);
40+
return FormatterStep.create(NAME,
41+
new State(),
42+
State::toFormatter);
4143
}
4244

4345
private static final class State implements Serializable {
@@ -64,7 +66,7 @@ FormatterFunc toFormatter() {
6466
* @return the line without the last semicolon
6567
*/
6668
private String removeSemicolon(String line) {
67-
// find last semicolon in a string a remove it
69+
// Find the last semicolon in a string and remove it.
6870
int lastSemicolon = line.lastIndexOf(";");
6971
if (lastSemicolon != -1 && lastSemicolon == line.length() - 1) {
7072
return line.substring(0, lastSemicolon);
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 DiffPlug
2+
* Copyright 2023-2024 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,7 +15,6 @@
1515
*/
1616
package com.diffplug.spotless.java;
1717

18-
import java.io.IOException;
1918
import java.io.Serializable;
2019
import java.lang.reflect.Constructor;
2120
import java.lang.reflect.Method;
@@ -27,30 +26,51 @@
2726
import com.diffplug.spotless.JarState;
2827
import com.diffplug.spotless.Jvm;
2928
import com.diffplug.spotless.Provisioner;
29+
import com.diffplug.spotless.RoundedStep;
3030

3131
/**
3232
* Enables CleanThat as a SpotLess step.
3333
*
3434
* @author Benoit Lacelle
3535
*/
3636
// https://github.com/diffplug/spotless/blob/main/CONTRIBUTING.md#how-to-add-a-new-formatterstep
37-
public final class CleanthatJavaStep {
38-
37+
public final class CleanthatJavaStep implements RoundedStep {
38+
private static final long serialVersionUID = 1L;
3939
private static final String NAME = "cleanthat";
4040
private static final String MAVEN_COORDINATE = "io.github.solven-eu.cleanthat:java";
41-
42-
// CleanThat changelog is available at https://github.com/solven-eu/cleanthat/blob/master/CHANGES.MD
41+
/**
42+
* CleanThat changelog is available at <a href="https://github.com/solven-eu/cleanthat/blob/master/CHANGES.MD">here</a>.
43+
*/
4344
private static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME).add(11, "2.16");
4445

45-
// prevent direct instantiation
46-
private CleanthatJavaStep() {}
46+
private final JarState.Promised jarState;
47+
private final String version;
48+
private final String sourceJdkVersion;
49+
private final List<String> included;
50+
private final List<String> excluded;
51+
private final boolean includeDraft;
52+
53+
private CleanthatJavaStep(JarState.Promised jarState,
54+
String version,
55+
String sourceJdkVersion,
56+
List<String> included,
57+
List<String> excluded,
58+
boolean includeDraft) {
59+
this.jarState = jarState;
60+
this.version = version;
61+
62+
this.sourceJdkVersion = sourceJdkVersion;
63+
this.included = included;
64+
this.excluded = excluded;
65+
this.includeDraft = includeDraft;
66+
}
4767

48-
/** Creates a step which apply default CleanThat mutators. */
68+
/** Creates a step that applies default CleanThat mutators. */
4969
public static FormatterStep create(Provisioner provisioner) {
5070
return create(defaultVersion(), provisioner);
5171
}
5272

53-
/** Creates a step which apply default CleanThat mutators. */
73+
/** Creates a step that applies default CleanThat mutators. */
5474
public static FormatterStep create(String version, Provisioner provisioner) {
5575
return create(MAVEN_COORDINATE, version, defaultSourceJdk(), defaultMutators(), defaultExcludedMutators(), defaultIncludeDraft(), provisioner);
5676
}
@@ -64,7 +84,6 @@ public static String defaultSourceJdk() {
6484

6585
/**
6686
* By default, we include only safe and consensual mutators
67-
* @return
6887
*/
6988
public static List<String> defaultMutators() {
7089
// see ICleanthatStepParametersProperties.SAFE_AND_CONSENSUAL
@@ -79,7 +98,7 @@ public static boolean defaultIncludeDraft() {
7998
return false;
8099
}
81100

82-
/** Creates a step which apply selected CleanThat mutators. */
101+
/** Creates a step that applies selected CleanThat mutators. */
83102
public static FormatterStep create(String groupArtifact,
84103
String version,
85104
String sourceJdkVersion,
@@ -93,57 +112,51 @@ public static FormatterStep create(String groupArtifact,
93112
}
94113
Objects.requireNonNull(version, "version");
95114
Objects.requireNonNull(provisioner, "provisioner");
96-
return FormatterStep.createLazy(NAME,
97-
() -> new JavaRefactorerState(NAME, groupArtifact, version, sourceJdkVersion, included, excluded, includeDraft, provisioner),
98-
JavaRefactorerState::createFormat);
115+
return FormatterStep.create(NAME,
116+
new CleanthatJavaStep(JarState.promise(() -> JarState.from(groupArtifact + ":" + version, provisioner)), version, sourceJdkVersion, included, excluded, includeDraft),
117+
CleanthatJavaStep::equalityState,
118+
State::createFormat);
99119
}
100120

101121
/** Get default formatter version */
102122
public static String defaultVersion() {
103-
return JVM_SUPPORT.getRecommendedFormatterVersion();
123+
return Objects.requireNonNull(JVM_SUPPORT.getRecommendedFormatterVersion());
104124
}
105125

106126
public static String defaultGroupArtifact() {
107127
return MAVEN_COORDINATE;
108128
}
109129

110-
static final class JavaRefactorerState implements Serializable {
111-
private static final long serialVersionUID = 1L;
112-
113-
final JarState jarState;
114-
final String stepName;
115-
final String version;
130+
private State equalityState() {
131+
return new State(jarState.get(), version, sourceJdkVersion, included, excluded, includeDraft);
132+
}
116133

117-
final String sourceJdkVersion;
118-
final List<String> included;
119-
final List<String> excluded;
120-
final boolean includeDraft;
134+
private static final class State implements Serializable {
135+
private static final long serialVersionUID = 1L;
121136

122-
JavaRefactorerState(String stepName, String version, Provisioner provisioner) throws IOException {
123-
this(stepName, MAVEN_COORDINATE, version, defaultSourceJdk(), defaultMutators(), defaultExcludedMutators(), defaultIncludeDraft(), provisioner);
124-
}
137+
private final JarState jarState;
138+
private final String version;
139+
private final String sourceJdkVersion;
140+
private final List<String> included;
141+
private final List<String> excluded;
142+
private final boolean includeDraft;
125143

126-
JavaRefactorerState(String stepName,
127-
String groupArtifact,
144+
State(JarState jarState,
128145
String version,
129146
String sourceJdkVersion,
130147
List<String> included,
131148
List<String> excluded,
132-
boolean includeDraft,
133-
Provisioner provisioner) throws IOException {
149+
boolean includeDraft) {
134150
JVM_SUPPORT.assertFormatterSupported(version);
135151
ModuleHelper.doOpenInternalPackagesIfRequired();
136-
this.jarState = JarState.from(groupArtifact + ":" + version, provisioner);
137-
this.stepName = stepName;
152+
this.jarState = jarState;
138153
this.version = version;
139-
140154
this.sourceJdkVersion = sourceJdkVersion;
141155
this.included = included;
142156
this.excluded = excluded;
143157
this.includeDraft = includeDraft;
144158
}
145159

146-
@SuppressWarnings("PMD.UseProperClassLoader")
147160
FormatterFunc createFormat() {
148161
ClassLoader classLoader = jarState.getClassLoader();
149162

@@ -159,9 +172,7 @@ FormatterFunc createFormat() {
159172
throw new IllegalStateException("Issue executing the formatter", e);
160173
}
161174

162-
return JVM_SUPPORT.suggestLaterVersionOnError(version, input -> {
163-
return (String) formatterMethod.invoke(formatter, input);
164-
});
175+
return JVM_SUPPORT.suggestLaterVersionOnError(version, input -> (String) formatterMethod.invoke(formatter, input));
165176
}
166177
}
167178
}

lib/src/main/java/com/diffplug/spotless/java/FormatAnnotationsStep.java

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 DiffPlug
2+
* Copyright 2022-2024 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.
@@ -26,6 +26,8 @@
2626

2727
import com.diffplug.spotless.FormatterFunc;
2828
import com.diffplug.spotless.FormatterStep;
29+
import com.diffplug.spotless.RoundedStep;
30+
import com.diffplug.spotless.SerializedFunction;
2931

3032
/**
3133
* Some formatters put every annotation on its own line
@@ -36,7 +38,8 @@
3638
* <p>
3739
* Note: A type annotation is an annotation that is meta-annotated with {@code @Target({ElementType.TYPE_USE})}.
3840
*/
39-
public final class FormatAnnotationsStep {
41+
public final class FormatAnnotationsStep implements RoundedStep {
42+
private static final long serialVersionUID = 1L;
4043

4144
/**
4245
* Simple names of type annotations.
@@ -389,14 +392,14 @@ public final class FormatAnnotationsStep {
389392

390393
);
391394

392-
static final String NAME = "No line break between type annotation and type";
395+
private static final String NAME = "No line break between type annotation and type";
393396

394397
public static FormatterStep create() {
395398
return create(Collections.emptyList(), Collections.emptyList());
396399
}
397400

398401
public static FormatterStep create(List<String> addedTypeAnnotations, List<String> removedTypeAnnotations) {
399-
return FormatterStep.create(NAME, new State(addedTypeAnnotations, removedTypeAnnotations), State::toFormatter);
402+
return FormatterStep.create(NAME, new State(addedTypeAnnotations, removedTypeAnnotations), SerializedFunction.identity(), State::toFormatter);
400403
}
401404

402405
private FormatAnnotationsStep() {}
@@ -432,13 +435,13 @@ private static final class State implements Serializable {
432435
}
433436

434437
FormatterFunc toFormatter() {
435-
return unixStr -> fixupTypeAnnotations(unixStr);
438+
return this::fixupTypeAnnotations;
436439
}
437440

438441
/**
439442
* Removes line break between type annotations and the following type.
440443
*
441-
* @param the text of a Java file
444+
* @param unixStr the text of a Java file
442445
* @return corrected text of the Java file
443446
*/
444447
String fixupTypeAnnotations(String unixStr) {

0 commit comments

Comments
 (0)