Skip to content

Commit b11ae32

Browse files
author
Adi
committed
Merge pull request #8 from AlexHaxe/dev
added NestedIfDepth, NestedForDepth and NestedTryDepth checks
2 parents 32d4f22 + 2ae612a commit b11ae32

12 files changed

+458
-20
lines changed

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,27 @@ More information in [wiki page](https://github.com/adireddy/haxe-checkstyle/wiki
102102
"privateUnderscorePrefix": false
103103
}
104104
},
105+
{
106+
"type": "NestedForDepth",
107+
"props": {
108+
"severity": "ERROR",
109+
"max": 1
110+
}
111+
},
112+
{
113+
"type": "NestedIfDepth",
114+
"props": {
115+
"severity": "ERROR",
116+
"max": 1
117+
}
118+
},
119+
{
120+
"type": "NestedTryDepth",
121+
"props": {
122+
"severity": "ERROR",
123+
"max": 1
124+
}
125+
},
105126
{
106127
"type": "Override",
107128
"props": {
@@ -112,7 +133,7 @@ More information in [wiki page](https://github.com/adireddy/haxe-checkstyle/wiki
112133
"type": "ParameterNumber",
113134
"props": {
114135
"severity": "INFO",
115-
"max": 10,
136+
"max": 7,
116137
"ignoreOverriddenMethods": false
117138
}
118139
},
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package checkstyle.checks;
2+
3+
import checkstyle.LintMessage.SeverityLevel;
4+
import haxeparser.Data;
5+
import haxe.macro.Expr;
6+
7+
@name("NestedForDepth")
8+
@desc("Max number of nested for blocks (default 1)")
9+
class NestedForDepthCheck extends Check {
10+
11+
public var severity:String = "ERROR";
12+
public var max:Int = 1;
13+
14+
override function _actualRun() {
15+
for (td in _checker.ast.decls) {
16+
switch (td.decl) {
17+
case EClass(d):
18+
checkFields(d);
19+
default:
20+
}
21+
}
22+
}
23+
24+
function checkFields(d:Definition<ClassFlag, Array<Field>>) {
25+
for (field in d.data) {
26+
checkField(field);
27+
}
28+
}
29+
30+
function checkField(f:Field) {
31+
switch (f.kind) {
32+
case FFun(fun):
33+
scanBlock(fun.expr, -1);
34+
default:
35+
}
36+
}
37+
38+
function scanBlock(e:Expr, depth:Int) {
39+
if (e == null) return;
40+
if (depth > max) {
41+
_warnNestedForDepth(depth, e.pos);
42+
return;
43+
}
44+
switch(e.expr) {
45+
case EBlock(exprs):
46+
scanExprs(exprs, depth);
47+
default:
48+
}
49+
}
50+
51+
function scanExprs(exprs:Array<Expr>, depth:Int) {
52+
for (e in exprs) {
53+
switch(e.expr) {
54+
case EFor(_, expr):
55+
scanBlock(expr, depth + 1);
56+
case EWhile(_, expr, _):
57+
scanBlock(expr, depth + 1);
58+
default:
59+
}
60+
}
61+
}
62+
63+
function _warnNestedForDepth(depth:Int, pos:Position) {
64+
logPos('Nested for depth is $depth (max allowed is ${max})', pos, Reflect.field(SeverityLevel, severity));
65+
}
66+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package checkstyle.checks;
2+
3+
import checkstyle.LintMessage.SeverityLevel;
4+
import haxeparser.Data;
5+
import haxe.macro.Expr;
6+
7+
@name("NestedIfDepth")
8+
@desc("Max number of nested if-else blocks (default 1)")
9+
class NestedIfDepthCheck extends Check {
10+
11+
public var severity:String = "ERROR";
12+
public var max:Int = 1;
13+
14+
override function _actualRun() {
15+
for (td in _checker.ast.decls) {
16+
switch (td.decl) {
17+
case EClass(d):
18+
checkFields(d);
19+
default:
20+
}
21+
}
22+
}
23+
24+
function checkFields(d:Definition<ClassFlag, Array<Field>>) {
25+
for (field in d.data) {
26+
checkField(field);
27+
}
28+
}
29+
30+
function checkField(f:Field) {
31+
switch (f.kind) {
32+
case FFun(fun):
33+
scanBlock(fun.expr, -1);
34+
default:
35+
}
36+
}
37+
38+
function scanBlock(e:Expr, depth:Int) {
39+
if (e == null) return;
40+
if (depth > max) {
41+
_warnNestedIfDepth(depth, e.pos);
42+
return;
43+
}
44+
switch(e.expr) {
45+
case EBlock(exprs):
46+
scanExprs(exprs, depth);
47+
default:
48+
}
49+
}
50+
51+
function scanExprs(exprs:Array<Expr>, depth:Int) {
52+
for (e in exprs) {
53+
switch(e.expr) {
54+
case EIf(_, ifPart,elsePart):
55+
scanBlock(ifPart, depth + 1);
56+
scanBlock(elsePart, depth + 1);
57+
default:
58+
}
59+
}
60+
}
61+
62+
function _warnNestedIfDepth(depth:Int, pos:Position) {
63+
logPos('Nested if-else depth is $depth (max allowed is ${max})', pos, Reflect.field(SeverityLevel, severity));
64+
}
65+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package checkstyle.checks;
2+
3+
import checkstyle.LintMessage.SeverityLevel;
4+
import haxeparser.Data;
5+
import haxe.macro.Expr;
6+
7+
@name("NestedTryDepth")
8+
@desc("Max number of nested try blocks (default 1)")
9+
class NestedTryDepthCheck extends Check {
10+
11+
public var severity:String = "ERROR";
12+
public var max:Int = 1;
13+
14+
override function _actualRun() {
15+
for (td in _checker.ast.decls) {
16+
switch (td.decl) {
17+
case EClass(d):
18+
checkFields(d);
19+
default:
20+
}
21+
}
22+
}
23+
24+
function checkFields(d:Definition<ClassFlag, Array<Field>>) {
25+
for (field in d.data) {
26+
checkField(field);
27+
}
28+
}
29+
30+
function checkField(f:Field) {
31+
switch (f.kind) {
32+
case FFun(fun):
33+
scanBlock(fun.expr, -1);
34+
default:
35+
}
36+
}
37+
38+
function scanBlock(e:Expr, depth:Int) {
39+
if (e == null) return null;
40+
if (depth > max) {
41+
_warnNestedTryDepth(depth, e.pos);
42+
return;
43+
}
44+
switch(e.expr) {
45+
case EBlock(exprs):
46+
scanExprs(exprs, depth);
47+
default:
48+
}
49+
}
50+
51+
function scanExprs(exprs:Array<Expr>, depth:Int) {
52+
for (e in exprs) {
53+
switch(e.expr) {
54+
case ETry(expr,catches):
55+
scanBlock(expr, depth + 1);
56+
scanCatches(catches, depth + 1);
57+
default:
58+
}
59+
}
60+
}
61+
62+
function scanCatches(catches:Array<Catch>, depth:Int) {
63+
for (c in catches) {
64+
scanBlock(c.expr, depth);
65+
}
66+
}
67+
68+
function _warnNestedTryDepth(depth:Int, pos:Position) {
69+
logPos('Nested try depth is $depth (max allowed is ${max})', pos, Reflect.field(SeverityLevel, severity));
70+
}
71+
}

checkstyle/checks/ParameterNumberCheck.hx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ import haxeparser.Data;
55
import haxe.macro.Expr;
66

77
@name("ParameterNumber")
8-
@desc("Max number of parameters per method (default 10)")
8+
@desc("Max number of parameters per method (default 7)")
99
class ParameterNumberCheck extends Check {
1010

1111
public var severity:String = "INFO";
12-
public var max:Int = 10;
12+
public var max:Int = 7;
1313
public var ignoreOverriddenMethods:Bool = false;
1414

1515
override function _actualRun() {
1616
for (td in _checker.ast.decls) {
17-
switch (td.decl){
17+
switch (td.decl) {
1818
case EClass(d):
1919
checkFields(d);
2020
default:

resources/config.json

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,27 @@
8585
"privateUnderscorePrefix": false
8686
}
8787
},
88+
{
89+
"type": "NestedForDepth",
90+
"props": {
91+
"severity": "ERROR",
92+
"max": 1
93+
}
94+
},
95+
{
96+
"type": "NestedIfDepth",
97+
"props": {
98+
"severity": "ERROR",
99+
"max": 1
100+
}
101+
},
102+
{
103+
"type": "NestedTryDepth",
104+
"props": {
105+
"severity": "ERROR",
106+
"max": 1
107+
}
108+
},
88109
{
89110
"type": "Override",
90111
"props": {
@@ -95,7 +116,7 @@
95116
"type": "ParameterNumber",
96117
"props": {
97118
"severity": "INFO",
98-
"max": 10,
119+
"max": 7,
99120
"ignoreOverriddenMethods": false
100121
}
101122
},

run.n

4.76 KB
Binary file not shown.

test/NestedForDepthCheckTest.hx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package ;
2+
3+
import checkstyle.checks.NestedForDepthCheck;
4+
5+
class NestedForDepthCheckTest extends CheckTestCase {
6+
7+
public function testDefault() {
8+
var msg = checkMessage(NestedForDepthTests.TEST1, new NestedForDepthCheck());
9+
assertEquals('', msg);
10+
}
11+
12+
public function testDefaultTooMany() {
13+
var msg = checkMessage(NestedForDepthTests.TEST2, new NestedForDepthCheck());
14+
assertEquals('Nested for depth is 2 (max allowed is 1)', msg);
15+
}
16+
17+
public function testMaxParameter() {
18+
var check = new NestedForDepthCheck();
19+
check.max = 2;
20+
21+
var msg = checkMessage(NestedForDepthTests.TEST1, check);
22+
assertEquals('', msg);
23+
24+
msg = checkMessage(NestedForDepthTests.TEST2, check);
25+
assertEquals('', msg);
26+
27+
check.max = 0;
28+
29+
msg = checkMessage(NestedForDepthTests.TEST1, check);
30+
assertEquals('', msg);
31+
32+
msg = checkMessage(NestedForDepthTests.TEST2, check);
33+
assertEquals('Nested for depth is 1 (max allowed is 0)', msg);
34+
}
35+
}
36+
37+
class NestedForDepthTests {
38+
public static inline var TEST1:String = "
39+
class Test {
40+
public function test(params:Array<Int>):Void {
41+
for (param in params) trace(param); // level 0
42+
for (i in 0...params.length) { // level 0
43+
trace ('$i ${params[i]}');
44+
}
45+
}
46+
}";
47+
48+
public static inline var TEST2:String =
49+
"class Test {
50+
public function test1(param:Array<Int>) {
51+
for (outerParam in params) { // level 0
52+
for (middleParam in params) { // level 1
53+
for (innerParam in params) { // level 2
54+
if (outerParam == innerParam) {
55+
trace (param);
56+
}
57+
}
58+
}
59+
}
60+
}
61+
}";
62+
}

0 commit comments

Comments
 (0)