Since Checkstyle 3.2
WARNING: This is a very powerful and flexible check, but, at the same time, it is low-level and very implementation-dependent because its results depend on the grammar we use to build abstract syntax trees. Thus, we recommend using other checks when they provide the desired functionality. Essentially, this check just works on the level of an abstract syntax tree and knows nothing about language structures.
name | description | type | default value | since |
---|---|---|---|---|
limitedTokens | Specify set of tokens with limited occurrences as descendants. | subset of tokens TokenTypes | {} |
3.2 |
maximumDepth | Specify the maximum depth for descendant counts. | int | 2147483647 |
3.2 |
maximumMessage | Define the violation message when the maximum count is exceeded. | String | null |
3.2 |
maximumNumber | Specify a maximum count for descendants. | int | 2147483647 |
3.2 |
minimumDepth | Specify the minimum depth for descendant counts. | int | 0 |
3.2 |
minimumMessage | Define the violation message when the minimum count is not reached. | String | null |
3.2 |
minimumNumber | Specify a minimum count for descendants. | int | 0 |
3.2 |
sumTokenCounts | Control whether the number of tokens found should be calculated from the sum of the individual token counts. | boolean | false |
5.0 |
tokens | tokens to check | set of any supported tokens | empty |
3.2 |
To configure the check to produce a violation on a switch statement with no default case:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="LITERAL_SWITCH"/> <property name="maximumDepth" value="2"/> <property name="limitedTokens" value="LITERAL_DEFAULT"/> <property name="minimumNumber" value="1"/> </module> </module> </module>
Example:
class Example1 { void testMethod1() { int x = 1; switch (x) { case 1: System.out.println("hi"); break; default: System.out.println("Default"); break; } int y = 1; switch (y) { // violation, 'Count of 0 for 'LITERAL_SWITCH' descendant' case 1: System.out.println("hi"); break; } } void testMethod2() { int x = 1; switch (x) { case 1: // Some code break; default: // Some code break; } switch (x) { case 1: // Some code break; case 2: // Some code break; default: // Some code break; } } void testMethod3() { int x = 1; int y = 2; switch (x) { // violation, 'Count of 0 for 'LITERAL_SWITCH' descendant' case 1: System.out.println("xyz"); break; } switch (y) { // violation, 'Count of 0 for 'LITERAL_SWITCH' descendant' case 1: switch (y) { // violation, 'Count of 0 for 'LITERAL_SWITCH' descendant' case 2: System.out.println("xyz"); break; } break; } } }
To configure the check to produce a violation on a switch with too many cases:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="LITERAL_SWITCH"/> <property name="limitedTokens" value="LITERAL_CASE"/> <property name="maximumDepth" value="2"/> <property name="maximumNumber" value="1"/> </module> </module> </module>
Example:
class Example2 { void testMethod1() { int x = 1; switch (x) { case 1: System.out.println("hi"); break; default: System.out.println("Default"); break; } int y = 1; switch (y) { case 1: System.out.println("hi"); break; } } void testMethod2() { int x = 1; switch (x) { case 1: // Some code break; default: // Some code break; } switch (x) { // violation, 'Count of 2 for 'LITERAL_SWITCH' descendant' case 1: // Some code break; case 2: // Some code break; default: // Some code break; } } void testMethod3() { int x = 1; int y = 2; switch (x) { case 1: System.out.println("xyz"); break; } switch (y) { case 1: switch (y) { case 2: System.out.println("xyz"); break; } break; } } }
To configure the check to produce a violation on a switch that is nested in another switch:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="LITERAL_SWITCH"/> <property name="limitedTokens" value="LITERAL_SWITCH"/> <property name="maximumNumber" value="0"/> <property name="minimumDepth" value="1"/> </module> </module> </module>
Example:
class Example3 { void testMethod1() { int x = 1; switch (x) { case 1: System.out.println("hi"); break; default: System.out.println("Default"); break; } int y = 1; switch (y) { case 1: System.out.println("hi"); break; } } void testMethod2() { int x = 1; switch (x) { case 1: // Some code break; default: // Some code break; } switch (x) { case 1: // Some code break; case 2: // Some code break; default: // Some code break; } } void testMethod3() { int x = 1; int y = 2; switch (x) { case 1: System.out.println("xyz"); break; } switch (y) { // violation, 'Count of 1 for 'LITERAL_SWITCH' descendant' case 1: switch (y) { case 2: System.out.println("xyz"); break; } break; } } }
To configure the check to produce a violation on a
condition in for
which performs no check:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="FOR_CONDITION"/> <property name="limitedTokens" value="EXPR"/> <property name="minimumNumber" value="1"/> </module> </module> </module>
Example:
class Example4 { void testMethod1() { for (int i = 0; i != 10; i++) { System.out.println(i); } int k = 0; for (; ; ) { // violation, 'Count of 0 for 'FOR_CONDITION' descendant' System.out.println(k); } } void testMethod2() { int[] array = new int[] {1, 2, 3, 4, 5}; for (int i = 0; i != array.length; i++) { System.out.println(i); } int j = 0; for (; j != array.length;) { System.out.println(j); j++; } } }
To configure the check to produce a violation on an initializer in
for
performs no setup (where a while
statement could be used instead):
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="FOR_INIT"/> <property name="limitedTokens" value="EXPR"/> <property name="minimumNumber" value="1"/> </module> </module> </module>
Example:
class Example5 { void testMethod1() { for (int i = 0; i != 10; i++) { System.out.println(i); } int k = 0; for (; ; ) { // violation, 'Count of 0 for 'FOR_INIT' descendant' System.out.println(k); } } void testMethod2() { int[] array = new int[] {1, 2, 3, 4, 5}; for (int i = 0; i != array.length; i++) { System.out.println(i); } int j = 0; // violation below, 'Count of 0 for 'FOR_INIT' descendant' for (; j != array.length;) { System.out.println(j); j++; } } }
To configure the check to produce a violation on a return statement from within a catch or finally block:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="LITERAL_FINALLY,LITERAL_CATCH"/> <property name="limitedTokens" value="LITERAL_RETURN"/> <property name="maximumNumber" value="0"/> </module> </module> </module>
Example:
class Example6 { void testMethod1() { try {} catch (Exception e) { // violation, 'Count of 1 for 'LITERAL_CATCH' descendant' System.out.println("xyz"); return; } finally { System.out.println("xyz"); } } void testMethod2() { try {} catch (Exception e) { // violation, 'Count of 1 for 'LITERAL_CATCH' descendant' System.out.println("xyz"); return; } finally { System.out.println("xyz"); } try {} catch (Exception e) { try {} catch (Exception ex) { // handle exception } } finally { try {} catch (Exception e) { // handle exception } } } }
To configure the check to produce a violation on a try statement within a catch or finally block:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="LITERAL_CATCH,LITERAL_FINALLY"/> <property name="limitedTokens" value="LITERAL_TRY"/> <property name="maximumNumber" value="0"/> </module> </module> </module>
Example:
class Example7 { void testMethod1() { try {} catch (Exception e) { System.out.println("xyz"); return; } finally { System.out.println("xyz"); } } void testMethod2() { try {} catch (Exception e) { System.out.println("xyz"); return; } finally { System.out.println("xyz"); } try {} catch (Exception e) { // violation, 'Count of 1 for 'LITERAL_CATCH' descendant' try {} catch (Exception ex) { // handle exception } } finally { // violation, 'Count of 1 for 'LITERAL_FINALLY' descendant ' try {} catch (Exception e) { // handle exception } } } }
To configure the check to produce a violation on a method with too many local variables:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="METHOD_DEF"/> <property name="limitedTokens" value="VARIABLE_DEF"/> <property name="maximumDepth" value="2"/> <property name="maximumNumber" value="1"/> </module> </module> </module>
Example:
class Example8 { void testMethod1() { int var1 = 1; } void testMethod2() { // violation 'Count of 2 for 'METHOD_DEF' descendant' int var1 = 1; int var2 = 2; } int testMethod3(int x) { if (x == -1) { return -1; } else if (x == 0) { return 0; } return -1; } int testMethod4(int x) { if (x == -1) { return -1; } else if (x == 0) { return 0; } else { return x; } } }
To configure the check to produce a violation on a method with too many returns:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="METHOD_DEF"/> <property name="limitedTokens" value="LITERAL_RETURN"/> <property name="maximumNumber" value="2"/> </module> </module> </module>
Example:
class Example9 { void testMethod1() { int var1 = 1; } void testMethod2() { int var1 = 1; int var2 = 2; } int testMethod3(int x) { // violation 'Count of 3 for 'METHOD_DEF' descendant' if (x == -1) { return -1; } else if (x == 0) { return 0; } return -1; } int testMethod4(int x) { // violation 'Count of 3 for 'METHOD_DEF' descendant' if (x == -1) { return -1; } else if (x == 0) { return 0; } else { return x; } } }
To configure the check to produce a violation on a method which throws too many exceptions:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="LITERAL_THROWS"/> <property name="limitedTokens" value="IDENT"/> <property name="maximumNumber" value="1"/> </module> </module> </module>
Example:
class Example10 { void testMethod1() throws ArithmeticException { // ... } // violation below, 'Count of 2 for 'LITERAL_THROWS' descendant' void testMethod2() throws ArithmeticException, ArithmeticException { // ... } }
To configure the check to produce a violation on a method with too many expressions:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="METHOD_DEF"/> <property name="limitedTokens" value="EXPR"/> <property name="maximumNumber" value="2"/> </module> </module> </module>
Example:
class Example11 { void testMethod1() { int x = 1; int z = x + 2; } // violation below, 'Count of 3 for 'METHOD_DEF' descendant' void testMethod2() { int x = 1; int y = 2; int z = x + y; } }
To configure the check to produce a violation on an empty statement:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="EMPTY_STAT"/> <property name="limitedTokens" value="EMPTY_STAT"/> <property name="maximumNumber" value="0"/> <property name="maximumDepth" value="0"/> <property name="maximumMessage" value="Empty statement is not allowed."/> </module> </module> </module>
Example:
class Example12 { void testMethod1 () { System.out.println("Hello"); } void testMethod2() { ; // violation, 'Empty statement is not allowed' } }
To configure the check to produce a violation on a class or interface with too many fields:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="CLASS_DEF,INTERFACE_DEF"/> <property name="limitedTokens" value="VARIABLE_DEF"/> <property name="maximumDepth" value="2"/> <property name="maximumNumber" value="1"/> </module> </module> </module>
Example:
class Example13 { private int field1; // Some code } // violation below, 'Count of 2 for 'CLASS_DEF' descendant' class ExampleTest { private int field1; private int field2; // Some code } interface Test1 { int FIELD_1 = 1; } // violation below,'Count of 2 for 'INTERFACE_DEF' descendant' interface Test2 { int FIELD_1 = 1; int FIELD_2 = 2; }
To configure the check to produce a violation on
comparing this
with null
:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="EQUAL,NOT_EQUAL"/> <property name="limitedTokens" value="LITERAL_THIS,LITERAL_NULL"/> <property name="maximumNumber" value="1"/> <property name="maximumDepth" value="1"/> <property name="sumTokenCounts" value="true"/> </module> </module> </module>
Example:
class Example14 { void testMethod1() { // violation below, 'Total count of 2 exceeds maximum count 1' if (this == null) { System.out.println("xyz"); } if (this != null) { // violation above, 'Total count of 2 exceeds maximum count 1' System.out.println("xyz"); } Object obj = new Object(); if (obj == null) { System.out.println("xyz"); } if (obj != null) { System.out.println("xyz"); } } }
To configure the check to produce a violation on a String
literal equality check:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="EQUAL,NOT_EQUAL"/> <property name="limitedTokens" value="STRING_LITERAL"/> <property name="maximumNumber" value="0"/> <property name="maximumDepth" value="1"/> </module> </module> </module>
Example:
class Example15 { void testMethod1() { String str = "abc"; if (str.equals("abc")) { System.out.println("equal."); } if (str == "abc") { // violation, 'Count of 1 for 'EQUAL' descendant' System.out.println("equal."); } } }
To configure the check to produce a violation on an assert statement that may have side effects:
<module name="Checker"> <module name="TreeWalker"> <module name="DescendantToken"> <property name="tokens" value="LITERAL_ASSERT"/> <property name="limitedTokens" value="ASSIGN,DEC,INC,POST_DEC, POST_INC,PLUS_ASSIGN,MINUS_ASSIGN,STAR_ASSIGN,DIV_ASSIGN,MOD_ASSIGN, BSR_ASSIGN,SR_ASSIGN,SL_ASSIGN,BAND_ASSIGN,BXOR_ASSIGN,BOR_ASSIGN, METHOD_CALL"/> <property name="maximumNumber" value="0"/> </module> </module> </module>
Example:
class Example16 { void testMethod1() { int a = 5; // violation below, 'Count of 1 for 'LITERAL_ASSERT' descendant' assert a++ == 0 : "is not"; System.out.println(a); assert a == 0 : "is not"; } }
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
com.puppycrawl.tools.checkstyle.checks