Class ImportOrderCheck
- java.lang.Object
-
- com.puppycrawl.tools.checkstyle.api.AutomaticBean
-
- com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
-
- com.puppycrawl.tools.checkstyle.api.AbstractCheck
-
- com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck
-
- All Implemented Interfaces:
Configurable
,Contextualizable
public class ImportOrderCheck extends AbstractCheck
Checks the ordering/grouping of imports. Features are:
- groups type/static imports: ensures that groups of imports come in a specific order (e.g., java. comes first, javax. comes second, then everything else)
- adds a separation between type import groups : ensures that a blank line sit between each group
- type/static import groups aren't separated internally: ensures that each group aren't separated internally by blank line or comment
- sorts type/static imports inside each group: ensures that imports within each group are in lexicographic order
- sorts according to case: ensures that the comparison between imports is case sensitive, in ASCII sort order
- arrange static imports: ensures the relative order between type imports and static imports (see ImportOrderOption)
-
Property
option
- specify policy on the relative order between type imports and static imports. Type iscom.puppycrawl.tools.checkstyle.checks.imports.ImportOrderOption
. Default value isunder
. -
Property
groups
- specify list of type import groups (every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g./regexp/
). All type imports, which does not match any group, falls into an additional group, located at the end. Thus, the empty list of type groups (the default value) means one group for all type imports. Type isjava.lang.String[]
. Validation type isjava.util.regex.Pattern
. Default value is""
. -
Property
ordered
- control whether type imports within each group should be sorted. It doesn't affect sorting for static imports. Type isboolean
. Default value istrue
. -
Property
separated
- control whether type import groups should be separated by, at least, one blank line or comment and aren't separated internally. It doesn't affect separations for static imports. Type isboolean
. Default value isfalse
. -
Property
separatedStaticGroups
- control whether static import groups should be separated by, at least, one blank line or comment and aren't separated internally. This property has effect only when the propertyoption
is is set totop
orbottom
. Type isboolean
. Default value isfalse
. -
Property
caseSensitive
- control whether string comparison should be case sensitive or not. Case sensitive sorting is in ASCII sort order. It affects both type imports and static imports. Type isboolean
. Default value istrue
. -
Property
staticGroups
- specify list of static import groups (every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g./regexp/
). All static imports, which does not match any group, falls into an additional group, located at the end. Thus, the empty list of static groups (the default value) means one group for all static imports. This property has effect only when the propertyoption
is set totop
orbottom
. Type isjava.lang.String[]
. Validation type isjava.util.regex.Pattern
. Default value is""
. -
Property
sortStaticImportsAlphabetically
- control whether static imports located at top or bottom are sorted within the group. Type isboolean
. Default value isfalse
. -
Property
useContainerOrderingForStatic
- control whether to use container ordering (Eclipse IDE term) for static imports or not. Type isboolean
. Default value isfalse
. -
Property
tokens
- tokens to check Type isjava.lang.String[]
. Validation type istokenSet
. Default value is: STATIC_IMPORT.
To configure the check so that it matches default Eclipse formatter configuration (tested on Kepler and Luna releases):
- group of static imports is on the top
- groups of type imports: "java" and "javax" packages first, then "org" and then all other imports
- imports will be sorted in the groups
- groups are separated by, at least, one blank line and aren't separated internally
Notes:
- "com" package is not mentioned on configuration, because it is ignored by Eclipse Kepler and Luna (looks like Eclipse defect)
- configuration below doesn't work in all 100% cases due to inconsistent behavior prior to Mars release, but covers most scenarios
<module name="ImportOrder"> <property name="groups" value="/^java\./,javax,org"/> <property name="ordered" value="true"/> <property name="separated" value="true"/> <property name="option" value="above"/> <property name="sortStaticImportsAlphabetically" value="true"/> </module>
To configure the check so that it matches default Eclipse formatter configuration (tested on Mars release):
- group of static imports is on the top
- groups of type imports: "java" and "javax" packages first, then "org" and "com", then all other imports as one group
- imports will be sorted in the groups
- groups are separated by, at least, one blank line and aren't separated internally
<module name="ImportOrder"> <property name="groups" value="/^java\./,javax,org,com"/> <property name="ordered" value="true"/> <property name="separated" value="true"/> <property name="option" value="above"/> <property name="sortStaticImportsAlphabetically" value="true"/> </module>
To configure the check so that it matches default IntelliJ IDEA formatter configuration (tested on v2018.2):
- group of static imports is on the bottom
- groups of type imports: all imports except of "javax" and "java", then "javax" and "java"
- imports will be sorted in the groups
- groups are separated by, at least, one blank line and aren't separated internally
Note: a suppression xpath single filter is needed because IDEA has no blank line between "javax" and "java". ImportOrder has a limitation by design to enforce an empty line between groups ("java", "javax"). There is no flexibility to enforce empty lines between some groups and no empty lines between other groups.
Note: "separated" option is disabled because IDEA default has blank line between "java" and static imports, and no blank line between "javax" and "java".
<module name="ImportOrder"> <property name="groups" value="*,javax,java"/> <property name="ordered" value="true"/> <property name="separated" value="false"/> <property name="option" value="bottom"/> <property name="sortStaticImportsAlphabetically" value="true"/> </module> <module name="SuppressionXpathSingleFilter"> <property name="checks" value="ImportOrder"/> <property name="message" value="^'java\..*'.*"/> </module>
To configure the check so that it matches default NetBeans formatter configuration (tested on v8):
- groups of type imports are not defined, all imports will be sorted as a one group
- static imports are not separated, they will be sorted along with other imports
<module name="ImportOrder"> <property name="option" value="inflow"/> </module>
Group descriptions enclosed in slashes are interpreted as regular expressions. If multiple groups match, the one matching a longer substring of the imported name will take precedence, with ties broken first in favor of earlier matches and finally in favor of the first matching group.
There is always a wildcard group to which everything not in a named group belongs. If an import does not match a named group, the group belongs to this wildcard group. The wildcard group position can be specified using the
*
character.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:
<module name="ImportOrder"> <property name="sortStaticImportsAlphabetically" value="true"/> <property name="option" value="top"/> </module>
import static java.lang.Math.PI; import static java.lang.Math.abs; // OK, alphabetical case sensitive ASCII order, 'P' < 'a' import static org.abego.treelayout.Configuration.AlignmentInLevel; // OK, alphabetical order import org.abego.*; import java.util.Set; // Wrong order for 'java.util.Set' import. public class SomeClass { ... }
To configure the Check with groups of static imports:
<module name="ImportOrder"> <property name="staticGroups" value="org,java"/> <property name="sortStaticImportsAlphabetically" value="true"/> </module>
import static org.abego.treelayout.Configuration.AlignmentInLevel; // Group 1 import static java.lang.Math.abs; // Group 2 import static java.lang.String.format; // Group 2 import static com.google.common.primitives.Doubles.BYTES; // Group "everything else" public class SomeClass { ... }
The following example shows the idea of 'useContainerOrderingForStatic' option that is useful for Eclipse IDE users to match ordering validation. This is how the import comparison works for static imports: we first compare the container of the static import, container is the type enclosing the static element being imported. When the result of the comparison is 0 (containers are equal), we compare the fully qualified import names. For e.g. this is what is considered to be container names for the given example: import static HttpConstants.COLON => HttpConstants import static HttpHeaders.addHeader => HttpHeaders import static HttpHeaders.setHeader => HttpHeaders import static HttpHeaders.Names.DATE => HttpHeaders.Names According to this logic, HttpHeaders.Names should come after HttpHeaders.
Example for
useContainerOrderingForStatic=true
<module name="ImportOrder"> <property name="useContainerOrderingForStatic" value="true"/> <property name="ordered" value="true"/> <property name="option" value="top"/> <property name="caseSensitive" value="false"/> <property name="sortStaticImportsAlphabetically" value="true"/> </module>
import static io.netty.handler.codec.http.HttpConstants.COLON; import static io.netty.handler.codec.http.HttpHeaders.addHeader; import static io.netty.handler.codec.http.HttpHeaders.setHeader; import static io.netty.handler.codec.http.HttpHeaders.Names.DATE; public class InputEclipseStaticImportsOrder { }
Example for
useContainerOrderingForStatic=false
<module name="ImportOrder"> <property name="useContainerOrderingForStatic" value="false"/> <property name="ordered" value="true"/> <property name="option" value="top"/> <property name="caseSensitive" value="false"/> <property name="sortStaticImportsAlphabetically" value="true"/> </module>
import static io.netty.handler.codec.http.HttpConstants.COLON; import static io.netty.handler.codec.http.HttpHeaders.addHeader; import static io.netty.handler.codec.http.HttpHeaders.setHeader; import static io.netty.handler.codec.http.HttpHeaders.Names.DATE; // violation public class InputEclipseStaticImportsOrder { }
Parent is
com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
-
import.groups.separated.internally
-
import.ordering
-
import.separation
- Since:
- 3.2
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class com.puppycrawl.tools.checkstyle.api.AutomaticBean
AutomaticBean.OutputStreamOptions
-
-
Field Summary
Fields Modifier and Type Field Description static java.lang.String
MSG_ORDERING
A key is pointing to the warning message text in "messages.properties" file.static java.lang.String
MSG_SEPARATED_IN_GROUP
A key is pointing to the warning message text in "messages.properties" file.static java.lang.String
MSG_SEPARATION
A key is pointing to the warning message text in "messages.properties" file.
-
Constructor Summary
Constructors Constructor Description ImportOrderCheck()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
beginTree(DetailAST rootAST)
Called before the starting to process a tree.int[]
getAcceptableTokens()
The configurable token set.int[]
getDefaultTokens()
Returns the default token a check is interested in.int[]
getRequiredTokens()
The tokens that this check must be registered for.void
setCaseSensitive(boolean caseSensitive)
Setter to control whether string comparison should be case sensitive or not.void
setGroups(java.lang.String... packageGroups)
Setter to specify list of type import groups (every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g.void
setOption(java.lang.String optionStr)
Setter to specify policy on the relative order between type imports and static imports.void
setOrdered(boolean ordered)
Setter to control whether type imports within each group should be sorted.void
setSeparated(boolean separated)
Setter to control whether type import groups should be separated by, at least, one blank line or comment and aren't separated internally.void
setSeparatedStaticGroups(boolean separatedStaticGroups)
Setter to control whether static import groups should be separated by, at least, one blank line or comment and aren't separated internally.void
setSortStaticImportsAlphabetically(boolean sortAlphabetically)
Setter to control whether static imports located at top or bottom are sorted within the group.void
setStaticGroups(java.lang.String... packageGroups)
Setter to specify list of static import groups (every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g.void
setUseContainerOrderingForStatic(boolean useContainerOrdering)
Setter to control whether to use container ordering (Eclipse IDE term) for static imports or not.void
visitToken(DetailAST ast)
Called to process a token.-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractCheck
clearMessages, destroy, finishTree, getFileContents, getLine, getLines, getMessages, getTabWidth, getTokenNames, init, isCommentNodesRequired, leaveToken, log, log, log, setFileContents, setTabWidth, setTokens
-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
finishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverity
-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AutomaticBean
configure, contextualize, getConfiguration, setupChild
-
-
-
-
Field Detail
-
MSG_SEPARATION
public static final java.lang.String MSG_SEPARATION
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
MSG_ORDERING
public static final java.lang.String MSG_ORDERING
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
MSG_SEPARATED_IN_GROUP
public static final java.lang.String MSG_SEPARATED_IN_GROUP
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
-
Method Detail
-
setOption
public void setOption(java.lang.String optionStr)
Setter to specify policy on the relative order between type imports and static imports.- Parameters:
optionStr
- string to decode option from- Throws:
java.lang.IllegalArgumentException
- if unable to decode
-
setGroups
public void setGroups(java.lang.String... packageGroups)
Setter to specify list of type import groups (every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g./regexp/
). All type imports, which does not match any group, falls into an additional group, located at the end. Thus, the empty list of type groups (the default value) means one group for all type imports.- Parameters:
packageGroups
- a comma-separated list of package names/prefixes.
-
setStaticGroups
public void setStaticGroups(java.lang.String... packageGroups)
Setter to specify list of static import groups (every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g./regexp/
). All static imports, which does not match any group, falls into an additional group, located at the end. Thus, the empty list of static groups (the default value) means one group for all static imports. This property has effect only when the propertyoption
is set totop
orbottom
.- Parameters:
packageGroups
- a comma-separated list of package names/prefixes.
-
setOrdered
public void setOrdered(boolean ordered)
Setter to control whether type imports within each group should be sorted. It doesn't affect sorting for static imports.- Parameters:
ordered
- whether lexicographic ordering of imports within a group required or not.
-
setSeparated
public void setSeparated(boolean separated)
Setter to control whether type import groups should be separated by, at least, one blank line or comment and aren't separated internally. It doesn't affect separations for static imports.- Parameters:
separated
- whether groups should be separated by one blank line or comment.
-
setSeparatedStaticGroups
public void setSeparatedStaticGroups(boolean separatedStaticGroups)
Setter to control whether static import groups should be separated by, at least, one blank line or comment and aren't separated internally. This property has effect only when the propertyoption
is is set totop
orbottom
.- Parameters:
separatedStaticGroups
- whether groups should be separated by one blank line or comment.
-
setCaseSensitive
public void setCaseSensitive(boolean caseSensitive)
Setter to control whether string comparison should be case sensitive or not. Case sensitive sorting is in ASCII sort order. It affects both type imports and static imports.- Parameters:
caseSensitive
- whether string comparison should be case sensitive.
-
setSortStaticImportsAlphabetically
public void setSortStaticImportsAlphabetically(boolean sortAlphabetically)
Setter to control whether static imports located at top or bottom are sorted within the group.- Parameters:
sortAlphabetically
- true or false.
-
setUseContainerOrderingForStatic
public void setUseContainerOrderingForStatic(boolean useContainerOrdering)
Setter to control whether to use container ordering (Eclipse IDE term) for static imports or not.- Parameters:
useContainerOrdering
- whether to use container ordering for static imports or not.
-
getDefaultTokens
public int[] getDefaultTokens()
Description copied from class:AbstractCheck
Returns the default token a check is interested in. Only used if the configuration for a check does not define the tokens.- Specified by:
getDefaultTokens
in classAbstractCheck
- Returns:
- the default tokens
- See Also:
TokenTypes
-
getAcceptableTokens
public int[] getAcceptableTokens()
Description copied from class:AbstractCheck
The configurable token set. Used to protect Checks against malicious users who specify an unacceptable token set in the configuration file. The default implementation returns the check's default tokens.- Specified by:
getAcceptableTokens
in classAbstractCheck
- Returns:
- the token set this check is designed for.
- See Also:
TokenTypes
-
getRequiredTokens
public int[] getRequiredTokens()
Description copied from class:AbstractCheck
The tokens that this check must be registered for.- Specified by:
getRequiredTokens
in classAbstractCheck
- Returns:
- the token set this must be registered for.
- See Also:
TokenTypes
-
beginTree
public void beginTree(DetailAST rootAST)
Description copied from class:AbstractCheck
Called before the starting to process a tree. Ideal place to initialize information that is to be collected whilst processing a tree.- Overrides:
beginTree
in classAbstractCheck
- Parameters:
rootAST
- the root of the tree
-
visitToken
public void visitToken(DetailAST ast)
Description copied from class:AbstractCheck
Called to process a token.- Overrides:
visitToken
in classAbstractCheck
- Parameters:
ast
- the token to process
-
-