Skip to content

Commit 9556bf9

Browse files
author
Vincent Potucek
committed
Merge remote-tracking branch 'f/fix-testRemoveUnusedInports' into fix-testRemoveUnusedInports
# Conflicts: # testlib/src/main/resources/java/removeunusedimports/Issue2532Post.test # testlib/src/main/resources/java/removeunusedimports/Issue2532Pre.test
2 parents 1196b72 + 006b74c commit 9556bf9

23 files changed

+566
-0
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
1212
## [Unreleased]
1313
### Added
1414
* Add support for removing wildcard imports via `removeWildcardImports` step. ([#2517](https://github.com/diffplug/spotless/pull/2517))
15+
* Add support for removing generic obsoletes imports via `replaceObsoletes` step. ([#2530](https://github.com/diffplug/spotless/pull/2530))
1516

1617
## [3.1.2] - 2025-05-27
1718
### Fixed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright 2016-2025 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.generic;
17+
18+
import static java.util.regex.Pattern.MULTILINE;
19+
import static java.util.regex.Pattern.compile;
20+
21+
import java.io.File;
22+
23+
import com.diffplug.spotless.FormatterStep;
24+
25+
public final class ReplaceObsoletesStep implements FormatterStep {
26+
27+
private static final long serialVersionUID = -6643164760547140534L;
28+
29+
private ReplaceObsoletesStep() {}
30+
31+
public static FormatterStep forJava() {
32+
return new ReplaceObsoletesStep();
33+
}
34+
35+
@Override
36+
public String getName() {
37+
return "replaceObsoletes";
38+
}
39+
40+
@Override
41+
public String format(String rawUnix, File file) throws Exception {
42+
return removeRedundantAbstractInInterfaces(
43+
removeRedundantPublicStaticInEnumsAndInterfaces(
44+
removeRedundantInitializations("float|double", "0(?:\\.0)?(?:f|d)?",
45+
removeRedundantInitializations("int|long|short|byte", "0(?:L)?",
46+
removeRedundantInitializations("String|\\w+", "null",
47+
removeRedundantInitializations("boolean", "false",
48+
replaceLineSeparator(rawUnix)))))));
49+
}
50+
51+
private static String replaceLineSeparator(String input) {
52+
return compile(
53+
"System\\.getProperty\\(\"line\\.separator\"(?:\\s*,\\s*\"\\\\n\")?\\)|" +
54+
"String\\s+\\w+\\s*=\\s*System\\.getProperty\\(\"line\\.separator\"(?:\\s*,\\s*\"\\\\n\")?\\)\\s*;",
55+
MULTILINE)
56+
.matcher(input)
57+
.replaceAll(match -> match.group().contains("String")
58+
? "String " + match.group().split("\\s+")[1].split("=")[0].trim() + " = System.lineSeparator();"
59+
: "System.lineSeparator()");
60+
}
61+
62+
private String removeRedundantInitializations(String typePattern, String defaultValuePattern, String input) {
63+
return compile(
64+
"([a-zA-Z]+\\s+(?:" + typePattern + ")\\s+\\w+)\\s*=\\s*" + defaultValuePattern + "\\s*;",
65+
MULTILINE)
66+
.matcher(input)
67+
.replaceAll("$1;");
68+
}
69+
70+
private String removeRedundantPublicStaticInEnumsAndInterfaces(String input) {
71+
// Handle enum constants
72+
String processed = compile(
73+
"(enum\\s+\\w+\\s*\\{[^}]*?)(public\\s+static\\s+)(\\w+\\s*,\\s*|\\w+\\s*;)",
74+
MULTILINE)
75+
.matcher(input)
76+
.replaceAll("$1$3");
77+
78+
// Handle enum methods
79+
processed = compile(
80+
"(enum\\s+\\w+\\s*\\{[^}]*?)(public\\s+static\\s+)(\\w+\\s+\\w+\\s*\\([^)]*\\)\\s*(?:throws\\s+[\\w.]+(?:\\s*,\\s*[\\w.]+)*\\s*)?\\{)",
81+
MULTILINE)
82+
.matcher(processed)
83+
.replaceAll("$1$3");
84+
85+
// Handle interface constants - keep 'final' but remove 'public static'
86+
processed = compile(
87+
"(interface\\s+\\w+\\s*\\{[^}]*?)(public\\s+static\\s+)(final\\s+)(\\w+\\s+\\w+\\s*=)",
88+
MULTILINE)
89+
.matcher(processed)
90+
.replaceAll("$1$3$4");
91+
92+
// Handle interface methods
93+
processed = compile(
94+
"(interface\\s+\\w+\\s*\\{[^}]*?)(public\\s+static\\s+)(\\w+\\s+\\w+\\s*\\([^)]*\\)\\s*(?:throws\\s+[\\w.]+(?:\\s*,\\s*[\\w.]+)*\\s*)?;)",
95+
MULTILINE)
96+
.matcher(processed)
97+
.replaceAll("$1$3");
98+
99+
// Handle interface inner classes
100+
processed = compile(
101+
"(interface\\s+\\w+\\s*\\{[^}]*?)(public\\s+static\\s+)(class\\s+\\w+\\s*\\{)",
102+
MULTILINE)
103+
.matcher(processed)
104+
.replaceAll("$1$3");
105+
106+
return processed;
107+
}
108+
109+
private String removeRedundantAbstractInInterfaces(String input) {
110+
// Handle abstract methods in interfaces
111+
return compile(
112+
"(interface\\s+\\w+\\s*\\{[^}]*?)(?:public\\s+)?abstract\\s+(\\w+\\s+\\w+\\s*\\([^)]*\\)\\s*(?:throws\\s+[\\w.]+(?:\\s*,\\s*[\\w.]+)*\\s*)?;)",
113+
MULTILINE)
114+
.matcher(input)
115+
.replaceAll("$1$2");
116+
}
117+
118+
@Override
119+
public void close() throws Exception {}
120+
}

plugin-gradle/CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
55
## [Unreleased]
66
### Added
77
* Add support for removing wildcard imports via `removeWildcardImports` step. ([#2517](https://github.com/diffplug/spotless/pull/2517))
8+
* Add support for removing generic obsoletes imports via `replaceObsoletes` step. ([#2530](https://github.com/diffplug/spotless/pull/2530))
89

910
## [7.0.4] - 2025-05-27
1011
### Fixed

plugin-maven/CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
55
## [Unreleased]
66
### Added
77
* Add support for removing wildcard imports via `removeWildcardImports` step. ([#2517](https://github.com/diffplug/spotless/pull/2517))
8+
* Add support for removing generic obsoletes imports via `replaceObsoletes` step. ([#2530](https://github.com/diffplug/spotless/pull/2530))
89

910
## [2.44.5] - 2025-05-27
1011
### Changed

plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ public void addRemoveWildcardImports(RemoveWildcardImports removeWildcardImports
8080
addStepFactory(removeWildcardImports);
8181
}
8282

83+
public void addReplaceObsoletes(ReplaceObsoletes replaceObsoletes) {
84+
addStepFactory(replaceObsoletes);
85+
}
86+
8387
public void addFormatAnnotations(FormatAnnotations formatAnnotations) {
8488
addStepFactory(formatAnnotations);
8589
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2025 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.maven.java;
17+
18+
import com.diffplug.spotless.FormatterStep;
19+
import com.diffplug.spotless.generic.ReplaceObsoletesStep;
20+
import com.diffplug.spotless.maven.FormatterStepConfig;
21+
import com.diffplug.spotless.maven.FormatterStepFactory;
22+
23+
public class ReplaceObsoletes implements FormatterStepFactory {
24+
@Override
25+
public FormatterStep newFormatterStep(FormatterStepConfig config) {
26+
return ReplaceObsoletesStep.forJava();
27+
}
28+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright 2016-2025 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.maven.java;
17+
18+
import org.junit.jupiter.api.Disabled;
19+
import org.junit.jupiter.api.Test;
20+
21+
import com.diffplug.spotless.maven.MavenIntegrationHarness;
22+
23+
class ReplaceObsoletesStepTest extends MavenIntegrationHarness {
24+
@Test
25+
void testSortPomCfg() throws Exception {
26+
writePomWithJavaSteps("<replaceObsoletes/>");
27+
28+
String path = "src/main/java/test.java";
29+
setFile(path).toResource("java/replaceobsoletes/SortPomCfgPre.test");
30+
mavenRunner().withArguments("spotless:apply").runNoError();
31+
assertFile(path).sameAsResource("java/replaceobsoletes/SortPomCfgPost.test");
32+
}
33+
34+
@Test
35+
void testSystemLineSeparator() throws Exception {
36+
writePomWithJavaSteps("<replaceObsoletes/>");
37+
38+
String path = "src/main/java/test.java";
39+
setFile(path).toResource("java/replaceobsoletes/SystemLineSeparatorPre.test");
40+
mavenRunner().withArguments("spotless:apply").runNoError();
41+
assertFile(path).sameAsResource("java/replaceobsoletes/SystemLineSeparatorPost.test");
42+
}
43+
44+
@Test
45+
void testBooleanInitializers() throws Exception {
46+
writePomWithJavaSteps("<replaceObsoletes/>");
47+
48+
String path = "src/main/java/test.java";
49+
setFile(path).toResource("java/replaceobsoletes/BooleanInitializersPre.test");
50+
mavenRunner().withArguments("spotless:apply").runNoError();
51+
assertFile(path).sameAsResource("java/replaceobsoletes/BooleanInitializersPost.test");
52+
}
53+
54+
@Test
55+
void testNullInitializers() throws Exception {
56+
writePomWithJavaSteps("<replaceObsoletes/>");
57+
58+
String path = "src/main/java/test.java";
59+
setFile(path).toResource("java/replaceobsoletes/NullInitializersPre.test");
60+
mavenRunner().withArguments("spotless:apply").runNoError();
61+
assertFile(path).sameAsResource("java/replaceobsoletes/NullInitializersPost.test");
62+
}
63+
64+
@Test
65+
void testIntInitializers() throws Exception {
66+
writePomWithJavaSteps("<replaceObsoletes/>");
67+
68+
String path = "src/main/java/test.java";
69+
setFile(path).toResource("java/replaceobsoletes/IntInitializersPre.test");
70+
mavenRunner().withArguments("spotless:apply").runNoError();
71+
assertFile(path).sameAsResource("java/replaceobsoletes/IntInitializersPost.test");
72+
}
73+
74+
@Test
75+
void testEnumPublicStatic() throws Exception {
76+
writePomWithJavaSteps("<replaceObsoletes/>");
77+
78+
String path = "src/main/java/test.java";
79+
setFile(path).toResource("java/replaceobsoletes/EnumPublicStaticPre.test");
80+
mavenRunner().withArguments("spotless:apply").runNoError();
81+
assertFile(path).sameAsResource("java/replaceobsoletes/EnumPublicStaticPost.test");
82+
}
83+
84+
@Test
85+
void testInterfacePublicStatic() throws Exception {
86+
writePomWithJavaSteps("<replaceObsoletes/>");
87+
88+
String path = "src/main/java/test.java";
89+
setFile(path).toResource("java/replaceobsoletes/InterfacePublicStaticPre.test");
90+
mavenRunner().withArguments("spotless:apply").runNoError();
91+
assertFile(path).sameAsResource("java/replaceobsoletes/InterfacePublicStaticPost.test");
92+
}
93+
94+
@Test
95+
@Disabled("feature envy: (edge case/hard to implement) having a dedicated method")
96+
void testSQLTokenizedFormatterPost() throws Exception {
97+
writePomWithJavaSteps("<replaceObsoletes/>");
98+
99+
String path = "src/main/java/test.java";
100+
setFile(path).toResource("java/replaceobsoletes/SQLTokenizedFormatterPre.test");
101+
mavenRunner().withArguments("spotless:apply").runNoError();
102+
assertFile(path).sameAsResource("java/replaceobsoletes/SQLTokenizedFormatterPost.test");
103+
}
104+
105+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public class Test {
2+
public boolean flag1;
3+
public boolean flag2 = true;
4+
public boolean flag3;
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public class Test {
2+
public boolean flag1 = false;
3+
public boolean flag2 = true;
4+
public boolean flag3 = false;
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public enum TestEnum {
2+
VALUE1,
3+
VALUE2;
4+
5+
void method() {}
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public enum TestEnum {
2+
public static VALUE1,
3+
public static VALUE2;
4+
5+
public static void method() {}
6+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
public class Test {
2+
public int int1;
3+
public int int2 = 1;
4+
public long long1;
5+
public long long2 = 1L;
6+
public float float1;
7+
public float float2 = 1.0f;
8+
public double double1;
9+
public double double2 = 1.0;
10+
public short short1;
11+
public short short2 = 1;
12+
public byte byte1;
13+
public byte byte2 = 1;
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
public class Test {
2+
public int int1 = 0;
3+
public int int2 = 1;
4+
public long long1 = 0L;
5+
public long long2 = 1L;
6+
public float float1 = 0.0f;
7+
public float float2 = 1.0f;
8+
public double double1 = 0.0;
9+
public double double2 = 1.0;
10+
public short short1 = 0;
11+
public short short2 = 1;
12+
public byte byte1 = 0;
13+
public byte byte2 = 1;
14+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
interface TestInterface {
2+
final int CONSTANT = 1;
3+
void method();
4+
class InnerClass {}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
interface TestInterface {
2+
public static final int CONSTANT = 1;
3+
public abstract void method();
4+
public static class InnerClass {}
5+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class Test {
2+
public String str1;
3+
public String str2 = "value";
4+
public Object obj1;
5+
public Foo Foo1;
6+
public Foo Foo2 = "null";
7+
public Object obj2 = new Object();
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class Test {
2+
public String str1 = null;
3+
public String str2 = "value";
4+
public Object obj1 = null;
5+
public Foo Foo1 = null;
6+
public Foo Foo2 = "null";
7+
public Object obj2 = new Object();
8+
}

0 commit comments

Comments
 (0)