Skip to content

Commit f02a13c

Browse files
authored
Merge pull request #20 from rliebz/only-binary-operators
Fix handling of miscellaneous operators
2 parents f55f5e3 + 4f0c092 commit f02a13c

File tree

2 files changed

+55
-15
lines changed

2 files changed

+55
-15
lines changed

gocognit.go

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ func (v *complexityVisitor) visitBranchStmt(n *ast.BranchStmt) ast.Visitor {
272272
}
273273

274274
func (v *complexityVisitor) visitBinaryExpr(n *ast.BinaryExpr) ast.Visitor {
275-
if (n.Op == token.LAND || n.Op == token.LOR) && !v.isCalculated(n) {
275+
if isBinaryLogicalOp(n.Op) && !v.isCalculated(n) {
276276
ops := v.collectBinaryOps(n)
277277

278278
var lastOp token.Token
@@ -299,15 +299,10 @@ func (v *complexityVisitor) visitCallExpr(n *ast.CallExpr) ast.Visitor {
299299

300300
func (v *complexityVisitor) collectBinaryOps(exp ast.Expr) []token.Token {
301301
v.markCalculated(exp)
302-
switch exp := exp.(type) {
303-
case *ast.BinaryExpr:
302+
if exp, ok := exp.(*ast.BinaryExpr); ok {
304303
return mergeBinaryOps(v.collectBinaryOps(exp.X), exp.Op, v.collectBinaryOps(exp.Y))
305-
case *ast.ParenExpr:
306-
// interest only on what inside paranthese
307-
return v.collectBinaryOps(exp.X)
308-
default:
309-
return []token.Token{}
310304
}
305+
return nil
311306
}
312307

313308
func (v *complexityVisitor) incIfComplexity(n *ast.IfStmt) {
@@ -320,16 +315,18 @@ func (v *complexityVisitor) incIfComplexity(n *ast.IfStmt) {
320315

321316
func mergeBinaryOps(x []token.Token, op token.Token, y []token.Token) []token.Token {
322317
var out []token.Token
323-
if len(x) != 0 {
324-
out = append(out, x...)
325-
}
326-
out = append(out, op)
327-
if len(y) != 0 {
328-
out = append(out, y...)
318+
out = append(out, x...)
319+
if isBinaryLogicalOp(op) {
320+
out = append(out, op)
329321
}
322+
out = append(out, y...)
330323
return out
331324
}
332325

326+
func isBinaryLogicalOp(op token.Token) bool {
327+
return op == token.LAND || op == token.LOR
328+
}
329+
333330
const Doc = `Find complex function using cognitive complexity calculation.
334331
335332
The gocognit analysis reports functions or methods which the complexity is over

testdata/src/a/a.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ func SimpleLogicalSeq2(a, b, c, d bool) string { // want "cognitive complexity 2
5959
return "not ok"
6060
} // total complexity = 2
6161

62+
func SimpleLogicalSeq3(a, b, c interface{}) string { // want "cognitive complexity 2 of func SimpleLogicalSeq3 is high \\(> 0\\)"
63+
if a == nil || b != nil || c != nil { // +1 for `if`, +1 for `||` sequence
64+
return "ok"
65+
}
66+
67+
return "not ok"
68+
} // total complexity = 2
69+
6270
func ComplexLogicalSeq1(a, b, c, d, e, f bool) string { // want "cognitive complexity 4 of func ComplexLogicalSeq1 is high \\(> 0\\)"
6371
if a && b && c || d || e && f { // +1 for `if`, +3 for changing sequence of `&&` `||` `&&`
6472
return "ok"
@@ -68,13 +76,48 @@ func ComplexLogicalSeq1(a, b, c, d, e, f bool) string { // want "cognitive compl
6876
} // total complexity = 4
6977

7078
func ComplexLogicalSeq2(a, b, c, d, e, f bool) string { // want "cognitive complexity 3 of func ComplexLogicalSeq2 is high \\(> 0\\)"
71-
if a && !(b && c) { // +1 for `if`, +2 for having sequence of `&&` `&&` chain
79+
if a && !(b && c) { // +1 for `if`, +1 for each `&&` chain
80+
return "ok"
81+
}
82+
83+
return "not ok"
84+
} // total complexity = 3
85+
86+
func ComplexLogicalSeq3(a, b, c, d, e, f bool) string { // want "cognitive complexity 3 of func ComplexLogicalSeq3 is high \\(> 0\\)"
87+
if a && (b && c) { // +1 for `if`, +1 for each `&&` chain
7288
return "ok"
7389
}
7490

7591
return "not ok"
7692
} // total complexity = 3
7793

94+
func ComplexLogicalSeq4(a, b, c, d, e, f bool) bool { // want "cognitive complexity 3 of func ComplexLogicalSeq4 is high \\(> 0\\)"
95+
return a && b && c || d || e && f // +3 for changing sequence of `&&` `||` `&&`
96+
} // total complexity = 3
97+
98+
func ComplexLogicalSeq5(a, b, c, d, e, f bool) bool { // want "cognitive complexity 3 of func ComplexLogicalSeq5 is high \\(> 0\\)"
99+
return a && b && (c && d || e || f) // +1 for `&&` sequence, +2 for `&&` `||` sequence in parentheses
100+
} // total complexity = 3
101+
102+
func ExprFunc(a, b, c any) bool { // want "cognitive complexity 2 of func ExprFunc is high \\(> 0\\)"
103+
if a != nil || b != nil || c != nil { // +1 for `if`, +1 for `||` chain
104+
return false
105+
}
106+
107+
return true
108+
} // total complexity = 2
109+
110+
func VarFunc(a, b, c any) bool { // want "cognitive complexity 2 of func VarFunc is high \\(> 0\\)"
111+
na := a != nil
112+
nb := b != nil
113+
nc := c != nil
114+
if na || nb || nc { // +1 for `if`, +1 for `||` chain
115+
return false
116+
}
117+
118+
return true
119+
} // total complexity = 2
120+
78121
func GetWords(number int) string { // want "cognitive complexity 1 of func GetWords is high \\(> 0\\)"
79122
switch number { // +1
80123
case 1:

0 commit comments

Comments
 (0)