Skip to content

Commit b325e5c

Browse files
committed
Enhance Import Sorter/Order to cope with multi-line comments and misplaced imports
1 parent eef0714 commit b325e5c

File tree

5 files changed

+77
-1
lines changed

5 files changed

+77
-1
lines changed

lib/src/main/java/com/diffplug/spotless/java/ImportSorter.java

+22-1
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,23 @@ public String format(String raw) {
4040
int firstImportLine = 0;
4141
int lastImportLine = 0;
4242
int line = 0;
43+
boolean isMultiLineComment = false;
4344
List<String> imports = new ArrayList<>();
4445
while (scanner.hasNext()) {
4546
line++;
4647
String next = scanner.nextLine();
4748
if (next == null) {
4849
break;
4950
}
51+
//Since we have no AST, we only consider the most common use cases.
52+
isMultiLineComment |= next.contains("/*");
53+
if (isMultiLineComment && next.contains("*/")) {
54+
isMultiLineComment = false;
55+
if (!next.contains("/*")) {
56+
continue;
57+
}
58+
}
59+
5060
if (next.startsWith("import ")) {
5161
int i = next.indexOf(".");
5262
if (isNotValidImport(i)) {
@@ -59,17 +69,28 @@ public String format(String raw) {
5969
int endIndex = next.indexOf(";");
6070

6171
String imprt = next.substring(START_INDEX_OF_IMPORTS_PACKAGE_DECLARATION, endIndex != -1 ? endIndex : next.length());
62-
if (!imports.contains(imprt)) {
72+
if (!isMultiLineComment && !imports.contains(imprt)) {
6373
imports.add(imprt);
6474
}
6575
}
76+
if (!isMultiLineComment && isBeginningOfScope(next)) {
77+
break; //Don't dare to touch lines after a scope started
78+
}
6679
}
6780
scanner.close();
6881

6982
List<String> sortedImports = ImportSorterImpl.sort(imports, importsOrder);
7083
return applyImportsToDocument(raw, firstImportLine, lastImportLine, sortedImports);
7184
}
7285

86+
private static boolean isBeginningOfScope(String line) {
87+
int scope = line.indexOf("{");
88+
if (0 <= scope) {
89+
return !line.substring(0, scope).contains("//");
90+
}
91+
return false;
92+
}
93+
7394
private static String applyImportsToDocument(final String document, int firstImportLine, int lastImportLine, List<String> strings) {
7495
boolean importsAlreadyAppended = false;
7596
Scanner scanner = new Scanner(document);

testlib/src/test/java/com/diffplug/spotless/java/ImportOrderStepTest.java

+12
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ public void removeDuplicates() throws Throwable {
5050
assertOnResources(step, "java/importsorter/JavaCodeSortedDuplicateImportsUnmatched.test", "java/importsorter/JavaCodeSortedImportsUnmatched.test");
5151
}
5252

53+
@Test
54+
public void removeComments() throws Throwable {
55+
FormatterStep step = ImportOrderStep.createFromFile(createTestFile("java/importsorter/import.properties"));
56+
assertOnResources(step, "java/importsorter/JavaCodeImportComments.test", "java/importsorter/JavaCodeSortedImports.test");
57+
}
58+
59+
@Test
60+
public void misplacedImports() throws Throwable {
61+
FormatterStep step = ImportOrderStep.createFromFile(createTestFile("java/importsorter/import.properties"));
62+
assertOnResources(step, "java/importsorter/JavaCodeUnsortedMisplacedImports.test", "java/importsorter/JavaCodeSortedMisplacedImports.test");
63+
}
64+
5365
@Test
5466
public void doesntThrowIfImportOrderIsntSerializable() {
5567
ImportOrderStep.createFromOrder(NonSerializableList.of("java", "javax", "org", "\\#com"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import static java.lang.Exception.*;
2+
//Will be removed
3+
import org.dooda.Didoo; /* Comment removed, import stays */
4+
import java.lang.Thread; /* Don't */ /* get */ /* confused */
5+
import java.lang.Runnable;
6+
/* import org.comments.will
7+
import org.comments.be
8+
import org.comments.removed
9+
*/
10+
import static java.lang.Runnable.*;
11+
/*
12+
import other.multiline.comments
13+
import will.be.removed.too */
14+
import static com.foo.Bar
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import java.lang.Runnable;
2+
import java.lang.Thread;
3+
4+
import org.dooda.Didoo;
5+
6+
import static java.lang.Exception.*;
7+
import static java.lang.Runnable.*;
8+
9+
import static com.foo.Bar;
10+
public class NotDeletedByFormatter {
11+
}
12+
import will.not;
13+
import be.sorted;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import static java.lang.Exception.*;
2+
import org.dooda.Didoo;
3+
/*
4+
public class IgnoredAndRemoved {
5+
}
6+
*/
7+
import java.lang.Thread;
8+
// Will be removed {}
9+
import java.lang.Runnable;
10+
11+
import static java.lang.Runnable.*;
12+
import static com.foo.Bar
13+
public class NotDeletedByFormatter {
14+
}
15+
import will.not;
16+
import be.sorted;

0 commit comments

Comments
 (0)