DescendantToken
Since Checkstyle 3.2
Description
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.
Properties
| 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 |
Examples
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) { // violation, 'Count of 0 for 'LITERAL_SWITCH' descendant'
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) { // violation, 'Count of 2 for 'LITERAL_SWITCH' descendant'
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) { // violation, 'Count of 0 for 'FOR_CONDITION' descendant'
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) { // violation, 'Count of 1 for 'LITERAL_CATCH' descendant'
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) { // violation, 'Count of 1 for 'LITERAL_CATCH' descendant'
try { }
catch (Exception ex) { }
return -1;
}
finally { // violation, 'Count of 1 for 'LITERAL_FINALLY' descendant '
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
; // violation, 'Empty statement is not allowed'
return 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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2; // violation below, 'Total count of 2 exceeds maximum count 1'
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
To configure the check to produce a violation with a custom message when the minimum count of descendants is not reached:
<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"/>
<property name="minimumMessage"
value="Switch must contain at least one default branch."/>
</module>
</module>
</module>
Example:
class Example17 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
// violation below 'Switch must contain at least one default branch.'
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) { // violation, 'Count of 0 for 'FOR_INIT' descendant'
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
// violation below 'Count of 2 for 'METHOD_DEF' descendant'
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
// violation below 'Count of 3 for 'METHOD_DEF' descendant'
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
// violation above, 'Count of 2 for 'LITERAL_THROWS' descendant'
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
// violation below, 'Count of 10 for 'METHOD_DEF' descendant'
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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; // violation above 'Count of 2 for 'CLASS_DEF' descendant'
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2; // violation below 'Count of 1 for 'EQUAL' descendant'
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0;
;
return 2;
}
}
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 {
private int field1;
private int field2;
int testMethod(int x, String str)
throws ArithmeticException, IllegalArgumentException {
switch (x) {
case 1:
break;
case 2:
break;
}
try { }
catch (Exception e) {
try { }
catch (Exception ex) { }
return -1;
}
finally {
try { }
catch (Exception ex) { }
}
for (;;) {
break;
}
int a = 1;
int b = 2;
if (this == null || str == "abc") {
return 0;
}
assert a++ == 0; // violation, 'Count of 1 for 'LITERAL_ASSERT' descendant'
;
return 2;
}
}
Example of Usage
Violation Messages
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
Fully Qualified Name
com.puppycrawl.tools.checkstyle.checks.DescendantTokenCheck
Use this fully qualified class name in configuration when an exact class reference is required.






