aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/bkielbasa
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2021-02-22 20:37:25 +0100
committerDmitry Vyukov <dvyukov@google.com>2021-02-22 21:02:12 +0100
commitfcc6d71be2c3ce7d9305c04fc2e87af554571bac (patch)
treeb01dbb3d1e2988e28ea158d2d543d603ec0b9569 /vendor/github.com/bkielbasa
parent8f23c528ad5a943b9ffec5dcaf332fd0f614006e (diff)
go.mod: update golangci-lint to v1.37
Diffstat (limited to 'vendor/github.com/bkielbasa')
-rw-r--r--vendor/github.com/bkielbasa/cyclop/LICENSE21
-rw-r--r--vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go104
2 files changed, 125 insertions, 0 deletions
diff --git a/vendor/github.com/bkielbasa/cyclop/LICENSE b/vendor/github.com/bkielbasa/cyclop/LICENSE
new file mode 100644
index 000000000..b4a776a40
--- /dev/null
+++ b/vendor/github.com/bkielbasa/cyclop/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Bartłomiej Klimczak
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go b/vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go
new file mode 100644
index 000000000..9b2801352
--- /dev/null
+++ b/vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go
@@ -0,0 +1,104 @@
+package analyzer
+
+import (
+ "flag"
+ "go/ast"
+ "go/token"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+var (
+ flagSet flag.FlagSet
+)
+
+var maxComplexity int
+var packageAverage float64
+var skipTests bool
+
+func NewAnalyzer() *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: "cyclop",
+ Doc: "calculates cyclomatic complexity",
+ Run: run,
+ Flags: flagSet,
+ }
+}
+
+func init() {
+ flagSet.IntVar(&maxComplexity, "maxComplexity", 10, "max complexity the function can have")
+ flagSet.Float64Var(&packageAverage, "packageAverage", 0, "max avarage complexity in package")
+ flagSet.BoolVar(&skipTests, "skipTests", false, "should the linter execute on test files as well")
+}
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ var sum, count float64
+ var pkgName string
+ var pkgPos token.Pos
+
+ for _, f := range pass.Files {
+ ast.Inspect(f, func(node ast.Node) bool {
+ f, ok := node.(*ast.FuncDecl)
+ if !ok {
+ if node == nil {
+ return true
+ }
+ if file, ok := node.(*ast.File); ok {
+ pkgName = file.Name.Name
+ pkgPos = node.Pos()
+ }
+ // we check function by function
+ return true
+ }
+
+ if skipTests && testFunc(f) {
+ return true
+ }
+
+ count++
+ comp := complexity(f)
+ sum += float64(comp)
+ if comp > maxComplexity {
+ pass.Reportf(node.Pos(), "calculated cyclomatic complexity for function %s is %d, max is %d", f.Name.Name, comp, maxComplexity)
+ }
+
+ return true
+ })
+ }
+
+ if packageAverage > 0 {
+ avg := sum / count
+ if avg > packageAverage {
+ pass.Reportf(pkgPos, "the avarage complexity for the package %s is %f, max is %f", pkgName, avg, packageAverage)
+ }
+ }
+
+ return nil, nil
+}
+
+func testFunc(f *ast.FuncDecl) bool {
+ return strings.HasPrefix(f.Name.Name, "Test")
+}
+
+func complexity(fn *ast.FuncDecl) int {
+ v := complexityVisitor{}
+ ast.Walk(&v, fn)
+ return v.Complexity
+}
+
+type complexityVisitor struct {
+ Complexity int
+}
+
+func (v *complexityVisitor) Visit(n ast.Node) ast.Visitor {
+ switch n := n.(type) {
+ case *ast.FuncDecl, *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt, *ast.CaseClause, *ast.CommClause:
+ v.Complexity++
+ case *ast.BinaryExpr:
+ if n.Op == token.LAND || n.Op == token.LOR {
+ v.Complexity++
+ }
+ }
+ return v
+}