/
GoogleJavaFormatStep.java
199 lines (169 loc) · 8.54 KB
/
GoogleJavaFormatStep.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*
* Copyright 2016-2024 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.java;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.Objects;
import com.diffplug.spotless.FormatterFunc;
import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.JarState;
import com.diffplug.spotless.Jvm;
import com.diffplug.spotless.Provisioner;
/** Wraps up <a href="https://github.com/google/google-java-format">google-java-format</a> as a FormatterStep. */
public class GoogleJavaFormatStep implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private static final String DEFAULT_STYLE = "GOOGLE";
private static final boolean DEFAULT_REFLOW_LONG_STRINGS = false;
private static final boolean DEFAULT_REORDER_IMPORTS = false;
private static final boolean DEFAULT_FORMAT_JAVADOC = true;
private static final String NAME = "google-java-format";
private static final String MAVEN_COORDINATE = "com.google.googlejavaformat:google-java-format";
/** The jar that contains the formatter. */
private final JarState.Promised jarState;
private final String version;
private final String style;
private final boolean reflowLongStrings;
private final boolean reorderImports;
private final boolean formatJavadoc;
private GoogleJavaFormatStep(JarState.Promised jarState,
String version,
String style,
boolean reflowLongStrings,
boolean reorderImports,
boolean formatJavadoc) {
this.jarState = jarState;
this.version = version;
this.style = style;
this.reflowLongStrings = reflowLongStrings;
this.reorderImports = reorderImports;
this.formatJavadoc = formatJavadoc;
}
/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(Provisioner provisioner) {
return create(defaultVersion(), provisioner);
}
/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(String version, Provisioner provisioner) {
return create(version, DEFAULT_STYLE, provisioner);
}
/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(String version, String style, Provisioner provisioner) {
return create(version, style, provisioner, DEFAULT_REFLOW_LONG_STRINGS);
}
/** Creates a step which formats everything - code, import order, and unused imports - and optionally reflows long strings. */
public static FormatterStep create(String version, String style, Provisioner provisioner, boolean reflowLongStrings) {
return create(MAVEN_COORDINATE, version, style, provisioner, reflowLongStrings);
}
public static FormatterStep create(String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings) {
return create(groupArtifact, version, style, provisioner, reflowLongStrings, DEFAULT_REORDER_IMPORTS);
}
public static FormatterStep create(String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings, boolean reorderImports) {
return create(groupArtifact, version, style, provisioner, reflowLongStrings, reorderImports, DEFAULT_FORMAT_JAVADOC);
}
/** Creates a step which formats everything - groupArtifact, code, import order, and unused imports - and optionally reflows long strings. */
public static FormatterStep create(String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings, boolean reorderImports, boolean formatJavadoc) {
return createInternally(groupArtifact, version, style, provisioner, reflowLongStrings, reorderImports, formatJavadoc, false);
}
static FormatterStep createRemoveUnusedImportsOnly(Provisioner provisioner) {
return createInternally(MAVEN_COORDINATE, defaultVersion(), defaultStyle(), provisioner, defaultReflowLongStrings(), defaultReorderImports(), defaultFormatJavadoc(), true);
}
private static FormatterStep createInternally(String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings, boolean reorderImports, boolean formatJavadoc, boolean removeImports) {
Objects.requireNonNull(groupArtifact, "groupArtifact");
if (groupArtifact.chars().filter(ch -> ch == ':').count() != 1) {
throw new IllegalArgumentException("groupArtifact must be in the form 'groupId:artifactId'");
}
Objects.requireNonNull(version, "version");
Objects.requireNonNull(style, "style");
Objects.requireNonNull(provisioner, "provisioner");
GoogleJavaFormatStep step = new GoogleJavaFormatStep(JarState.promise(() -> JarState.from(groupArtifact + ":" + version, provisioner)), version, style, reflowLongStrings, reorderImports, formatJavadoc);
if (removeImports) {
return FormatterStep.create(NAME,
step,
GoogleJavaFormatStep::equalityState,
State::createRemoveUnusedImportsOnly);
} else {
return FormatterStep.create(NAME,
step,
GoogleJavaFormatStep::equalityState,
State::createFormat);
}
}
private static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME)
.addMin(11, "1.8") // we only support google-java-format >= 1.8 due to api changes
.addMin(16, "1.10.0") // java 16 requires at least 1.10.0 due to jdk api changes in JavaTokenizer
.addMin(21, "1.17.0") // java 21 requires at least 1.17.0 due to https://github.com/google/google-java-format/issues/898
.add(11, "1.22.0"); // default version
public static String defaultGroupArtifact() {
return MAVEN_COORDINATE;
}
/** Get default formatter version */
public static String defaultVersion() {
return Objects.requireNonNull(JVM_SUPPORT.getRecommendedFormatterVersion());
}
public static String defaultStyle() {
return DEFAULT_STYLE;
}
public static boolean defaultReflowLongStrings() {
return DEFAULT_REFLOW_LONG_STRINGS;
}
public static boolean defaultReorderImports() {
return DEFAULT_REORDER_IMPORTS;
}
public static boolean defaultFormatJavadoc() {
return DEFAULT_FORMAT_JAVADOC;
}
private State equalityState() {
return new State(version, style, jarState.get(), reflowLongStrings, reorderImports, formatJavadoc);
}
private static final class State implements Serializable {
private static final long serialVersionUID = 1L;
private final JarState jarState;
private final String version;
private final String style;
private final boolean reflowLongStrings;
private final boolean reorderImports;
private final boolean formatJavadoc;
State(String version,
String style,
JarState jarState,
boolean reflowLongStrings,
boolean reorderImports,
boolean formatJavadoc) {
JVM_SUPPORT.assertFormatterSupported(version);
ModuleHelper.doOpenInternalPackagesIfRequired();
this.jarState = jarState;
this.version = version;
this.style = style;
this.reflowLongStrings = reflowLongStrings;
this.reorderImports = reorderImports;
this.formatJavadoc = formatJavadoc;
}
FormatterFunc createFormat() throws Exception {
final ClassLoader classLoader = jarState.getClassLoader();
Class<?> formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.java.GoogleJavaFormatFormatterFunc");
Constructor<?> constructor = formatterFunc.getConstructor(String.class, String.class, boolean.class, boolean.class, boolean.class);
FormatterFunc googleJavaFormatFormatterFunc = (FormatterFunc) constructor.newInstance(version, style, reflowLongStrings, reorderImports, formatJavadoc);
return JVM_SUPPORT.suggestLaterVersionOnError(version, googleJavaFormatFormatterFunc);
}
FormatterFunc createRemoveUnusedImportsOnly() throws Exception {
ClassLoader classLoader = jarState.getClassLoader();
Class<?> formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.java.GoogleJavaFormatRemoveUnusedImporterFormatterFunc");
Constructor<?> constructor = formatterFunc.getConstructor(String.class); //version
FormatterFunc googleJavaFormatRemoveUnusedImporterFormatterFunc = (FormatterFunc) constructor.newInstance(version);
return JVM_SUPPORT.suggestLaterVersionOnError(version, googleJavaFormatRemoveUnusedImporterFormatterFunc);
}
}
}