aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/4d63.com
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/4d63.com
parent8f23c528ad5a943b9ffec5dcaf332fd0f614006e (diff)
go.mod: update golangci-lint to v1.37
Diffstat (limited to 'vendor/4d63.com')
-rw-r--r--vendor/4d63.com/gochecknoglobals/LICENSE21
-rw-r--r--vendor/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go154
2 files changed, 175 insertions, 0 deletions
diff --git a/vendor/4d63.com/gochecknoglobals/LICENSE b/vendor/4d63.com/gochecknoglobals/LICENSE
new file mode 100644
index 000000000..c401e6608
--- /dev/null
+++ b/vendor/4d63.com/gochecknoglobals/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Leigh McCulloch
+
+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/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go b/vendor/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go
new file mode 100644
index 000000000..5b6325dd9
--- /dev/null
+++ b/vendor/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go
@@ -0,0 +1,154 @@
+package checknoglobals
+
+import (
+ "flag"
+ "fmt"
+ "go/ast"
+ "go/token"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+// allowedExpression is a struct representing packages and methods that will
+// be an allowed combination to use as a global variable, f.ex. Name `regexp`
+// and SelName `MustCompile`.
+type allowedExpression struct {
+ Name string
+ SelName string
+}
+
+const Doc = `check that no global variables exist
+
+This analyzer checks for global variables and errors on any found.
+
+A global variable is a variable declared in package scope and that can be read
+and written to by any function within the package. Global variables can cause
+side effects which are difficult to keep track of. A code in one function may
+change the variables state while another unrelated chunk of code may be
+effected by it.`
+
+// Analyzer provides an Analyzer that checks that there are no global
+// variables, except for errors and variables containing regular
+// expressions.
+func Analyzer() *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: "gochecknoglobals",
+ Doc: Doc,
+ Run: checkNoGlobals,
+ Flags: flags(),
+ RunDespiteErrors: true,
+ }
+}
+
+func flags() flag.FlagSet {
+ flags := flag.NewFlagSet("", flag.ExitOnError)
+ flags.Bool("t", false, "Include tests")
+
+ return *flags
+}
+
+func isAllowed(v ast.Node) bool {
+ switch i := v.(type) {
+ case *ast.Ident:
+ return i.Name == "_" || i.Name == "version" || looksLikeError(i)
+ case *ast.CallExpr:
+ if expr, ok := i.Fun.(*ast.SelectorExpr); ok {
+ return isAllowedSelectorExpression(expr)
+ }
+ case *ast.CompositeLit:
+ if expr, ok := i.Type.(*ast.SelectorExpr); ok {
+ return isAllowedSelectorExpression(expr)
+ }
+ }
+
+ return false
+}
+
+func isAllowedSelectorExpression(v *ast.SelectorExpr) bool {
+ x, ok := v.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+
+ allowList := []allowedExpression{
+ {Name: "regexp", SelName: "MustCompile"},
+ }
+
+ for _, i := range allowList {
+ if x.Name == i.Name && v.Sel.Name == i.SelName {
+ return true
+ }
+ }
+
+ return false
+}
+
+// looksLikeError returns true if the AST identifier starts
+// with 'err' or 'Err', or false otherwise.
+//
+// TODO: https://github.com/leighmcculloch/gochecknoglobals/issues/5
+func looksLikeError(i *ast.Ident) bool {
+ prefix := "err"
+ if i.IsExported() {
+ prefix = "Err"
+ }
+ return strings.HasPrefix(i.Name, prefix)
+}
+
+func checkNoGlobals(pass *analysis.Pass) (interface{}, error) {
+ includeTests := pass.Analyzer.Flags.Lookup("t").Value.(flag.Getter).Get().(bool)
+
+ for _, file := range pass.Files {
+ filename := pass.Fset.Position(file.Pos()).Filename
+ if !strings.HasSuffix(filename, ".go") {
+ continue
+ }
+ if !includeTests && strings.HasSuffix(filename, "_test.go") {
+ continue
+ }
+
+ for _, decl := range file.Decls {
+ genDecl, ok := decl.(*ast.GenDecl)
+ if !ok {
+ continue
+ }
+ if genDecl.Tok != token.VAR {
+ continue
+ }
+ for _, spec := range genDecl.Specs {
+ valueSpec := spec.(*ast.ValueSpec)
+ onlyAllowedValues := false
+
+ for _, vn := range valueSpec.Values {
+ if isAllowed(vn) {
+ onlyAllowedValues = true
+ continue
+ }
+
+ onlyAllowedValues = false
+ break
+ }
+
+ if onlyAllowedValues {
+ continue
+ }
+
+ for _, vn := range valueSpec.Names {
+ if isAllowed(vn) {
+ continue
+ }
+
+ message := fmt.Sprintf("%s is a global variable", vn.Name)
+ pass.Report(analysis.Diagnostic{
+ Pos: vn.Pos(),
+ Category: "global",
+ Message: message,
+ })
+ }
+ }
+ }
+ }
+
+ return nil, nil
+}