diff --git a/lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedDeclarationsStep.java b/lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedDeclarationsStep.java new file mode 100644 index 0000000000..facec6842f --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedDeclarationsStep.java @@ -0,0 +1,29 @@ +/* + * Copyright 2016-2025 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 com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.glue.pjf.PalantirJavaFormatFormatterFormatSourceAndFixImportsAndDeclarationsFunc; +import com.diffplug.spotless.glue.pjf.PalantirJavaFormatFormatterFunc; + +/** Uses google-java-format or cleanthat.UnnecessaryImport, but only to remove unused imports. */ +public interface RemoveUnusedDeclarationsStep { + String NAME = "removeUnusedImports"; + + static FormatterStep create() { + return new PalantirJavaFormatFormatterFormatSourceAndFixImportsAndDeclarationsFunc("PALANTIR", true); + } +} diff --git a/lib/src/palantirJavaFormat/java/com/diffplug/spotless/glue/pjf/PalantirJavaFormatFormatterFormatSourceAndFixImportsAndDeclarationsFunc.java b/lib/src/palantirJavaFormat/java/com/diffplug/spotless/glue/pjf/PalantirJavaFormatFormatterFormatSourceAndFixImportsAndDeclarationsFunc.java new file mode 100644 index 0000000000..29ed3c1ee0 --- /dev/null +++ b/lib/src/palantirJavaFormat/java/com/diffplug/spotless/glue/pjf/PalantirJavaFormatFormatterFormatSourceAndFixImportsAndDeclarationsFunc.java @@ -0,0 +1,101 @@ +/* + * Copyright 2022-2025 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.glue.pjf; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +import javax.annotation.Nullable; + +import com.palantir.javaformat.java.Formatter; +import com.palantir.javaformat.java.ImportOrderer; +import com.palantir.javaformat.java.JavaFormatterOptions; +import com.palantir.javaformat.java.RemoveUnusedImports; + +import com.diffplug.spotless.FormatterFunc; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.Lint; + +public class PalantirJavaFormatFormatterFormatSourceAndFixImportsAndDeclarationsFunc implements FormatterFunc, FormatterStep { + + private final Formatter formatter; + + private final JavaFormatterOptions.Style formatterStyle; + + /** + * Creates a new formatter func that formats code via Palantir. + * @param style The style to use for formatting. + * @param formatJavadoc Whether to format Java docs. Requires at least Palantir 2.36.0 or later, otherwise the + * constructor will throw. + */ + public PalantirJavaFormatFormatterFormatSourceAndFixImportsAndDeclarationsFunc(String style, boolean formatJavadoc) { + this.formatterStyle = JavaFormatterOptions.Style.valueOf(style); + JavaFormatterOptions.Builder builder = JavaFormatterOptions.builder(); + builder.style(formatterStyle); + if (formatJavadoc) { + applyFormatJavadoc(builder); + } + formatter = Formatter.createFormatter(builder.build()); + } + + @Override + public String apply(String input) throws Exception { + return formatter.formatSourceAndFixImportsAndDeclarations(input); + } + + @Override + public String apply(String unix, File file) throws Exception { + return FormatterFunc.super.apply(unix, file); + } + + @Override + public List lint(String content, File file) throws Exception { + return FormatterFunc.super.lint(content, file); + } + + @Override + public String toString() { + return "PalantirJavaFormatFormatterFunc{formatter=" + formatter + '}'; + } + + private static void applyFormatJavadoc(JavaFormatterOptions.Builder builder) { + // The formatJavadoc option is available since Palantir 2.36.0 + // To support older versions for now, attempt to invoke the builder method via reflection. + try { + Method formatJavadoc = JavaFormatterOptions.Builder.class.getMethod("formatJavadoc", boolean.class); + formatJavadoc.invoke(builder, true); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + throw new IllegalStateException("Cannot enable formatJavadoc option, make sure you are using Palantir with version 2.36.0 or later", e); + } + } + + @Override + public String getName() { + return toString(); + } + + @Nullable @Override + public String format(String rawUnix, File file) throws Exception { + return apply(rawUnix); + } + + @Override + public void close() throws Exception { + + } +} diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java index f0530fb968..b0a526627c 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java @@ -40,6 +40,7 @@ import com.diffplug.spotless.java.GoogleJavaFormatStep; import com.diffplug.spotless.java.ImportOrderStep; import com.diffplug.spotless.java.PalantirJavaFormatStep; +import com.diffplug.spotless.java.RemoveUnusedDeclarationsStep; import com.diffplug.spotless.java.RemoveUnusedImportsStep; import com.diffplug.spotless.java.RemoveWildcardImportsStep; @@ -156,6 +157,10 @@ public void removeWildcardImports() { addStep(RemoveWildcardImportsStep.create()); } + public void removeUnusedDeclarations() { + addStep(RemoveUnusedDeclarationsStep.create()); + } + /** Uses the google-java-format jar to format source code. */ public GoogleJavaFormatConfig googleJavaFormat() { return googleJavaFormat(GoogleJavaFormatStep.defaultVersion());