From 4e02a6ce1960fc34aa670cd5a13ce2e91aa8ee48 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 03:56:49 +0000 Subject: [PATCH 1/5] Initial plan From 567c52311d67489cca57f208f756a047c4694fc2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 04:00:43 +0000 Subject: [PATCH 2/5] Add ExpandWildcardImports Maven plugin integration implementation Co-authored-by: shitikanth <544054+shitikanth@users.noreply.github.com> --- .../spotless/maven/AbstractSpotlessMojo.java | 2 +- .../spotless/maven/FormatterConfig.java | 10 ++- .../spotless/maven/FormatterFactory.java | 2 +- .../spotless/maven/FormatterStepConfig.java | 10 ++- .../maven/java/ExpandWildcardImports.java | 63 +++++++++++++++++++ .../diffplug/spotless/maven/java/Java.java | 4 ++ 6 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ExpandWildcardImports.java diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index 3952a8de70..d2c84d7cdb 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -397,7 +397,7 @@ private FormatterConfig getFormatterConfig() { FileLocator fileLocator = getFileLocator(); final Optional optionalRatchetFrom = Optional.ofNullable(this.ratchetFrom) .filter(ratchet -> !RATCHETFROM_NONE.equals(ratchet)); - return new FormatterConfig(baseDir, encoding, lineEndings, optionalRatchetFrom, provisioner, fileLocator, formatterStepFactories, Optional.ofNullable(setLicenseHeaderYearsFromGitHistory), lintSuppressions); + return new FormatterConfig(baseDir, encoding, lineEndings, optionalRatchetFrom, provisioner, fileLocator, formatterStepFactories, Optional.ofNullable(setLicenseHeaderYearsFromGitHistory), lintSuppressions, project); } private FileLocator getFileLocator() { diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java index 842d4da68e..4ef7ff1800 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java @@ -21,6 +21,8 @@ import java.util.List; import java.util.Optional; +import org.apache.maven.project.MavenProject; + import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.LintSuppression; import com.diffplug.spotless.Provisioner; @@ -35,9 +37,10 @@ public class FormatterConfig { private final List globalStepFactories; private final Optional spotlessSetLicenseHeaderYearsFromGitHistory; private final List lintSuppressions; + private final MavenProject project; public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Optional ratchetFrom, Provisioner provisioner, - FileLocator fileLocator, List globalStepFactories, Optional spotlessSetLicenseHeaderYearsFromGitHistory, List lintSuppressions) { + FileLocator fileLocator, List globalStepFactories, Optional spotlessSetLicenseHeaderYearsFromGitHistory, List lintSuppressions, MavenProject project) { this.encoding = encoding; this.lineEndings = lineEndings; this.ratchetFrom = ratchetFrom; @@ -46,6 +49,7 @@ public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Op this.globalStepFactories = globalStepFactories; this.spotlessSetLicenseHeaderYearsFromGitHistory = spotlessSetLicenseHeaderYearsFromGitHistory; this.lintSuppressions = lintSuppressions; + this.project = project; } public String getEncoding() { @@ -79,4 +83,8 @@ public FileLocator getFileLocator() { public List getLintSuppressions() { return unmodifiableList(lintSuppressions); } + + public MavenProject getProject() { + return project; + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 6c7cc0d349..62b266c1c2 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -185,7 +185,7 @@ Optional ratchetFrom(FormatterConfig config) { } private FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { - return new FormatterStepConfig(encoding, licenseHeaderDelimiter(), ratchetFrom(config), config.getProvisioner(), config.getFileLocator(), config.getSpotlessSetLicenseHeaderYearsFromGitHistory()); + return new FormatterStepConfig(encoding, licenseHeaderDelimiter(), ratchetFrom(config), config.getProvisioner(), config.getFileLocator(), config.getSpotlessSetLicenseHeaderYearsFromGitHistory(), config.getProject()); } private static List gatherStepFactories(List allGlobal, List allConfigured) { diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java index a1f2e52b41..847cd358b7 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java @@ -18,6 +18,8 @@ import java.nio.charset.Charset; import java.util.Optional; +import org.apache.maven.project.MavenProject; + import com.diffplug.spotless.Provisioner; public class FormatterStepConfig { @@ -28,14 +30,16 @@ public class FormatterStepConfig { private final Provisioner provisioner; private final FileLocator fileLocator; private final Optional spotlessSetLicenseHeaderYearsFromGitHistory; + private final MavenProject project; - public FormatterStepConfig(Charset encoding, String licenseHeaderDelimiter, Optional ratchetFrom, Provisioner provisioner, FileLocator fileLocator, Optional spotlessSetLicenseHeaderYearsFromGitHistory) { + public FormatterStepConfig(Charset encoding, String licenseHeaderDelimiter, Optional ratchetFrom, Provisioner provisioner, FileLocator fileLocator, Optional spotlessSetLicenseHeaderYearsFromGitHistory, MavenProject project) { this.encoding = encoding; this.licenseHeaderDelimiter = licenseHeaderDelimiter; this.ratchetFrom = ratchetFrom; this.provisioner = provisioner; this.fileLocator = fileLocator; this.spotlessSetLicenseHeaderYearsFromGitHistory = spotlessSetLicenseHeaderYearsFromGitHistory; + this.project = project; } public Charset getEncoding() { @@ -61,4 +65,8 @@ public FileLocator getFileLocator() { public Optional spotlessSetLicenseHeaderYearsFromGitHistory() { return spotlessSetLicenseHeaderYearsFromGitHistory; } + + public MavenProject getProject() { + return project; + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ExpandWildcardImports.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ExpandWildcardImports.java new file mode 100644 index 0000000000..02829c61a1 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ExpandWildcardImports.java @@ -0,0 +1,63 @@ +/* + * Copyright 2025-2026 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.maven.java; + +import java.io.File; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.project.MavenProject; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.java.ExpandWildcardImportsStep; +import com.diffplug.spotless.maven.FormatterStepConfig; +import com.diffplug.spotless.maven.FormatterStepFactory; + +public class ExpandWildcardImports implements FormatterStepFactory { + + @Override + public FormatterStep newFormatterStep(FormatterStepConfig config) { + MavenProject project = config.getProject(); + Set typeSolverClasspath = new HashSet<>(); + + // Add source directories + String sourceDirectory = project.getBuild().getSourceDirectory(); + if (sourceDirectory != null) { + File sourceDir = new File(sourceDirectory); + if (sourceDir.exists()) { + typeSolverClasspath.add(sourceDir); + } + } + + String testSourceDirectory = project.getBuild().getTestSourceDirectory(); + if (testSourceDirectory != null) { + File testSourceDir = new File(testSourceDirectory); + if (testSourceDir.exists()) { + typeSolverClasspath.add(testSourceDir); + } + } + + // Add compiled dependencies + project.getArtifacts().stream() + .map(Artifact::getFile) + .filter(Objects::nonNull) + .forEach(typeSolverClasspath::add); + + return ExpandWildcardImportsStep.create(typeSolverClasspath, config.getProvisioner()); + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index acc97647d7..53068fead5 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -88,6 +88,10 @@ public void addFormatAnnotations(FormatAnnotations formatAnnotations) { addStepFactory(formatAnnotations); } + public void addExpandWildcardImports(ExpandWildcardImports expandWildcardImports) { + addStepFactory(expandWildcardImports); + } + public void addCleanthat(CleanthatJava cleanthat) { addStepFactory(cleanthat); } From 2546cdb24d68cb15ed515cd6d6af88c29e408ff5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 04:03:44 +0000 Subject: [PATCH 3/5] Add documentation for expandWildcardImports in Maven plugin README Co-authored-by: shitikanth <544054+shitikanth@users.noreply.github.com> --- plugin-maven/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index aa855dd4b9..6bb834dcae 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -232,6 +232,7 @@ any other maven phase (i.e. compile) then it can be configured as below; + @@ -257,6 +258,14 @@ any other maven phase (i.e. compile) then it can be configured as below; ``` +### expandWildcardImports + +Automatically replaces wildcard imports (e.g., `import java.util.*`) with explicit imports for the classes actually used in the code. This step analyzes your source code and project dependencies to determine which specific classes are needed and generates the appropriate import statements. + +```xml + +``` + ### forbidModuleImports ```xml From ee80a74f247087eedd7d5e61726b1109d0f6fd4e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 04:05:51 +0000 Subject: [PATCH 4/5] Fix copyright year and improve source root handling to support multiple directories Co-authored-by: shitikanth <544054+shitikanth@users.noreply.github.com> --- .../maven/java/ExpandWildcardImports.java | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ExpandWildcardImports.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ExpandWildcardImports.java index 02829c61a1..bcea932608 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ExpandWildcardImports.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ExpandWildcardImports.java @@ -1,5 +1,5 @@ /* - * Copyright 2025-2026 DiffPlug + * Copyright 2025 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,22 +35,17 @@ public FormatterStep newFormatterStep(FormatterStepConfig config) { MavenProject project = config.getProject(); Set typeSolverClasspath = new HashSet<>(); - // Add source directories - String sourceDirectory = project.getBuild().getSourceDirectory(); - if (sourceDirectory != null) { - File sourceDir = new File(sourceDirectory); - if (sourceDir.exists()) { - typeSolverClasspath.add(sourceDir); - } - } - - String testSourceDirectory = project.getBuild().getTestSourceDirectory(); - if (testSourceDirectory != null) { - File testSourceDir = new File(testSourceDirectory); - if (testSourceDir.exists()) { - typeSolverClasspath.add(testSourceDir); - } - } + // Add all main source roots + project.getCompileSourceRoots().stream() + .map(File::new) + .filter(File::exists) + .forEach(typeSolverClasspath::add); + + // Add all test source roots + project.getTestCompileSourceRoots().stream() + .map(File::new) + .filter(File::exists) + .forEach(typeSolverClasspath::add); // Add compiled dependencies project.getArtifacts().stream() From 00b22ba2e3e3c6704a9b2028010cff88098d9359 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 04:10:54 +0000 Subject: [PATCH 5/5] Add Maven plugin test for ExpandWildcardImportsStep Co-authored-by: shitikanth <544054+shitikanth@users.noreply.github.com> --- .../java/ExpandWildcardImportsStepTest.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 plugin-maven/src/test/java/com/diffplug/spotless/maven/java/ExpandWildcardImportsStepTest.java diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/ExpandWildcardImportsStepTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/ExpandWildcardImportsStepTest.java new file mode 100644 index 0000000000..7b7fcbeeb3 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/ExpandWildcardImportsStepTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 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.maven.java; + +import org.junit.jupiter.api.Test; + +import com.diffplug.spotless.maven.MavenIntegrationHarness; + +class ExpandWildcardImportsStepTest extends MavenIntegrationHarness { + + @Test + void testExpandWildcardImports() throws Exception { + writePomWithJavaSteps(""); + + // Create the supporting classes needed for import resolution + setFile("src/main/java/foo/bar/AnotherClassInSamePackage.java") + .toResource("java/expandwildcardimports/AnotherClassInSamePackage.test"); + setFile("src/main/java/foo/bar/baz/AnotherImportedClass.java") + .toResource("java/expandwildcardimports/AnotherImportedClass.test"); + + // Create the annotation class that's used in the test + setFile("src/main/java/org/example/SomeAnnotation.java") + .toContent("package org.example;\n\npublic @interface SomeAnnotation {}\n"); + + // Set the main file to format + String path = "src/main/java/foo/bar/JavaClassWithWildcards.java"; + setFile(path).toResource("java/expandwildcardimports/JavaClassWithWildcardsUnformatted.test"); + + // Run spotless:apply + mavenRunner().withArguments("spotless:apply").runNoError(); + + // Verify the wildcards were expanded + assertFile(path).sameAsResource("java/expandwildcardimports/JavaClassWithWildcardsFormatted.test"); + } +}