Skip to content

Commit 8b1a11f

Browse files
authored
Merge pull request #38 from uudashr/fix-nesting-else-elseif
Fix nesting inside else/else if
2 parents 8540f62 + d755295 commit 8b1a11f

File tree

5 files changed

+137
-17
lines changed

5 files changed

+137
-17
lines changed

gocognit.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,9 @@ func (v *complexityVisitor) visitIfStmt(n *ast.IfStmt) ast.Visitor {
179179

180180
ast.Walk(v, n.Cond)
181181

182-
pure := !v.markedAsElseNode(n) // pure `if` statement, not an `else if`
183-
if pure {
184-
v.incNesting()
185-
ast.Walk(v, n.Body)
186-
v.decNesting()
187-
} else {
188-
ast.Walk(v, n.Body)
189-
}
182+
v.incNesting()
183+
ast.Walk(v, n.Body)
184+
v.decNesting()
190185

191186
if _, ok := n.Else.(*ast.BlockStmt); ok {
192187
v.incComplexity()

gocognit_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ func TestAnalyzerOver3(t *testing.T) {
1818
gocognit.Analyzer.Flags.Set("over", "3")
1919
analysistest.Run(t, testdata, gocognit.Analyzer, "b")
2020
}
21+
22+
func TestAnalyzerComplex(t *testing.T) {
23+
testdata := analysistest.TestData()
24+
gocognit.Analyzer.Flags.Set("over", "0")
25+
analysistest.Run(t, testdata, gocognit.Analyzer, "d")
26+
}

testdata/src/a/a.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,47 @@ func IfElseNested(n int) string { // want "cognitive complexity 3 of func IfElse
2323
if n == 100 { // +1
2424
return "a hundred"
2525
} else { // + 1
26-
if n == 200 { // + 1
26+
if n == 200 { // +1
2727
return "two hundred"
2828
}
2929
}
3030

3131
return "others"
3232
} // total complexity = 3
3333

34-
func IfElseIfNested(n int) string { // want "cognitive complexity 3 of func IfElseIfNested is high \\(> 0\\)"
34+
func IfElseIfNested(n int) string { // want "cognitive complexity 4 of func IfElseIfNested is high \\(> 0\\)"
3535
if n == 100 { // +1
3636
return "a hundred"
37-
} else if n < 300 { // + 1
38-
if n == 200 { // + 1
37+
} else if n < 300 { // +1
38+
if n == 200 { // +2 (nesting=1)
3939
return "two hundred"
4040
}
4141
}
4242

4343
return "others"
44-
} // total complexity = 3
44+
} // total complexity = 4
45+
46+
func NestingIfElseIfNested(n int) string { // want "cognitive complexity 7 of func NestingIfElseIfNested is high \\(> 0\\)"
47+
if n > 0 { // +1
48+
if n == 100 { // +2 (nesting=1)
49+
return "a hundred"
50+
} else if n < 300 { // +1
51+
if n == 200 { // +3 (nesting=2)
52+
return "two hundred"
53+
}
54+
}
55+
}
56+
57+
return "others"
58+
} // total complexity = 7
59+
60+
func SimpleLogicalSeq0(a, b bool) string { // want "cognitive complexity 2 of func SimpleLogicalSeq0 is high \\(> 0\\)"
61+
if a && b { // +1 "if", +1 "&&"
62+
return "ok"
63+
}
64+
65+
return "not ok"
66+
} // total complexity = 2
4567

4668
func SimpleLogicalSeq1(a, b, c, d bool) string { // want "cognitive complexity 2 of func SimpleLogicalSeq1 is high \\(> 0\\)"
4769
if a && b && c && d { // +1 for `if`, +1 for `&&` sequence
@@ -247,3 +269,18 @@ func IgnoreMe(name string) bool {
247269

248270
return false
249271
} // total complexity = 1
272+
273+
func SwitchInNest(w io.Writer, i interface{}) error { // want "cognitive complexity 3 of func SwitchInNest is high \\(> 0\\)"
274+
if i != nil { // +1
275+
switch v := i.(type) { // +2 (nesting = 1)
276+
case int:
277+
fmt.Fprint(w, "int ", v)
278+
case string:
279+
fmt.Fprint(w, "string", v)
280+
default:
281+
return errors.New("unrecognized type")
282+
}
283+
}
284+
285+
return errors.New("nil interface")
286+
} // total complexity = 3

testdata/src/b/b.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,39 @@ func IfElseNested(n int) string {
3131
return "others"
3232
} // total complexity = 3
3333

34-
func IfElseIfNested(n int) string {
34+
func IfElseIfNested(n int) string { // want "cognitive complexity 4 of func IfElseIfNested is high \\(> 3\\)"
3535
if n == 100 { // +1
3636
return "a hundred"
37-
} else if n < 300 { // + 1
38-
if n == 200 { // + 1
37+
} else if n < 300 { // +1
38+
if n == 200 { // +2 (nesting=1)
3939
return "two hundred"
4040
}
4141
}
4242

4343
return "others"
44-
} // total complexity = 3
44+
} // total complexity = 4
45+
46+
func NestingIfElseIfNested(n int) string { // want "cognitive complexity 7 of func NestingIfElseIfNested is high \\(> 3\\)"
47+
if n > 0 { // +1
48+
if n == 100 { // +2 (nesting = 1)
49+
return "a hundred"
50+
} else if n < 300 { // +1
51+
if n == 200 { // +3 (nesting = 2)
52+
return "two hundred"
53+
}
54+
}
55+
}
56+
57+
return "others"
58+
} // total complexity = 7
59+
60+
func SimpleLogicalSeq0(a, b bool) string {
61+
if a && b { // +1 for `if`, +1 for `&&` sequence
62+
return "ok"
63+
}
64+
65+
return "not ok"
66+
} // total complexity = 2
4567

4668
func SimpleLogicalSeq1(a, b, c, d bool) string {
4769
if a && b && c && d { // +1 for `if`, +1 for `&&` sequence

testdata/src/d/d.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package testdata
2+
3+
import (
4+
"strings"
5+
)
6+
7+
// Adopt from org.sonar.api.utils.WildcardPattern.java in SonarQube
8+
9+
func ToRegexp(antPattern string, directorySeparator string) string { // want "cognitive complexity 20 of func ToRegexp is high \\(> 0\\)"
10+
escapedDirectorySeparator := "\\" + directorySeparator
11+
12+
var sb strings.Builder
13+
sb.WriteString("^")
14+
15+
i := 0
16+
if strings.HasPrefix(antPattern, "/") || // +1 "if", +1 "||"
17+
strings.HasPrefix(antPattern, "\\") {
18+
i = 1
19+
}
20+
21+
for i < len(antPattern) { // +1
22+
ch := antPattern[i]
23+
24+
if strings.ContainsRune(SPECIAL_CHARS, rune(ch)) { // +2 (nesting=1)
25+
sb.WriteString("\\")
26+
sb.WriteByte(ch)
27+
} else if ch == '*' { // +1
28+
if i+1 < len(antPattern) && antPattern[i+1] == '*' { // +3 "if" (nesting=2), +1 "&&"
29+
if i+2 < len(antPattern) && isSlash(antPattern[i+2]) { // +4 "if" (nesting=3), +1 "&&"
30+
sb.WriteString("(?:.*")
31+
sb.WriteString(escapedDirectorySeparator)
32+
sb.WriteString("|)")
33+
i += 2
34+
} else { // +1
35+
sb.WriteString(".*")
36+
i += 1
37+
}
38+
} else { // +1
39+
sb.WriteString("[^" + escapedDirectorySeparator + "]*?")
40+
}
41+
} else if ch == '?' { // +1
42+
sb.WriteString("[^" + escapedDirectorySeparator + "]")
43+
} else if isSlash(ch) { // +1
44+
sb.WriteString(escapedDirectorySeparator)
45+
} else { // +1
46+
sb.WriteByte(ch)
47+
}
48+
49+
i++
50+
}
51+
52+
sb.WriteString("$")
53+
return sb.String()
54+
} // total complelxity = 20
55+
56+
func isSlash(ch byte) bool { // want "cognitive complexity 1 of func isSlash is high \\(> 0\\)"
57+
return ch == '/' || ch == '\\' // +1
58+
}
59+
60+
var SPECIAL_CHARS = "()[]^$.{}+|"

0 commit comments

Comments
 (0)