Import Order Check, added option allows alphabetical grouping order in static group, issue #12

This commit is contained in:
alexkravin 2015-03-13 18:52:59 +04:00 committed by Roman Ivanov
parent 2650bf757b
commit 5bd22fd613
8 changed files with 285 additions and 6 deletions

View File

@ -697,7 +697,7 @@
<regex><pattern>.*.checks.imports.IllegalImportCheck</pattern><branchRate>100</branchRate><lineRate>94</lineRate></regex>
<regex><pattern>.*.checks.imports.ImportControlCheck</pattern><branchRate>75</branchRate><lineRate>70</lineRate></regex>
<regex><pattern>.*.checks.imports.ImportControlLoader</pattern><branchRate>72</branchRate><lineRate>88</lineRate></regex>
<regex><pattern>.*.checks.imports.ImportOrderCheck</pattern><branchRate>91</branchRate><lineRate>98</lineRate></regex>
<regex><pattern>.*.checks.imports.ImportOrderCheck</pattern><branchRate>91</branchRate><lineRate>99</lineRate></regex>
<regex><pattern>.*.checks.imports.PkgControl</pattern><branchRate>80</branchRate><lineRate>100</lineRate></regex>
<regex><pattern>.*.checks.imports.RedundantImportCheck</pattern><branchRate>81</branchRate><lineRate>94</lineRate></regex>
<regex><pattern>.*.checks.imports.UnusedImportsCheck</pattern><branchRate>90</branchRate><lineRate>97</lineRate></regex>

View File

@ -78,16 +78,42 @@ import java.util.regex.Pattern;
* <li>ordered: true</li>
* <li>case sensitive: true</li>
* <li>static import: under</li>
* <li>sort static imports alphabetically: false</li>
* </ul>
*
* <p>
* Compatible with Java 1.5 source.
* Check also has on option making it more flexible:
* <b>sortStaticImportsAlphabetically</b> - sets whether static imports grouped by
* <b>top</b> or <b>bottom</b> option should be sorted alphabetically or
* not, default value is <b>false</b>. It is applied to static imports grouped
* with <b>top</b> or <b>bottom</b> options.<br>
* This option is helping in reconciling of this Check and other tools like
* Eclipse's Organize Imports feature.
* </p>
* <p>
* To configure the Check allows static imports grouped to the <b>top</b>
* being sorted alphabetically:
* </p>
* <p>
* <pre>
* <code>
* 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 { ... }
* </code>
* </pre>
* </p>
*
* @author Bill Schneider
* @author o_sukhodolsky
* @author David DIDIER
* @author Steve McKay
* @author <a href="mailto:nesterenko-aleksey@list.ru">Aleksey Nesterenko</a>
*/
public class ImportOrderCheck
extends AbstractOptionCheck<ImportOrderOption>
@ -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 <b>top<b/> or <b>bottom<b/> 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 <code>0</code> 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;
}
}

View File

@ -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);
}
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -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
{
}

View File

@ -429,6 +429,13 @@ class FooBar {
<td><a href="property_types.html#boolean">Boolean</a></td>
<td>true</td>
</tr>
<tr>
<td>sortStaticImportsAlphabetically</td>
<td>whether static imports grouped by <b>top</b> or <b>bottom</b> option
are sorted alphabetically or not</td>
<td><a href="property_types.html#boolean">Boolean</a></td>
<td>false</td>
</tr>
</table>
</subsection>
@ -449,6 +456,30 @@ class FooBar {
&lt;property name=&quot;option&quot; value=&quot;above&quot;/>
&lt;/module>
</source>
<p>
To configure the Check allows static imports grouped to the <b>top</b>
being sorted alphabetically:
</p>
<source>
&lt;module name=&quot;ImportOrder&quot;>
&lt;property name=&quot;sortStaticImportsAlphabetically&quot; value=&quot;true&quot;/>
&lt;property name=&quot;option&quot; value=&quot;top&quot;/>
&lt;/module>
</source>
<source>
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 { ... }
</source>
</subsection>
<subsection name="Package">