Skip to content

Commit d8735ba

Browse files
committed
Update FenceStep so that it uses FormatterStep.createLazy
1 parent 02e0140 commit d8735ba

File tree

1 file changed

+68
-88
lines changed

1 file changed

+68
-88
lines changed

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

Lines changed: 68 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2024 DiffPlug
2+
* Copyright 2020-2025 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.
@@ -24,9 +24,9 @@
2424
import java.util.regex.Matcher;
2525
import java.util.regex.Pattern;
2626

27-
import javax.annotation.Nullable;
28-
27+
import com.diffplug.spotless.ConfigurationCacheHackList;
2928
import com.diffplug.spotless.Formatter;
29+
import com.diffplug.spotless.FormatterFunc;
3030
import com.diffplug.spotless.FormatterStep;
3131
import com.diffplug.spotless.LineEnding;
3232
import com.diffplug.spotless.Lint;
@@ -80,94 +80,82 @@ private void assertRegexSet() {
8080

8181
/** Returns a step which will apply the given steps but preserve the content selected by the regex / openClose pair. */
8282
public FormatterStep preserveWithin(List<FormatterStep> steps) {
83-
assertRegexSet();
84-
return new PreserveWithin(name, regex, steps);
83+
return createStep(Kind.PRESERVE, steps);
8584
}
8685

8786
/**
8887
* Returns a step which will apply the given steps only within the blocks selected by the regex / openClose pair.
8988
* Linting within the substeps is not supported.
9089
*/
9190
public FormatterStep applyWithin(List<FormatterStep> steps) {
91+
return createStep(Kind.APPLY, steps);
92+
}
93+
94+
private FormatterStep createStep(Kind kind, List<FormatterStep> steps) {
9295
assertRegexSet();
93-
return new ApplyWithin(name, regex, steps);
96+
return FormatterStep.createLazy(name, () -> new RoundtripAndEqualityState(kind, regex, steps, false),
97+
RoundtripAndEqualityState::toEqualityState,
98+
RoundtripAndEqualityState::toFormatterFunc);
9499
}
95100

96-
static class ApplyWithin extends BaseStep {
97-
private static final long serialVersionUID = 17061466531957339L;
101+
private enum Kind {
102+
APPLY, PRESERVE
103+
}
98104

99-
ApplyWithin(String name, Pattern regex, List<FormatterStep> steps) {
100-
super(name, regex, steps);
101-
}
105+
private static class RoundtripAndEqualityState implements Serializable {
106+
final String regexPattern;
107+
final int regexFlags;
108+
final Kind kind;
109+
final ConfigurationCacheHackList steps;
102110

103-
@Override
104-
protected String applySubclass(Formatter formatter, String unix, File file) {
105-
List<String> groups = groupsZeroed();
106-
Matcher matcher = regex.matcher(unix);
107-
while (matcher.find()) {
108-
// apply the formatter to each group
109-
groups.add(formatter.compute(matcher.group(1), file));
110-
}
111-
// and then assemble the result right away
112-
return assembleGroups(unix);
111+
/** Roundtrip state. */
112+
private RoundtripAndEqualityState(Kind kind, Pattern regex, List<FormatterStep> steps, boolean optimizeForEquality) {
113+
this.kind = kind;
114+
this.regexPattern = regex.pattern();
115+
this.regexFlags = regex.flags();
116+
this.steps = optimizeForEquality ? ConfigurationCacheHackList.forEquality() : ConfigurationCacheHackList.forRoundtrip();
117+
this.steps.addAll(steps);
113118
}
114-
}
115119

116-
static class PreserveWithin extends BaseStep {
117-
private static final long serialVersionUID = -8676786492305178343L;
120+
private Pattern regex() {
121+
return Pattern.compile(regexPattern, regexFlags);
122+
}
118123

119-
PreserveWithin(String name, Pattern regex, List<FormatterStep> steps) {
120-
super(name, regex, steps);
124+
private List<FormatterStep> steps() {
125+
return steps.getSteps();
121126
}
122127

123-
private void storeGroups(String unix) {
124-
List<String> groups = groupsZeroed();
125-
Matcher matcher = regex.matcher(unix);
126-
while (matcher.find()) {
127-
// store whatever is within the open/close tags
128-
groups.add(matcher.group(1));
129-
}
128+
public RoundtripAndEqualityState toEqualityState() {
129+
return new RoundtripAndEqualityState(kind, regex(), steps(), true);
130130
}
131131

132-
@Override
133-
protected String applySubclass(Formatter formatter, String unix, File file) {
134-
storeGroups(unix);
135-
String formatted = formatter.compute(unix, file);
136-
return assembleGroups(formatted);
132+
public BaseFormatter toFormatterFunc() {
133+
return new BaseFormatter(kind, this);
137134
}
138135
}
139136

140137
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
141-
private static abstract class BaseStep implements Serializable, FormatterStep {
142-
final String name;
143-
private static final long serialVersionUID = -2301848328356559915L;
138+
private static class BaseFormatter implements FormatterFunc.NeedsFile, FormatterFunc.Closeable {
139+
final Kind kind;
144140
final Pattern regex;
145141
final List<FormatterStep> steps;
146142

147-
transient ArrayList<String> groups = new ArrayList<>();
148-
transient StringBuilder builderInternal;
143+
final ArrayList<String> groups = new ArrayList<>();
144+
final StringBuilder builderInternal = new StringBuilder();
149145

150-
public BaseStep(String name, Pattern regex, List<FormatterStep> steps) {
151-
this.name = name;
152-
this.regex = regex;
153-
this.steps = steps;
146+
public BaseFormatter(Kind kind, RoundtripAndEqualityState state) {
147+
this.kind = kind;
148+
this.regex = state.regex();
149+
this.steps = state.steps();
154150
}
155151

156152
protected ArrayList<String> groupsZeroed() {
157-
if (groups == null) {
158-
groups = new ArrayList<>();
159-
} else {
160-
groups.clear();
161-
}
153+
groups.clear();
162154
return groups;
163155
}
164156

165157
private StringBuilder builderZeroed() {
166-
if (builderInternal == null) {
167-
builderInternal = new StringBuilder();
168-
} else {
169-
builderInternal.setLength(0);
170-
}
158+
builderInternal.setLength(0);
171159
return builderInternal;
172160
}
173161

@@ -215,41 +203,33 @@ protected String assembleGroups(String unix) {
215203
}
216204
}
217205

218-
@Override
219-
public String getName() {
220-
return name;
221-
}
206+
private Formatter formatter;
222207

223-
private transient Formatter formatter;
224-
225-
private String apply(String rawUnix, File file) throws Exception {
208+
@Override
209+
public String applyWithFile(String unix, File file) throws Exception {
226210
if (formatter == null) {
227211
formatter = buildFormatter();
228212
}
229-
return applySubclass(formatter, rawUnix, file);
230-
}
231-
232-
@Nullable
233-
@Override
234-
public String format(String rawUnix, File file) throws Exception {
235-
return apply(rawUnix, file);
236-
}
237-
238-
protected abstract String applySubclass(Formatter formatter, String unix, File file) throws Exception;
239-
240-
@Override
241-
public boolean equals(Object o) {
242-
if (this == o)
243-
return true;
244-
if (o == null || getClass() != o.getClass())
245-
return false;
246-
BaseStep step = (BaseStep) o;
247-
return name.equals(step.name) && regex.pattern().equals(step.regex.pattern()) && regex.flags() == step.regex.flags() && steps.equals(step.steps);
248-
}
249-
250-
@Override
251-
public int hashCode() {
252-
return Objects.hash(name, regex.pattern(), regex.flags(), steps);
213+
List<String> groups = groupsZeroed();
214+
Matcher matcher = regex.matcher(unix);
215+
switch (kind) {
216+
case APPLY:
217+
while (matcher.find()) {
218+
// apply the formatter to each group
219+
groups.add(formatter.compute(matcher.group(1), file));
220+
}
221+
// and then assemble the result right away
222+
return assembleGroups(unix);
223+
case PRESERVE:
224+
while (matcher.find()) {
225+
// store whatever is within the open/close tags
226+
groups.add(matcher.group(1));
227+
}
228+
String formatted = formatter.compute(unix, file);
229+
return assembleGroups(formatted);
230+
default:
231+
throw new Error();
232+
}
253233
}
254234

255235
@Override

0 commit comments

Comments
 (0)