Skip to content

Commit c56968a

Browse files
committed
Add a roundtrip-serializable method to FormatterStep.
1 parent 56bb67e commit c56968a

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,29 @@ public final String format(String rawUnix, File file) throws Exception {
104104
}
105105
}
106106

107+
/**
108+
* @param name
109+
* The name of the formatter step.
110+
* @param roundtripInit
111+
* If the step has any state, this supplier will calculate it lazily. The supplier doesn't
112+
* have to be serializable, but the result it calculates needs to be serializable.
113+
* @param equalityFunc
114+
* A pure serializable function (method reference recommended) which takes the result of `roundtripInit`,
115+
* and returns a serializable object whose serialized representation will be used for `.equals` and
116+
* `.hashCode` of the FormatterStep.
117+
* @param formatterFunc
118+
* A pure serializable function (method reference recommended) which takes the result of `equalityFunc`,
119+
* and returns a `FormatterFunc` which will be used for the actual formatting.
120+
* @return A FormatterStep which can be losslessly roundtripped through the java serialization machinery.
121+
*/
122+
static <RoundtripState extends Serializable, EqualityState extends Serializable> FormatterStep createLazy(
123+
String name,
124+
ThrowingEx.Supplier<RoundtripState> roundtripInit,
125+
SerializedFunction<RoundtripState, EqualityState> equalityFunc,
126+
SerializedFunction<EqualityState, FormatterFunc> formatterFunc) {
127+
return new FormatterStepSerializationRoundtrip(name, roundtripInit, equalityFunc, formatterFunc);
128+
}
129+
107130
/**
108131
* @param name
109132
* The name of the formatter step
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2023 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.IOException;
19+
import java.io.ObjectStreamException;
20+
import java.io.Serializable;
21+
22+
import edu.umd.cs.findbugs.annotations.Nullable;
23+
24+
class FormatterStepSerializationRoundtrip<RoundtripState extends Serializable, EqualityState extends Serializable> extends FormatterStepEqualityOnStateSerialization<EqualityState> {
25+
private final String name;
26+
private final transient ThrowingEx.Supplier<RoundtripState> initializer;
27+
private @Nullable RoundtripState roundtripStateInternal;
28+
private final SerializedFunction<RoundtripState, EqualityState> equalityStateExtractor;
29+
private final SerializedFunction<EqualityState, FormatterFunc> equalityStateToFormatter;
30+
31+
public FormatterStepSerializationRoundtrip(String name, ThrowingEx.Supplier<RoundtripState> initializer, SerializedFunction<RoundtripState, EqualityState> equalityStateExtractor, SerializedFunction<EqualityState, FormatterFunc> equalityStateToFormatter) {
32+
this.name = name;
33+
this.initializer = initializer;
34+
this.equalityStateExtractor = equalityStateExtractor;
35+
this.equalityStateToFormatter = equalityStateToFormatter;
36+
}
37+
38+
@Override
39+
public String getName() {
40+
return name;
41+
}
42+
43+
@Override
44+
protected EqualityState stateSupplier() throws Exception {
45+
if (roundtripStateInternal != null) {
46+
roundtripStateInternal = initializer.get();
47+
}
48+
return equalityStateExtractor.apply(roundtripStateInternal);
49+
}
50+
51+
@Override
52+
protected FormatterFunc stateToFormatter(EqualityState equalityState) throws Exception {
53+
return equalityStateToFormatter.apply(equalityState);
54+
}
55+
56+
// override serialize output
57+
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
58+
if (roundtripStateInternal == null) {
59+
roundtripStateInternal = ThrowingEx.get(initializer::get);
60+
}
61+
out.defaultWriteObject();
62+
}
63+
64+
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
65+
in.defaultReadObject();
66+
}
67+
68+
private void readObjectNoData() throws ObjectStreamException {
69+
throw new UnsupportedOperationException();
70+
}
71+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2023 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+
@FunctionalInterface
21+
interface SerializedFunction<T, R> extends Serializable, ThrowingEx.Function<T, R> {}

0 commit comments

Comments
 (0)