From 5bd22fd6136bd16e82d32c5a386bcf033004d8eb Mon Sep 17 00:00:00 2001 From: alexkravin Date: Fri, 13 Mar 2015 18:52:59 +0400 Subject: [PATCH] Import Order Check, added option allows alphabetical grouping order in static group, issue #12 --- pom.xml | 2 +- .../checks/imports/ImportOrderCheck.java | 71 ++++++++- .../checks/imports/ImportOrderCheckTest.java | 135 ++++++++++++++++++ .../InputImportOrderStaticGroupOrder.java | 13 ++ ...nputImportOrderStaticGroupOrderBottom.java | 13 ++ ...utImportOrderStaticOnDemandGroupOrder.java | 13 ++ ...rtOrderStaticOnDemandGroupOrderBottom.java | 13 ++ src/xdocs/config_imports.xml | 31 ++++ 8 files changed, 285 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticGroupOrder.java create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticGroupOrderBottom.java create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticOnDemandGroupOrder.java create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticOnDemandGroupOrderBottom.java diff --git a/pom.xml b/pom.xml index ed0f16ed9..35a96fee7 100644 --- a/pom.xml +++ b/pom.xml @@ -697,7 +697,7 @@ .*.checks.imports.IllegalImportCheck10094 .*.checks.imports.ImportControlCheck7570 .*.checks.imports.ImportControlLoader7288 - .*.checks.imports.ImportOrderCheck9198 + .*.checks.imports.ImportOrderCheck9199 .*.checks.imports.PkgControl80100 .*.checks.imports.RedundantImportCheck8194 .*.checks.imports.UnusedImportsCheck9097 diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheck.java index 108205471..5e2f8111c 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheck.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheck.java @@ -78,16 +78,42 @@ import java.util.regex.Pattern; *
  • ordered: true
  • *
  • case sensitive: true
  • *
  • static import: under
  • + *
  • sort static imports alphabetically: false
  • * * *

    - * Compatible with Java 1.5 source. + * Check also has on option making it more flexible: + * sortStaticImportsAlphabetically - sets whether static imports grouped by + * top or bottom option should be sorted alphabetically or + * not, default value is false. It is applied to static imports grouped + * with top or bottom options.
    + * This option is helping in reconciling of this Check and other tools like + * Eclipse's Organize Imports feature. + *

    + *

    + * To configure the Check allows static imports grouped to the top + * being sorted alphabetically: + *

    + *

    + *

    + * 
    + * import static java.lang.Math.abs;
    + * import static org.abego.treelayout.Configuration.AlignmentInLevel; // OK, alphabetical order
    + *
    + * import org.abego.*;
    + *
    + * import java.util.Set;
    + *
    + * public class SomeClass { ... }
    + * 
    + * 
    *

    * * @author Bill Schneider * @author o_sukhodolsky * @author David DIDIER * @author Steve McKay + * @author Aleksey Nesterenko */ public class ImportOrderCheck extends AbstractOptionCheck @@ -127,6 +153,8 @@ public class ImportOrderCheck private boolean lastImportStatic; /** Whether there was any imports. */ private boolean beforeFirstImport; + /** Whether static imports should be sorted alphabetically or not. */ + private boolean sortStaticImportsAlphabetically; /** * Groups static imports under each group. @@ -209,6 +237,16 @@ public class ImportOrderCheck this.caseSensitive = caseSensitive; } + /** + * Sets whether static imports (when grouped using 'top' and 'bottom' option) + * are sorted alphabetically or according to the package groupings. + * @param sortAlphabetically true or false. + */ + public void setSortStaticImportsAlphabetically(boolean sortAlphabetically) + { + this.sortStaticImportsAlphabetically = sortAlphabetically; + } + @Override public int[] getDefaultTokens() { @@ -311,7 +349,9 @@ public class ImportOrderCheck } } } - else if (groupIdx == lastGroup) { + else if (groupIdx == lastGroup || (sortStaticImportsAlphabetically + && isAlphabeticallySortableStaticImport(isStatic))) + { doVisitTokenInSameGroup(isStatic, previous, name, line); } else { @@ -323,6 +363,23 @@ public class ImportOrderCheck } } + /** + * Checks whether static imports grouped by top or bottom option + * are sorted alphabetically or not. + * @param isStatic if current import is static. + * @return true if static imports should be sorted alphabetically. + */ + private boolean isAlphabeticallySortableStaticImport(boolean isStatic) + { + boolean result = false; + if (isStatic && (getAbstractOption() == ImportOrderOption.TOP + || getAbstractOption() == ImportOrderOption.BOTTOM)) + { + result = true; + } + return result; + } + /** * Shares processing... * @@ -410,13 +467,17 @@ public class ImportOrderCheck * than the string2; and a value greater than 0 if * string1 is lexicographically greater than string2. */ - private int compare(String string1, String string2, + private static int compare(String string1, String string2, boolean caseSensitive) { + int result; if (caseSensitive) { - return string1.compareTo(string2); + result = string1.compareTo(string2); + } + else { + result = string1.compareToIgnoreCase(string2); } - return string1.compareToIgnoreCase(string2); + return result; } } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheckTest.java index 44cf7cfa6..7dc77b8c1 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheckTest.java @@ -227,4 +227,139 @@ public class ImportOrderCheckTest extends BaseCheckTestSupport final String[] expected = {}; verify(checkConfig, getPath("imports" + File.separator + "InputImportOrder_NoFailureForRedundantImports.java"), expected); } + + @Test + public void testStaticGroupsAlphabeticalOrder() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "top"); + checkConfig.addAttribute("groups", "org, java"); + checkConfig.addAttribute("sortStaticImportsAlphabetically", "true"); + final String[] expected = {}; + verify(checkConfig, getPath("imports" + File.separator + "InputImportOrderStaticGroupOrder.java"), expected); + } + + @Test + public void testStaticGroupsOrder() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "top"); + checkConfig.addAttribute("groups", "org, java"); + final String[] expected = { + "4: " + getCheckMessage(MSG_ORDERING, "org.abego.treelayout.Configuration.AlignmentInLevel"), + }; + verify(checkConfig, getPath("imports" + File.separator + "InputImportOrderStaticGroupOrder.java"), expected); + } + + @Test + public void testStaticGroupsAlphabeticalOrderBottom() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "bottom"); + checkConfig.addAttribute("groups", "org, java"); + checkConfig.addAttribute("sortStaticImportsAlphabetically", "true"); + final String[] expected = {}; + verify(checkConfig, getPath("imports" + File.separator + "InputImportOrderStaticGroupOrderBottom.java"), expected); + } + + @Test + public void testStaticGroupsOrderBottom() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "bottom"); + checkConfig.addAttribute("groups", "org, java"); + final String[] expected = { + "8: " + getCheckMessage(MSG_ORDERING, "org.abego.treelayout.Configuration.AlignmentInLevel"), + }; + verify(checkConfig, getPath("imports" + File.separator + "InputImportOrderStaticGroupOrderBottom.java"), expected); + } + + @Test + public void testStaticGroupsOrderAbove() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "above"); + checkConfig.addAttribute("groups", "org, java"); + checkConfig.addAttribute("sortStaticImportsAlphabetically", "true"); + final String[] expected = { + "7: " + getCheckMessage(MSG_ORDERING, "java.lang.Math.PI"), + "8: " + getCheckMessage(MSG_ORDERING, "org.abego.treelayout.Configuration.AlignmentInLevel"), + }; + verify(checkConfig, getPath("imports" + File.separator + "InputImportOrderStaticGroupOrderBottom.java"), expected); + } + + @Test + public void testStaticOnDemandGroupsOrder() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "top"); + checkConfig.addAttribute("groups", "org, java"); + final String[] expected = { + "4: " + getCheckMessage(MSG_ORDERING, "org.abego.treelayout.Configuration.*"), + }; + verify(checkConfig, getPath("imports" + File.separator + + "InputImportOrderStaticOnDemandGroupOrder.java"), expected); + } + + @Test + public void testStaticOnDemandGroupsAlphabeticalOrder() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "top"); + checkConfig.addAttribute("groups", "org, java"); + checkConfig.addAttribute("sortStaticImportsAlphabetically", "true"); + final String[] expected = {}; + verify(checkConfig, getPath("imports" + File.separator + + "InputImportOrderStaticOnDemandGroupOrder.java"), expected); + } + + @Test + public void testStaticOnDemandGroupsOrderBottom() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "bottom"); + checkConfig.addAttribute("groups", "org, java"); + final String[] expected = { + "8: " + getCheckMessage(MSG_ORDERING, "org.abego.treelayout.Configuration.*"), + }; + verify(checkConfig, getPath("imports" + File.separator + + "InputImportOrderStaticOnDemandGroupOrderBottom.java"), expected); + } + + @Test + public void testStaticOnDemandGroupsAlphabeticalOrderBottom() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "bottom"); + checkConfig.addAttribute("groups", "org, java"); + checkConfig.addAttribute("sortStaticImportsAlphabetically", "true"); + final String[] expected = {}; + verify(checkConfig, getPath("imports" + File.separator + + "InputImportOrderStaticOnDemandGroupOrderBottom.java"), expected); + } + + @Test + public void testStaticOnDemandGroupsOrderAbove() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(ImportOrderCheck.class); + checkConfig.addAttribute("option", "above"); + checkConfig.addAttribute("groups", "org, java"); + checkConfig.addAttribute("sortStaticImportsAlphabetically", "true"); + final String[] expected = { + "7: " + getCheckMessage(MSG_ORDERING, "java.lang.Math.*"), + "8: " + getCheckMessage(MSG_ORDERING, "org.abego.treelayout.Configuration.*"), + }; + verify(checkConfig, getPath("imports" + File.separator + + "InputImportOrderStaticOnDemandGroupOrderBottom.java"), expected); + } } diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticGroupOrder.java b/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticGroupOrder.java new file mode 100644 index 000000000..699cd4139 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticGroupOrder.java @@ -0,0 +1,13 @@ +package com.puppycrawl.tools.checkstyle.imports; + +import static java.lang.Math.abs; +import static org.abego.treelayout.Configuration.AlignmentInLevel; + +import org.*; + +import java.util.Set; + +public class InputImportOrderStaticGroupOrder +{ + +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticGroupOrderBottom.java b/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticGroupOrderBottom.java new file mode 100644 index 000000000..461e61adb --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticGroupOrderBottom.java @@ -0,0 +1,13 @@ +package com.puppycrawl.tools.checkstyle.imports; + +import org.*; + +import java.util.Set; + +import static java.lang.Math.PI; +import static org.abego.treelayout.Configuration.AlignmentInLevel; + +public class InputImportOrderStaticGroupOrderBottom +{ + +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticOnDemandGroupOrder.java b/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticOnDemandGroupOrder.java new file mode 100644 index 000000000..7ebac9034 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticOnDemandGroupOrder.java @@ -0,0 +1,13 @@ +package com.puppycrawl.tools.checkstyle.imports; + +import static java.lang.Math.*; +import static org.abego.treelayout.Configuration.*; + +import org.*; + +import java.util.Set; + +public class InputImportOrderStaticOnDemandGroupOrder +{ + +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticOnDemandGroupOrderBottom.java b/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticOnDemandGroupOrderBottom.java new file mode 100644 index 000000000..89feb4061 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/imports/InputImportOrderStaticOnDemandGroupOrderBottom.java @@ -0,0 +1,13 @@ +package com.puppycrawl.tools.checkstyle.imports; + +import org.*; + +import java.util.Set; + +import static java.lang.Math.*; +import static org.abego.treelayout.Configuration.*; + +public class InputImportOrderStaticOnDemandGroupOrderBottom +{ + +} diff --git a/src/xdocs/config_imports.xml b/src/xdocs/config_imports.xml index 7242573b7..524c6dd1b 100644 --- a/src/xdocs/config_imports.xml +++ b/src/xdocs/config_imports.xml @@ -429,6 +429,13 @@ class FooBar { Boolean true + + sortStaticImportsAlphabetically + whether static imports grouped by top or bottom option + are sorted alphabetically or not + Boolean + false + @@ -449,6 +456,30 @@ class FooBar { <property name="option" value="above"/> </module> + +

    + To configure the Check allows static imports grouped to the top + being sorted alphabetically: +

    + + +<module name="ImportOrder"> + <property name="sortStaticImportsAlphabetically" value="true"/> + <property name="option" value="top"/> +</module> + + + +import static java.lang.Math.abs; +import static org.abego.treelayout.Configuration.AlignmentInLevel; // OK, alphabetical order + +import org.abego.*; + +import java.util.Set; + +public class SomeClass { ... } + +