|
18 | 18 | import java.io.IOException;
|
19 | 19 | import java.io.Serializable;
|
20 | 20 | import java.lang.reflect.Constructor;
|
21 |
| -import java.lang.reflect.InvocationTargetException; |
22 |
| -import java.lang.reflect.Method; |
23 |
| -import java.lang.reflect.Proxy; |
24 |
| -import java.util.ArrayList; |
25 | 21 | import java.util.Collections;
|
26 | 22 | import java.util.Map;
|
27 | 23 | import java.util.Objects;
|
|
31 | 27 | import com.diffplug.spotless.FormatterStep;
|
32 | 28 | import com.diffplug.spotless.JarState;
|
33 | 29 | import com.diffplug.spotless.Provisioner;
|
34 |
| -import com.diffplug.spotless.ThrowingEx; |
35 | 30 |
|
36 | 31 | /** Wraps up <a href="https://github.com/pinterest/ktlint">ktlint</a> as a FormatterStep. */
|
37 | 32 | public class KtLintStep {
|
38 | 33 | // prevent direct instantiation
|
39 | 34 | private KtLintStep() {}
|
40 | 35 |
|
41 |
| - private static final String DEFAULT_VERSION = "0.45.2"; |
| 36 | + private static final String DEFAULT_VERSION = "0.46.1"; |
42 | 37 | static final String NAME = "ktlint";
|
43 |
| - static final String PACKAGE_PRE_0_32 = "com.github.shyiko"; |
44 | 38 | static final String PACKAGE = "com.pinterest";
|
45 |
| - static final String MAVEN_COORDINATE_PRE_0_32 = PACKAGE_PRE_0_32 + ":ktlint:"; |
46 | 39 | static final String MAVEN_COORDINATE = PACKAGE + ":ktlint:";
|
47 | 40 |
|
48 | 41 | public static FormatterStep create(Provisioner provisioner) {
|
@@ -85,95 +78,30 @@ static final class State implements Serializable {
|
85 | 78 |
|
86 | 79 | /** Are the files being linted Kotlin script files. */
|
87 | 80 | private final boolean isScript;
|
88 |
| - private final String pkg; |
89 | 81 | /** The jar that contains the formatter. */
|
90 | 82 | final JarState jarState;
|
91 | 83 | private final boolean useExperimental;
|
92 | 84 | private final TreeMap<String, String> userData;
|
93 | 85 | private final TreeMap<String, Object> editorConfigOverride;
|
94 |
| - private final boolean useParams; |
95 | 86 |
|
96 | 87 | State(String version, Provisioner provisioner, boolean isScript, boolean useExperimental,
|
97 | 88 | Map<String, String> userData, Map<String, Object> editorConfigOverride) throws IOException {
|
98 | 89 |
|
99 |
| - if (!editorConfigOverride.isEmpty() && |
100 |
| - BadSemver.version(version) < BadSemver.version(0, 45, 2)) { |
101 |
| - throw new IllegalStateException("KtLint editorConfigOverride supported for version 0.45.2 and later"); |
| 90 | + if (BadSemver.version(version) < BadSemver.version(0, 46, 0)) { |
| 91 | + throw new IllegalStateException("KtLint versions < 0.46.0 not supported!"); |
102 | 92 | }
|
103 | 93 |
|
104 | 94 | this.useExperimental = useExperimental;
|
105 | 95 | this.userData = new TreeMap<>(userData);
|
106 | 96 | this.editorConfigOverride = new TreeMap<>(editorConfigOverride);
|
107 |
| - String coordinate; |
108 |
| - if (BadSemver.version(version) < BadSemver.version(0, 32)) { |
109 |
| - coordinate = MAVEN_COORDINATE_PRE_0_32; |
110 |
| - this.pkg = PACKAGE_PRE_0_32; |
111 |
| - } else { |
112 |
| - coordinate = MAVEN_COORDINATE; |
113 |
| - this.pkg = PACKAGE; |
114 |
| - } |
115 |
| - this.useParams = BadSemver.version(version) >= BadSemver.version(0, 34); |
116 |
| - this.jarState = JarState.from(coordinate + version, provisioner); |
| 97 | + this.jarState = JarState.from(MAVEN_COORDINATE + version, provisioner); |
117 | 98 | this.isScript = isScript;
|
118 | 99 | }
|
119 | 100 |
|
120 | 101 | FormatterFunc createFormat() throws Exception {
|
121 |
| - if (useParams) { |
122 |
| - Class<?> formatterFunc = jarState.getClassLoader().loadClass("com.diffplug.spotless.glue.ktlint.KtlintFormatterFunc"); |
123 |
| - Constructor<?> constructor = formatterFunc.getConstructor(boolean.class, boolean.class, Map.class, Map.class); |
124 |
| - return (FormatterFunc.NeedsFile) constructor.newInstance(isScript, useExperimental, userData, editorConfigOverride); |
125 |
| - } |
126 |
| - |
127 |
| - ClassLoader classLoader = jarState.getClassLoader(); |
128 |
| - // String KtLint::format(String input, Iterable<RuleSet> rules, Function2 errorCallback) |
129 |
| - |
130 |
| - ArrayList<Object> ruleSets = new ArrayList<>(); |
131 |
| - |
132 |
| - // first, we get the standard rules |
133 |
| - Class<?> standardRuleSetProviderClass = classLoader.loadClass(pkg + ".ktlint.ruleset.standard.StandardRuleSetProvider"); |
134 |
| - Object standardRuleSet = standardRuleSetProviderClass.getMethod("get").invoke(standardRuleSetProviderClass.newInstance()); |
135 |
| - ruleSets.add(standardRuleSet); |
136 |
| - |
137 |
| - // second, we get the experimental rules if desired |
138 |
| - if (useExperimental) { |
139 |
| - Class<?> experimentalRuleSetProviderClass = classLoader.loadClass(pkg + ".ktlint.ruleset.experimental.ExperimentalRuleSetProvider"); |
140 |
| - Object experimentalRuleSet = experimentalRuleSetProviderClass.getMethod("get").invoke(experimentalRuleSetProviderClass.newInstance()); |
141 |
| - ruleSets.add(experimentalRuleSet); |
142 |
| - } |
143 |
| - |
144 |
| - // next, we create an error callback which throws an assertion error when the format is bad |
145 |
| - Class<?> function2Interface = classLoader.loadClass("kotlin.jvm.functions.Function2"); |
146 |
| - Class<?> lintErrorClass = classLoader.loadClass(pkg + ".ktlint.core.LintError"); |
147 |
| - Method detailGetter = lintErrorClass.getMethod("getDetail"); |
148 |
| - Method lineGetter = lintErrorClass.getMethod("getLine"); |
149 |
| - Method colGetter = lintErrorClass.getMethod("getCol"); |
150 |
| - Object formatterCallback = Proxy.newProxyInstance(classLoader, new Class[]{function2Interface}, |
151 |
| - (proxy, method, args) -> { |
152 |
| - Object lintError = args[0]; //ktlint.core.LintError |
153 |
| - boolean corrected = (Boolean) args[1]; |
154 |
| - if (!corrected) { |
155 |
| - String detail = (String) detailGetter.invoke(lintError); |
156 |
| - int line = (Integer) lineGetter.invoke(lintError); |
157 |
| - int col = (Integer) colGetter.invoke(lintError); |
158 |
| - throw new AssertionError("Error on line: " + line + ", column: " + col + "\n" + detail); |
159 |
| - } |
160 |
| - return null; |
161 |
| - }); |
162 |
| - |
163 |
| - // grab the KtLint singleton |
164 |
| - Class<?> ktlintClass = classLoader.loadClass(pkg + ".ktlint.core.KtLint"); |
165 |
| - Object ktlint = ktlintClass.getDeclaredField("INSTANCE").get(null); |
166 |
| - |
167 |
| - // and its format method |
168 |
| - String formatterMethodName = isScript ? "formatScript" : "format"; |
169 |
| - Method formatterMethod = ktlintClass.getMethod(formatterMethodName, String.class, Iterable.class, Map.class, function2Interface); |
170 |
| - return input -> { |
171 |
| - try { |
172 |
| - return (String) formatterMethod.invoke(ktlint, input, ruleSets, userData, formatterCallback); |
173 |
| - } catch (InvocationTargetException e) { |
174 |
| - throw ThrowingEx.unwrapCause(e); |
175 |
| - } |
176 |
| - }; |
| 102 | + Class<?> formatterFunc = jarState.getClassLoader().loadClass("com.diffplug.spotless.glue.ktlint.KtlintFormatterFunc"); |
| 103 | + Constructor<?> constructor = formatterFunc.getConstructor(boolean.class, boolean.class, Map.class, Map.class); |
| 104 | + return (FormatterFunc.NeedsFile) constructor.newInstance(isScript, useExperimental, userData, editorConfigOverride); |
177 | 105 | }
|
178 | 106 | }
|
179 | 107 | }
|
0 commit comments