# gocognit

package module
Version: v1.0.1 Latest Latest

Go to latest
Published: Dec 18, 2019 License: MIT

### Gocognit

Gocognit calculates cognitive complexities of functions in Go source code. A measurement of how hard does the code is intuitively to understand.

#### Understanding the complexity

Given code using `if` statement,

``````func GetWords(number int) string {
if number == 1 {            // +1
return "one"
} else if number == 2 {     // +1
return "a couple"
} else if number == 3 {     // +1
return "a few"
} else {                    // +1
return "lots"
}
} // Cognitive complexity = 4
``````

Above code can be refactored using `switch` statement,

``````func GetWords(number int) string {
switch number {             // +1
case 1:
return "one"
case 2:
return "a couple"
case 3:
return "a few"
default:
return "lots"
}
} // Cognitive complexity = 1
``````

As you see above codes are the same, but the second code are easier to understand, that is why the cognitive complexity score are lower compare to the first one.

#### Comparison with cyclometic complexity

##### Example 1
###### Cyclometic complexity
``````func GetWords(number int) string {      // +1
switch number {
case 1:                         // +1
return "one"
case 2:                         // +1
return "a couple"
case 3:                         // +1
return "a few"
default:
return "lots"
}
} // Cyclomatic complexity = 4
``````
###### Cognitive complexity
``````func GetWords(number int) string {
switch number {                     // +1
case 1:
return "one"
case 2:
return "a couple"
case 3:
return "a few"
default:
return "lots"
}
} // Cognitive complexity = 1
``````

Cognitive complexity give lower score compare to cyclomatic complexity.

##### Example 2
###### Cyclomatic complexity
``````func SumOfPrimes(max int) int {         // +1
var total int

OUT:
for i := 1; i < max; i++ {          // +1
for j := 2; j < i; j++ {        // +1
if i%j == 0 {               // +1
continue OUT
}
}
total += i
}

} // Cyclomatic complexity = 4
``````
###### Cognitive complexity
``````func SumOfPrimes(max int) int {
var total int

OUT:
for i := 1; i < max; i++ {          // +1
for j := 2; j < i; j++ {        // +2 (nesting = 1)
if i%j == 0 {               // +3 (nesting = 2)
continue OUT            // +1
}
}
total += i
}

} // Cognitive complexity = 7
``````

Cognitive complexity give higher score compare to cyclomatic complexity.

#### Rules

The cognitive complexity of a function is calculated according to the following rules:

Note: these rules are specific for Go, please see the original whitepaper for more complete reference.

##### Increments

There is an increment for each of the following:

1. `if`, `else if`, `else`
2. `switch`, `select`
3. `for`
4. `goto` LABEL, `break` LABEL, `continue` LABEL
5. sequence of binary logical operators
6. each method in a recursion cycle
##### Nesting level

The following structures increment the nesting level:

1. `if`, `else if`, `else`
2. `switch`, `select`
3. `for`
4. function literal or lambda
##### Nesting increments

The following structures receive a nesting increment commensurate with their nested depth inside nesting structures:

1. `if`
2. `switch`, `select`
3. `for`

#### Installation

``````\$ go get github.com/uudashr/gocognit/cmd/gocognit
``````

#### Usage

``````\$ gocognit
Calculate cognitive complexities of Go functions.
Usage:
gocognit [flags] <Go file or directory> ...
Flags:
-over N   show functions with complexity > N only and
return exit code 1 if the set is non-empty
-top N    show the top N most complex functions only
-avg      show the average complexity over all functions,
not depending on whether -over or -top are set
The output fields for each line are:
<complexity> <package> <function> <file:row:column>
``````

Examples:

``````\$ gocognit .
\$ gocognit main.go
\$ gocognit -top 10 src/
\$ gocognit -over 25 docker
\$ gocognit -avg .
``````

The output fields for each line are:

``````<complexity> <package> <function> <file:row:column>
``````

## Documentation ¶

### Constants ¶

This section is empty.

### Variables ¶

This section is empty.

### Functions ¶

#### func Complexity ¶

`func Complexity(fn *ast.FuncDecl) int`

Complexity calculates the cognitive complexity of a function.

### Types ¶

#### type Stat ¶

```type Stat struct {
PkgName    string
FuncName   string
Complexity int
Pos        token.Position
}```

Stat is statistic of the complexity.

#### func ComplexityStats ¶

`func ComplexityStats(f *ast.File, fset *token.FileSet, stats []Stat) []Stat`

ComplexityStats builds the complexity statistics.

#### func (Stat) String ¶

`func (s Stat) String() string`

## Directories ¶

Path Synopsis
cmd
GoCognitive calculates the cognitive complexities of functions and methods in Go source code.
GoCognitive calculates the cognitive complexities of functions and methods in Go source code.