Skip to content

Commit

Permalink
Fix nesting inside else/else if
Browse files Browse the repository at this point in the history
  • Loading branch information
uudashr committed Dec 5, 2024
1 parent 8540f62 commit d755295
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 17 deletions.
11 changes: 3 additions & 8 deletions gocognit.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,9 @@ func (v *complexityVisitor) visitIfStmt(n *ast.IfStmt) ast.Visitor {

ast.Walk(v, n.Cond)

pure := !v.markedAsElseNode(n) // pure `if` statement, not an `else if`
if pure {
v.incNesting()
ast.Walk(v, n.Body)
v.decNesting()
} else {
ast.Walk(v, n.Body)
}
v.incNesting()
ast.Walk(v, n.Body)
v.decNesting()

if _, ok := n.Else.(*ast.BlockStmt); ok {
v.incComplexity()
Expand Down
6 changes: 6 additions & 0 deletions gocognit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ func TestAnalyzerOver3(t *testing.T) {
gocognit.Analyzer.Flags.Set("over", "3")
analysistest.Run(t, testdata, gocognit.Analyzer, "b")
}

func TestAnalyzerComplex(t *testing.T) {
testdata := analysistest.TestData()
gocognit.Analyzer.Flags.Set("over", "0")
analysistest.Run(t, testdata, gocognit.Analyzer, "d")
}
47 changes: 42 additions & 5 deletions testdata/src/a/a.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,47 @@ func IfElseNested(n int) string { // want "cognitive complexity 3 of func IfElse
if n == 100 { // +1
return "a hundred"
} else { // + 1
if n == 200 { // + 1
if n == 200 { // +1
return "two hundred"
}
}

return "others"
} // total complexity = 3

func IfElseIfNested(n int) string { // want "cognitive complexity 3 of func IfElseIfNested is high \\(> 0\\)"
func IfElseIfNested(n int) string { // want "cognitive complexity 4 of func IfElseIfNested is high \\(> 0\\)"
if n == 100 { // +1
return "a hundred"
} else if n < 300 { // + 1
if n == 200 { // + 1
} else if n < 300 { // +1
if n == 200 { // +2 (nesting=1)
return "two hundred"
}
}

return "others"
} // total complexity = 3
} // total complexity = 4

func NestingIfElseIfNested(n int) string { // want "cognitive complexity 7 of func NestingIfElseIfNested is high \\(> 0\\)"
if n > 0 { // +1
if n == 100 { // +2 (nesting=1)
return "a hundred"
} else if n < 300 { // +1
if n == 200 { // +3 (nesting=2)
return "two hundred"
}
}
}

return "others"
} // total complexity = 7

func SimpleLogicalSeq0(a, b bool) string { // want "cognitive complexity 2 of func SimpleLogicalSeq0 is high \\(> 0\\)"
if a && b { // +1 "if", +1 "&&"
return "ok"
}

return "not ok"
} // total complexity = 2

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

return false
} // total complexity = 1

func SwitchInNest(w io.Writer, i interface{}) error { // want "cognitive complexity 3 of func SwitchInNest is high \\(> 0\\)"
if i != nil { // +1
switch v := i.(type) { // +2 (nesting = 1)
case int:
fmt.Fprint(w, "int ", v)
case string:
fmt.Fprint(w, "string", v)
default:
return errors.New("unrecognized type")
}
}

return errors.New("nil interface")
} // total complexity = 3
30 changes: 26 additions & 4 deletions testdata/src/b/b.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,39 @@ func IfElseNested(n int) string {
return "others"
} // total complexity = 3

func IfElseIfNested(n int) string {
func IfElseIfNested(n int) string { // want "cognitive complexity 4 of func IfElseIfNested is high \\(> 3\\)"
if n == 100 { // +1
return "a hundred"
} else if n < 300 { // + 1
if n == 200 { // + 1
} else if n < 300 { // +1
if n == 200 { // +2 (nesting=1)
return "two hundred"
}
}

return "others"
} // total complexity = 3
} // total complexity = 4

func NestingIfElseIfNested(n int) string { // want "cognitive complexity 7 of func NestingIfElseIfNested is high \\(> 3\\)"
if n > 0 { // +1
if n == 100 { // +2 (nesting = 1)
return "a hundred"
} else if n < 300 { // +1
if n == 200 { // +3 (nesting = 2)
return "two hundred"
}
}
}

return "others"
} // total complexity = 7

func SimpleLogicalSeq0(a, b bool) string {
if a && b { // +1 for `if`, +1 for `&&` sequence
return "ok"
}

return "not ok"
} // total complexity = 2

func SimpleLogicalSeq1(a, b, c, d bool) string {
if a && b && c && d { // +1 for `if`, +1 for `&&` sequence
Expand Down
60 changes: 60 additions & 0 deletions testdata/src/d/d.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package testdata

import (
"strings"
)

// Adopt from org.sonar.api.utils.WildcardPattern.java in SonarQube

func ToRegexp(antPattern string, directorySeparator string) string { // want "cognitive complexity 20 of func ToRegexp is high \\(> 0\\)"
escapedDirectorySeparator := "\\" + directorySeparator

var sb strings.Builder
sb.WriteString("^")

i := 0
if strings.HasPrefix(antPattern, "/") || // +1 "if", +1 "||"
strings.HasPrefix(antPattern, "\\") {
i = 1
}

for i < len(antPattern) { // +1
ch := antPattern[i]

if strings.ContainsRune(SPECIAL_CHARS, rune(ch)) { // +2 (nesting=1)
sb.WriteString("\\")
sb.WriteByte(ch)
} else if ch == '*' { // +1
if i+1 < len(antPattern) && antPattern[i+1] == '*' { // +3 "if" (nesting=2), +1 "&&"
if i+2 < len(antPattern) && isSlash(antPattern[i+2]) { // +4 "if" (nesting=3), +1 "&&"
sb.WriteString("(?:.*")
sb.WriteString(escapedDirectorySeparator)
sb.WriteString("|)")
i += 2
} else { // +1
sb.WriteString(".*")
i += 1
}
} else { // +1
sb.WriteString("[^" + escapedDirectorySeparator + "]*?")
}
} else if ch == '?' { // +1
sb.WriteString("[^" + escapedDirectorySeparator + "]")
} else if isSlash(ch) { // +1
sb.WriteString(escapedDirectorySeparator)
} else { // +1
sb.WriteByte(ch)
}

i++
}

sb.WriteString("$")
return sb.String()
} // total complelxity = 20

func isSlash(ch byte) bool { // want "cognitive complexity 1 of func isSlash is high \\(> 0\\)"
return ch == '/' || ch == '\\' // +1
}

var SPECIAL_CHARS = "()[]^$.{}+|"

0 comments on commit d755295

Please sign in to comment.