diff --git a/lib/build.gradle b/lib/build.gradle index 3c8b6e75e4..876aa9e4a1 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -114,8 +114,9 @@ dependencies { gsonCompileOnly 'com.google.code.gson:gson:2.10.1' - cleanthatCompileOnly 'io.github.solven-eu.cleanthat:java:2.6' - compatCleanthat2Dot1CompileAndTestOnly 'io.github.solven-eu.cleanthat:java:2.6' + String VER_CLEANTHAT="2.8" + cleanthatCompileOnly "io.github.solven-eu.cleanthat:java:$VER_CLEANTHAT" + compatCleanthat2Dot1CompileAndTestOnly "io.github.solven-eu.cleanthat:java:$VER_CLEANTHAT" gherkinCompileOnly 'io.cucumber:gherkin-utils:8.0.2' gherkinCompileOnly 'org.slf4j:slf4j-api:2.0.0' diff --git a/lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java b/lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java index d7148f8892..1137604264 100644 --- a/lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java +++ b/lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java @@ -88,8 +88,7 @@ private String doApply(String input) throws InterruptedException, IOException { LOGGER.debug("Processing sourceJdk={} included={} excluded={}", jdkVersion, included, excluded, includeDraft); LOGGER.debug("Available mutators: {}", JavaRefactorer.getAllIncluded()); - // Spotless calls steps always with LF eol. - return refactorer.doFormat(input, LineEnding.LF); + return refactorer.doFormat(input); } } diff --git a/lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java b/lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java index c1e5ae1fa4..0377af8bc5 100644 --- a/lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java +++ b/lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java @@ -40,7 +40,7 @@ public final class CleanthatJavaStep { private static final String MAVEN_COORDINATE = "io.github.solven-eu.cleanthat:java"; // CleanThat changelog is available at https://github.com/solven-eu/cleanthat/blob/master/CHANGES.MD - private static final Jvm.Support JVM_SUPPORT = Jvm. support(NAME).add(11, "2.6"); + private static final Jvm.Support JVM_SUPPORT = Jvm. support(NAME).add(11, "2.8"); // prevent direct instantiation private CleanthatJavaStep() {} @@ -83,8 +83,8 @@ public static boolean defaultIncludeDraft() { public static FormatterStep create(String groupArtifact, String version, String sourceJdkVersion, - List excluded, List included, + List excluded, boolean includeDraft, Provisioner provisioner) { Objects.requireNonNull(groupArtifact, "groupArtifact"); @@ -94,7 +94,7 @@ public static FormatterStep create(String groupArtifact, Objects.requireNonNull(version, "version"); Objects.requireNonNull(provisioner, "provisioner"); return FormatterStep.createLazy(NAME, - () -> new JavaRefactorerState(NAME, groupArtifact, version, sourceJdkVersion, excluded, included, includeDraft, provisioner), + () -> new JavaRefactorerState(NAME, groupArtifact, version, sourceJdkVersion, included, excluded, includeDraft, provisioner), JavaRefactorerState::createFormat); } @@ -120,7 +120,7 @@ static final class JavaRefactorerState implements Serializable { final boolean includeDraft; JavaRefactorerState(String stepName, String version, Provisioner provisioner) throws IOException { - this(stepName, MAVEN_COORDINATE, version, defaultSourceJdk(), defaultExcludedMutators(), defaultMutators(), defaultIncludeDraft(), provisioner); + this(stepName, MAVEN_COORDINATE, version, defaultSourceJdk(), defaultMutators(), defaultExcludedMutators(), defaultIncludeDraft(), provisioner); } JavaRefactorerState(String stepName, @@ -131,10 +131,7 @@ static final class JavaRefactorerState implements Serializable { List excluded, boolean includeDraft, Provisioner provisioner) throws IOException { - // https://github.com/diffplug/spotless/issues/1583 - if (!version.endsWith("-SNAPSHOT")) { - JVM_SUPPORT.assertFormatterSupported(version); - } + JVM_SUPPORT.assertFormatterSupported(version); ModuleHelper.doOpenInternalPackagesIfRequired(); this.jarState = JarState.from(groupArtifact + ":" + version, provisioner); this.stepName = stepName; @@ -162,17 +159,9 @@ FormatterFunc createFormat() { throw new IllegalStateException("Issue executing the formatter", e); } - // https://github.com/diffplug/spotless/issues/1583 - if (!version.endsWith("-SNAPSHOT")) { - return JVM_SUPPORT.suggestLaterVersionOnError(version, input -> { - return (String) formatterMethod.invoke(formatter, input); - }); - } else { - return input -> { - return (String) formatterMethod.invoke(formatter, input); - }; - } + return JVM_SUPPORT.suggestLaterVersionOnError(version, input -> { + return (String) formatterMethod.invoke(formatter, input); + }); } - } } diff --git a/lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java b/lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java index 91ce3cc023..a4c460e929 100644 --- a/lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java +++ b/lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,22 +15,47 @@ */ package com.diffplug.spotless.java; +import java.util.Arrays; import java.util.Objects; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.Provisioner; -/** Uses google-java-format, but only to remove unused imports. */ +/** Uses google-java-format or cleanthat.UnnecessaryImport, but only to remove unused imports. */ public class RemoveUnusedImportsStep { + static final String NAME = "removeUnusedImports"; + + static final String GJF = "google-java-format"; + static final String CLEANTHAT = "cleanthat-javaparser-unnecessaryimport"; + + // https://github.com/solven-eu/cleanthat/blob/master/java/src/main/java/eu/solven/cleanthat/engine/java/refactorer/mutators/UnnecessaryImport.java + private static final String CLEANTHAT_MUTATOR = "UnnecessaryImport"; + // prevent direct instantiation private RemoveUnusedImportsStep() {} - static final String NAME = "removeUnusedImports"; + public static final String defaultFormatter() { + return GJF; + } public static FormatterStep create(Provisioner provisioner) { + // The default importRemover is GJF + return create(GJF, provisioner); + } + + public static FormatterStep create(String unusedImportRemover, Provisioner provisioner) { Objects.requireNonNull(provisioner, "provisioner"); - return FormatterStep.createLazy(NAME, - () -> new GoogleJavaFormatStep.State(NAME, GoogleJavaFormatStep.defaultVersion(), provisioner), - GoogleJavaFormatStep.State::createRemoveUnusedImportsOnly); + + if (GJF.equals(unusedImportRemover)) { + return FormatterStep.createLazy(NAME, + () -> new GoogleJavaFormatStep.State(NAME, GoogleJavaFormatStep.defaultVersion(), provisioner), + GoogleJavaFormatStep.State::createRemoveUnusedImportsOnly); + } else if (CLEANTHAT.equals(unusedImportRemover)) { + return FormatterStep.createLazy(NAME, + () -> new CleanthatJavaStep.JavaRefactorerState(NAME, CleanthatJavaStep.defaultGroupArtifact(), CleanthatJavaStep.defaultVersion(), "99.9", Arrays.asList(CLEANTHAT_MUTATOR), Arrays.asList(), false, provisioner), + CleanthatJavaStep.JavaRefactorerState::createFormat); + } else { + throw new IllegalArgumentException("Invalid unusedImportRemover: " + unusedImportRemover); + } } } diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 6c7268eab6..d4256b15b4 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -4,6 +4,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] ### Added +* `removeUnusedImport` can be configured to rely on `cleanthat-javaparser-unnecessaryimport`. Default remains `google-java-format`. ([#1589](https://github.com/diffplug/spotless/pull/1589)) +### Changes +* Bump default `cleanthat` version to latest `2.6` -> `2.8`. ([#1589](https://github.com/diffplug/spotless/pull/1589) * Support configuration of mirrors for P2 repositories ([#1629](https://github.com/diffplug/spotless/issues/1629)): ``` spotless { diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index 5ae9d2bd95..2bb824b3ee 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -182,6 +182,17 @@ spotless { target 'src/*/java/**/*.java' ``` +### removeUnusedImports + +``` +spotless { + java { + removeUnusedImports() + // optional: you may switch for `google-java-format` as underlying engine to `cleanthat-javaparser-unnecessaryimport` + // which enables processing any language level source file with a JDK8+ Runtime + removeUnusedImports().engine('cleanthat-javaparser-unnecessaryimport') +``` + ### google-java-format [homepage](https://github.com/google/google-java-format). [changelog](https://github.com/google/google-java-format/releases). @@ -272,11 +283,13 @@ spotless { cleanthat() // optional: you can specify a specific version and/or config file cleanthat() - .groupArtifact('1.7') // default is 'io.github.solven-eu.cleanthat:java' - .version('2.1') // You may force a past of -SNAPSHOT - .sourceCompatibility('1.7') // default is '1.7' - .addMutator('your.custom.MagicMutator') - .excludeMutator('UseCollectionIsEmpty') + .groupArtifact('io.github.solven-eu.cleanthat:java') // Optional. Default is 'io.github.solven-eu.cleanthat:java' + .version('2.8') // You may force a custom version of Cleanthat + .sourceCompatibility('1.7') // default is '1.7' + .addMutator('SafeAndConsensual') // Default includes the SafeAndConsensual composite mutator + .addMutator('your.custom.MagicMutator') // List of mutators: https://github.com/solven-eu/cleanthat/blob/master/MUTATORS.generated.MD + .excludeMutator('UseCollectionIsEmpty') // You may exclude some mutators (from Composite ones) + .includeDraft(false) // You may exclude draft mutators (from Composite ones) ``` 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 3ca582dd21..d8dd77a09c 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 @@ -109,7 +109,11 @@ private FormatterStep createStep() { /** Removes any unused imports. */ public void removeUnusedImports() { - addStep(RemoveUnusedImportsStep.create(provisioner())); + addStep(RemoveUnusedImportsStep.create(RemoveUnusedImportsStep.defaultFormatter(), provisioner())); + } + + public void removeUnusedImports(String formatter) { + addStep(RemoveUnusedImportsStep.create(formatter, provisioner())); } /** Uses the google-java-format jar to format source code. */ diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java index e6569b2647..eed4cf1a4d 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java @@ -62,4 +62,22 @@ void multipleBlocksShouldWork() throws IOException { gradleRunner().withArguments("spotlessApply").build(); gradleRunner().withArguments("spotlessApply").build(); } + + @Test + void removeUnusedImportsWithCleanthat() throws IOException { + setFile("build.gradle").toLines( + "plugins {", + " id 'com.diffplug.spotless'", + " id 'java'", + "}", + "repositories { mavenCentral() }", + "", + "spotless {", + " java { removeUnusedImports('cleanthat-javaparser-unnecessaryimport') }", + "}"); + + setFile("src/main/java/test.java").toResource("java/removeunusedimports/Jdk17TextBlockUnformatted.test"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/java/test.java").sameAsResource("java/removeunusedimports/Jdk17TextBlockFormatted.test"); + } } diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 231d68e0e7..dfd5677031 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -4,11 +4,13 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] ### Added +* `removeUnusedImport` can be configured to rely on `cleanthat-javaparser-unnecessaryimport`. Default remains `google-java-format`. ([#1589](https://github.com/diffplug/spotless/pull/1589)) * The `style` option in Palantir Java Format ([#1654](https://github.com/diffplug/spotless/pull/1654)). * Added support for Gherkin feature files ([#1649](https://github.com/diffplug/spotless/issues/1649)). ### Fixed * Fix non deterministic computation of cache fingerprint when using multiple formatters. ([#1643](https://github.com/diffplug/spotless/pull/1643) fixes [#1642](https://github.com/diffplug/spotless/pull/1642)) ### Changes +* Bump default `cleanthat` version to latest `2.6` -> `2.8`. ([#1589](https://github.com/diffplug/spotless/pull/1589) * **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions < `1.8`. ([#1630](https://github.com/diffplug/spotless/pull/1630)) * Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#1630](https://github.com/diffplug/spotless/pull/1630)) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index b12d777b29..9ffd6f10b8 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -208,6 +208,14 @@ any other maven phase (i.e. compile) then it can be configured as below; ``` +### removeUnusedImports + +```xml + + google-java-format + +``` + ### google-java-format [homepage](https://github.com/google/google-java-format). [changelog](https://github.com/google/google-java-format/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java). @@ -285,17 +293,18 @@ These mechanisms already exist for the Gradle plugin. ```xml - 2.0 + 2.8 ${maven.compiler.source} - * + SafeAndConsensual - + LiteralsFirstInComparisons OptionalNotEmpty + false ``` diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java index 54fd30a167..85c6bbb8fe 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package com.diffplug.spotless.maven.java; +import org.apache.maven.plugins.annotations.Parameter; + import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.RemoveUnusedImportsStep; import com.diffplug.spotless.maven.FormatterStepConfig; @@ -22,8 +24,11 @@ public class RemoveUnusedImports implements FormatterStepFactory { + @Parameter + private String engine = RemoveUnusedImportsStep.defaultFormatter(); + @Override public FormatterStep newFormatterStep(FormatterStepConfig config) { - return RemoveUnusedImportsStep.create(config.getProvisioner()); + return RemoveUnusedImportsStep.create(engine, config.getProvisioner()); } } diff --git a/testlib/src/main/resources/java/removeunusedimports/Jdk17TextBlockFormatted.test b/testlib/src/main/resources/java/removeunusedimports/Jdk17TextBlockFormatted.test new file mode 100644 index 0000000000..d6abc3685c --- /dev/null +++ b/testlib/src/main/resources/java/removeunusedimports/Jdk17TextBlockFormatted.test @@ -0,0 +1,28 @@ +package io.github.shafthq.shaft.tools.tms; + + + +import static io.restassured.RestAssured.*; + +public class XrayIntegrationHelper { + private static String getLinkJIRATicketRequestBody() { + return """ + { + "update":{ + "issuelinks":[ + { + "add":{ + "type":{ + "name":"Relates" + }, + "outwardIssue":{ + "key":"${TICKET_ID}" + } + } + } + ] + } + } + """; + } +} diff --git a/testlib/src/main/resources/java/removeunusedimports/Jdk17TextBlockUnformatted.test b/testlib/src/main/resources/java/removeunusedimports/Jdk17TextBlockUnformatted.test new file mode 100644 index 0000000000..1bfad32664 --- /dev/null +++ b/testlib/src/main/resources/java/removeunusedimports/Jdk17TextBlockUnformatted.test @@ -0,0 +1,49 @@ +package io.github.shafthq.shaft.tools.tms; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.shaft.cli.FileActions; +import com.shaft.tools.io.ReportManager; +import io.github.shafthq.shaft.tools.io.helpers.ReportManagerHelper; +import io.restassured.config.RestAssuredConfig; +import io.restassured.config.SSLConfig; +import io.restassured.http.ContentType; +import io.restassured.response.Response; +import io.restassured.specification.RequestSpecification; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.Base64; +import java.util.Calendar; +import java.util.List; + +import static io.restassured.RestAssured.*; +import static io.restassured.config.EncoderConfig.encoderConfig; + + +public class XrayIntegrationHelper { + private static String getLinkJIRATicketRequestBody() { + return """ + { + "update":{ + "issuelinks":[ + { + "add":{ + "type":{ + "name":"Relates" + }, + "outwardIssue":{ + "key":"${TICKET_ID}" + } + } + } + ] + } + } + """; + } +} diff --git a/testlib/src/main/resources/java/removeunusedimports/RevelcFormatted.test b/testlib/src/main/resources/java/removeunusedimports/RevelcFormatted.test new file mode 100644 index 0000000000..672400fdb8 --- /dev/null +++ b/testlib/src/main/resources/java/removeunusedimports/RevelcFormatted.test @@ -0,0 +1,81 @@ +/* + * 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. + */ + +@XmlSchema( + xmlns = { + @XmlNs(prefix = "order", namespaceURI = "http://www.camel.apache.org/jaxb/example/order/1"), + @XmlNs(prefix = "address", namespaceURI = "http://www.camel.apache.org/jaxb/example/address/1") + } +) +package net.revelc.code.imp; + +import com.foo.Type1; +import com.foo.Type2; +import com.foo.Type3; +import com.foo.Type4; +import com.foo.Type5; +import com.foo.Type6; +import com.foo.Type7; +import com.foo.Type8; +import com.foo.Type9; +import com.foo.Type10; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.springframework.stereotype.Component; + +import com.foo.Type11; +import com.foo.internal.Type12; +import com.foo.params.Type13; +import javax.xml.bind.annotation.XmlNs; +import javax.xml.bind.annotation.XmlSchema; + +import static org.junit.Assert.assertFalse; + +import static org.junit.Assert.*; + +/** + * The import of {@link HashMap} should not be stripped away, since it + * is used in this comment. + */ +// https://github.com/revelc/impsort-maven-plugin/blob/main/src/test/resources/UnusedImports.java +@Component +public class UnusedImports { + ImmutableMap immutable; + + /** + * The following should also not be removed: + * + * @param blah when {@link Type13} blah + * @see Map + */ + public List getList(String blah) { + assertFalse(false); + return null; + } + + /** + * {@link Type1#method()} + * {@link Type2#method(Type3, Type4)} + * {@link #method(Type5, Type6)} + * {@value Type7#field} + * @see Type8#method() + * @see Type9#method(Type10) + * @throws Type11 when {@link Type12} is seen + */ + public void foo() { + } +} diff --git a/testlib/src/main/resources/java/removeunusedimports/RevelcUnformatted.test b/testlib/src/main/resources/java/removeunusedimports/RevelcUnformatted.test new file mode 100644 index 0000000000..bb43884a82 --- /dev/null +++ b/testlib/src/main/resources/java/removeunusedimports/RevelcUnformatted.test @@ -0,0 +1,89 @@ +/* + * 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. + */ + +@XmlSchema( + xmlns = { + @XmlNs(prefix = "order", namespaceURI = "http://www.camel.apache.org/jaxb/example/order/1"), + @XmlNs(prefix = "address", namespaceURI = "http://www.camel.apache.org/jaxb/example/address/1") + } +) +package net.revelc.code.imp; + +import com.foo.Type1; +import com.foo.Type2; +import com.foo.Type3; +import com.foo.Type4; +import com.foo.Type5; +import com.foo.Type6; +import com.foo.Type7; +import com.foo.Type8; +import com.foo.Type9; +import com.foo.Type10; +import net.revelc.code.imp.Something; +import net.revelc.code.imp.Something.Else; +import net.revelc.code.imp.*; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableMap; +import io.swagger.annotations.ApiOperation; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.foo.Type11; +import com.foo.internal.Type12; +import com.foo.params.Type13; +import javax.xml.bind.annotation.XmlNs; +import javax.xml.bind.annotation.XmlSchema; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import static org.junit.Assert.*; + +/** + * The import of {@link HashMap} should not be stripped away, since it + * is used in this comment. + */ +// https://github.com/revelc/impsort-maven-plugin/blob/main/src/test/resources/UnusedImports.java +@Component +public class UnusedImports { + ImmutableMap immutable; + + /** + * The following should also not be removed: + * + * @param blah when {@link Type13} blah + * @see Map + */ + public List getList(String blah) { + assertFalse(false); + return null; + } + + /** + * {@link Type1#method()} + * {@link Type2#method(Type3, Type4)} + * {@link #method(Type5, Type6)} + * {@value Type7#field} + * @see Type8#method() + * @see Type9#method(Type10) + * @throws Type11 when {@link Type12} is seen + */ + public void foo() { + } +} diff --git a/testlib/src/main/resources/java/removeunusedimports/SealedClassTestsFormatted.test b/testlib/src/main/resources/java/removeunusedimports/SealedClassTestsFormatted.test new file mode 100644 index 0000000000..2ef96e6c72 --- /dev/null +++ b/testlib/src/main/resources/java/removeunusedimports/SealedClassTestsFormatted.test @@ -0,0 +1,45 @@ +/* + * Copyright 2015-2023 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * https://www.eclipse.org/legal/epl-v20.html + */ + +package java.removeunusedimports; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; + +class SealedClassTests extends AbstractJupiterTestEngineTests { + + @Test + void sealedTestClassesAreTestClasses() { + executeTestsForClass(TestCase.class).testEvents() // + .assertStatistics(stats -> stats.finished(2).succeeded(1).failed(1)); + } + + sealed + abstract static class AbstractTestCase + permits TestCase + { + + @Test + void succeedingTest() { + assertTrue(true); + } + + @Test + void failingTest() { + fail("always fails"); + } + } + + static final class TestCase extends AbstractTestCase { + } + +} diff --git a/testlib/src/main/resources/java/removeunusedimports/SealedClassTestsUnformatted.test b/testlib/src/main/resources/java/removeunusedimports/SealedClassTestsUnformatted.test new file mode 100644 index 0000000000..942aa4d235 --- /dev/null +++ b/testlib/src/main/resources/java/removeunusedimports/SealedClassTestsUnformatted.test @@ -0,0 +1,46 @@ +/* + * Copyright 2015-2023 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * https://www.eclipse.org/legal/epl-v20.html + */ + +package java.removeunusedimports; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; +import useless.project.UnusedClass; + +class SealedClassTests extends AbstractJupiterTestEngineTests { + + @Test + void sealedTestClassesAreTestClasses() { + executeTestsForClass(TestCase.class).testEvents() // + .assertStatistics(stats -> stats.finished(2).succeeded(1).failed(1)); + } + + sealed + abstract static class AbstractTestCase + permits TestCase + { + + @Test + void succeedingTest() { + assertTrue(true); + } + + @Test + void failingTest() { + fail("always fails"); + } + } + + static final class TestCase extends AbstractTestCase { + } + +} diff --git a/testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStep_withCleanthatJavaparserTest.java b/testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStep_withCleanthatJavaparserTest.java new file mode 100644 index 0000000000..11e31aeae2 --- /dev/null +++ b/testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStep_withCleanthatJavaparserTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016-2023 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 org.junit.jupiter.api.Test; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.SerializableEqualityTester; +import com.diffplug.spotless.StepHarness; +import com.diffplug.spotless.TestProvisioner; + +class RemoveUnusedImportsStep_withCleanthatJavaparserTest { + @Test + void behavior() throws Exception { + FormatterStep step = RemoveUnusedImportsStep.create(RemoveUnusedImportsStep.CLEANTHAT, TestProvisioner.mavenCentral()); + StepHarness.forStep(step) + .testResource("java/removeunusedimports/JavaCodeUnformatted.test", "java/removeunusedimports/JavaCodeFormatted.test") + .testResource("java/removeunusedimports/JavaCodeWithLicenseUnformatted.test", "java/removeunusedimports/JavaCodeWithLicenseFormatted.test") + .testResource("java/removeunusedimports/JavaCodeWithLicensePackageUnformatted.test", "java/removeunusedimports/JavaCodeWithLicensePackageFormatted.test") + .testResource("java/removeunusedimports/JavaCodeWithPackageUnformatted.test", "java/removeunusedimports/JavaCodeWithPackageFormatted.test") + .testResource("java/removeunusedimports/Jdk17TextBlockUnformatted.test", "java/removeunusedimports/Jdk17TextBlockFormatted.test") + .testResource("java/removeunusedimports/RevelcUnformatted.test", "java/removeunusedimports/RevelcFormatted.test") + // Sealed classes are introduced with JDK15: This syntax is not supported by javaParser: such files are not trimmed from unused imports (for now) + .testResource("java/removeunusedimports/SealedClassTestsUnformatted.test", "java/removeunusedimports/SealedClassTestsUnformatted.test"); + } + + @Test + void equality() throws Exception { + new SerializableEqualityTester() { + @Override + protected void setupTest(API api) { + api.areDifferentThan(); + } + + @Override + protected FormatterStep create() { + return RemoveUnusedImportsStep.create(RemoveUnusedImportsStep.CLEANTHAT, TestProvisioner.mavenCentral()); + } + }.testEquals(); + } +} diff --git a/testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStepTest.java b/testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStep_withGoogleJavaFormatTest.java similarity index 68% rename from testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStepTest.java rename to testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStep_withGoogleJavaFormatTest.java index 5e0baa86c2..44699a8215 100644 --- a/testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/java/RemoveUnusedImportsStep_withGoogleJavaFormatTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,15 +22,20 @@ import com.diffplug.spotless.StepHarness; import com.diffplug.spotless.TestProvisioner; -class RemoveUnusedImportsStepTest { +class RemoveUnusedImportsStep_withGoogleJavaFormatTest { @Test void behavior() throws Exception { - FormatterStep step = RemoveUnusedImportsStep.create(TestProvisioner.mavenCentral()); + FormatterStep step = RemoveUnusedImportsStep.create(RemoveUnusedImportsStep.GJF, TestProvisioner.mavenCentral()); StepHarness.forStep(step) .testResource("java/removeunusedimports/JavaCodeUnformatted.test", "java/removeunusedimports/JavaCodeFormatted.test") .testResource("java/removeunusedimports/JavaCodeWithLicenseUnformatted.test", "java/removeunusedimports/JavaCodeWithLicenseFormatted.test") .testResource("java/removeunusedimports/JavaCodeWithLicensePackageUnformatted.test", "java/removeunusedimports/JavaCodeWithLicensePackageFormatted.test") - .testResource("java/removeunusedimports/JavaCodeWithPackageUnformatted.test", "java/removeunusedimports/JavaCodeWithPackageFormatted.test"); + .testResource("java/removeunusedimports/JavaCodeWithPackageUnformatted.test", "java/removeunusedimports/JavaCodeWithPackageFormatted.test") + .testResource("java/removeunusedimports/RevelcUnformatted.test", "java/removeunusedimports/RevelcFormatted.test") + // GoogleFormat requires running over a JDK17 to handle JDK17 features + // .testResource("java/removeunusedimports/Jdk17TextBlockUnformatted.test", "java/removeunusedimports/Jdk17TextBlockFormatted.test") + //.testResource("java/removeunusedimports/SealedClassTestsUnformatted.test", "java/removeunusedimports/SealedClassTestsFormatted.test") + ; } @Test @@ -43,7 +48,7 @@ protected void setupTest(API api) { @Override protected FormatterStep create() { - return RemoveUnusedImportsStep.create(TestProvisioner.mavenCentral()); + return RemoveUnusedImportsStep.create(RemoveUnusedImportsStep.GJF, TestProvisioner.mavenCentral()); } }.testEquals(); }