prysm-pulse/tools/analyzers/gocognit
terencechain d17996f8b0
Update to V4 🚀 (#12134)
* Update V3 from V4

* Fix build v3 -> v4

* Update ssz

* Update beacon_chain.pb.go

* Fix formatter import

* Update update-mockgen.sh comment to v4

* Fix conflicts. Pass build and tests

* Fix test
2023-03-17 18:52:56 +00:00
..
analyzer.go Update go to 1.19.3 (#11630) 2022-11-18 19:12:19 +00:00
BUILD.bazel Update to V4 🚀 (#12134) 2023-03-17 18:52:56 +00:00
CognitiveComplexity.pdf Static analysis: gocognit (#10527) 2022-04-15 06:29:07 +00:00
README.md Static analysis: gocognit (#10527) 2022-04-15 06:29:07 +00:00

Copied from 5bf6714651/README.md License: MIT

GoDoc

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
    }

    return total
} // 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
    }

    return total
} // 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 install github.com/uudashr/gocognit/cmd/gocognit@latest

or

$ 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>