aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/kyoh86/exportloopref
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2025-01-22 16:07:17 +0100
committerTaras Madan <tarasmadan@google.com>2025-01-23 10:42:36 +0000
commit7b4377ad9d8a7205416df8d6217ef2b010f89481 (patch)
treee6fec4fd12ff807a16d847923f501075bf71d16c /vendor/github.com/kyoh86/exportloopref
parent475a4c203afb8b7d3af51c4fd32bb170ff32a45e (diff)
vendor: delete
Diffstat (limited to 'vendor/github.com/kyoh86/exportloopref')
-rw-r--r--vendor/github.com/kyoh86/exportloopref/.golangci.yml4
-rw-r--r--vendor/github.com/kyoh86/exportloopref/.goreleaser.yml51
-rw-r--r--vendor/github.com/kyoh86/exportloopref/LICENSE21
-rw-r--r--vendor/github.com/kyoh86/exportloopref/Makefile16
-rw-r--r--vendor/github.com/kyoh86/exportloopref/README.md223
-rw-r--r--vendor/github.com/kyoh86/exportloopref/exportloopref.go334
6 files changed, 0 insertions, 649 deletions
diff --git a/vendor/github.com/kyoh86/exportloopref/.golangci.yml b/vendor/github.com/kyoh86/exportloopref/.golangci.yml
deleted file mode 100644
index e876057f3..000000000
--- a/vendor/github.com/kyoh86/exportloopref/.golangci.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-linters:
- enable:
- - unparam
- - exportloopref
diff --git a/vendor/github.com/kyoh86/exportloopref/.goreleaser.yml b/vendor/github.com/kyoh86/exportloopref/.goreleaser.yml
deleted file mode 100644
index 95d44aaac..000000000
--- a/vendor/github.com/kyoh86/exportloopref/.goreleaser.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
-
-project_name: exportloopref
-builds:
- - id: default
- goos:
- - linux
- - darwin
- - windows
- goarch:
- - amd64
- - arm64
- - "386"
- main: ./cmd/exportloopref
- binary: exportloopref
-brews:
- - install: |
- bin.install "exportloopref"
- tap:
- owner: kyoh86
- name: homebrew-tap
- folder: Formula
- homepage: https://github.com/kyoh86/exportloopref
- description: An analyzer that finds exporting pointers for loop variables.
- license: MIT
-nfpms:
- - builds:
- - default
- maintainer: kyoh86 <me@kyoh86.dev>
- homepage: https://github.com/kyoh86/exportloopref
- description: An analyzer that finds exporting pointers for loop variables.
- license: MIT
- formats:
- - apk
- - deb
- - rpm
-archives:
- - id: gzip
- format: tar.gz
- format_overrides:
- - goos: windows
- format: zip
- files:
- - licence*
- - LICENCE*
- - license*
- - LICENSE*
- - readme*
- - README*
- - changelog*
- - CHANGELOG*
diff --git a/vendor/github.com/kyoh86/exportloopref/LICENSE b/vendor/github.com/kyoh86/exportloopref/LICENSE
deleted file mode 100644
index 7ac9dba4a..000000000
--- a/vendor/github.com/kyoh86/exportloopref/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020 kyoh86
-
-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/kyoh86/exportloopref/Makefile b/vendor/github.com/kyoh86/exportloopref/Makefile
deleted file mode 100644
index 4d3ef22f7..000000000
--- a/vendor/github.com/kyoh86/exportloopref/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-.PHONY: gen lint test install man
-
-VERSION := `git vertag get`
-COMMIT := `git rev-parse HEAD`
-
-gen:
- go generate ./...
-
-lint: gen
- golangci-lint run
-
-test: lint
- go test -v --race ./...
-
-install: test
- go install -a -ldflags "-X=main.version=$(VERSION) -X=main.commit=$(COMMIT)" ./...
diff --git a/vendor/github.com/kyoh86/exportloopref/README.md b/vendor/github.com/kyoh86/exportloopref/README.md
deleted file mode 100644
index 0f581ffce..000000000
--- a/vendor/github.com/kyoh86/exportloopref/README.md
+++ /dev/null
@@ -1,223 +0,0 @@
-# exportloopref
-
-An analyzer that finds exporting pointers for loop variables.
-![](https://repository-images.githubusercontent.com/256768552/a1c5bb80-dd73-11eb-9453-e520f517e730)
-Pin them all!
-
-[![PkgGoDev](https://pkg.go.dev/badge/kyoh86/exportloopref)](https://pkg.go.dev/kyoh86/exportloopref)
-[![Go Report Card](https://goreportcard.com/badge/github.com/kyoh86/exportloopref)](https://goreportcard.com/report/github.com/kyoh86/exportloopref)
-[![Coverage Status](https://img.shields.io/codecov/c/github/kyoh86/exportloopref.svg)](https://codecov.io/gh/kyoh86/exportloopref)
-[![Release](https://github.com/kyoh86/exportloopref/workflows/Release/badge.svg)](https://github.com/kyoh86/exportloopref/releases)
-
-## What's this?
-
-Sample problem code from: https://github.com/kyoh86/exportloopref/blob/main/testdata/src/simple/simple.go
-
-```go
-package main
-
-func main() {
- var intArray [4]*int
- var intSlice []*int
- var intRef *int
- var intStr struct{ x *int }
-
- println("loop expecting 10, 11, 12, 13")
- for i, p := range []int{10, 11, 12, 13} {
- printp(&p) // not a diagnostic
- intSlice = append(intSlice, &p) // want "exporting a pointer for the loop variable p"
- intArray[i] = &p // want "exporting a pointer for the loop variable p"
- if i%2 == 0 {
- intRef = &p // want "exporting a pointer for the loop variable p"
- intStr.x = &p // want "exporting a pointer for the loop variable p"
- }
- var vStr struct{ x *int }
- var vArray [4]*int
- var v *int
- if i%2 == 0 {
- v = &p // not a diagnostic (x is local variable)
- vArray[1] = &p // not a diagnostic (x is local variable)
- vStr.x = &p
- }
- _ = v
- }
-
- println(`slice expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
- for _, p := range intSlice {
- printp(p)
- }
- println(`array expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
- for _, p := range intArray {
- printp(p)
- }
- println(`captured value expecting "12" but "13"`)
- printp(intRef)
-}
-
-func printp(p *int) {
- println(*p)
-}
-```
-
-In Go, the `p` variable in the above loops is actually a single variable.
-So in many case (like the above), using it makes for us annoying bugs.
-
-You can find them with `exportloopref`, and fix it.
-
-```go
-package main
-
-func main() {
- var intArray [4]*int
- var intSlice []*int
- var intRef *int
- var intStr struct{ x *int }
-
- println("loop expecting 10, 11, 12, 13")
- for i, p := range []int{10, 11, 12, 13} {
- p := p // FIX variable into the local variable
- printp(&p)
- intSlice = append(intSlice, &p)
- intArray[i] = &p
- if i%2 == 0 {
- intRef = &p
- intStr.x = &p
- }
- var vStr struct{ x *int }
- var vArray [4]*int
- var v *int
- if i%2 == 0 {
- v = &p
- vArray[1] = &p
- vStr.x = &p
- }
- _ = v
- }
-
- println(`slice expecting "10, 11, 12, 13"`)
- for _, p := range intSlice {
- printp(p)
- }
- println(`array expecting "10, 11, 12, 13"`)
- for _, p := range intArray {
- printp(p)
- }
- println(`captured value expecting "12"`)
- printp(intRef)
-}
-
-func printp(p *int) {
- println(*p)
-}
-```
-
-ref: https://github.com/kyoh86/exportloopref/blob/main/testdata/src/fixed/fixed.go
-
-## Sensing policy
-
-I want to make exportloopref as accurately as possible.
-So some cases of lints will be false-negative.
-
-e.g.
-
-```go
-var s Foo
-for _, p := range []int{10, 11, 12, 13} {
- s.Bar(&p) // If s stores the pointer, it will be bug.
-}
-```
-
-If you want to report all of lints (with some false-positives),
-you should use [looppointer](https://github.com/kyoh86/looppointer).
-
-### Known false negatives
-
-Case 1: pass the pointer to function to export.
-
-Case 2: pass the pointer to local variable, and export it.
-
-```go
-package main
-
-type List []*int
-
-func (l *List) AppendP(p *int) {
- *l = append(*l, p)
-}
-
-func main() {
- var slice []*int
- list := List{}
-
- println("loop expect exporting 10, 11, 12, 13")
- for _, v := range []int{10, 11, 12, 13} {
- list.AppendP(&v) // Case 1: wanted "exporting a pointer for the loop variable v", but cannot be found
-
- p := &v // p is the local variable
- slice = append(slice, p) // Case 2: wanted "exporting a pointer for the loop variable v", but cannot be found
- }
-
- println(`slice expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
- for _, p := range slice {
- printp(p)
- }
- println(`array expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
- for _, p := range ([]*int)(list) {
- printp(p)
- }
-}
-
-func printp(p *int) {
- println(*p)
-}
-```
-
-## Install
-
-go:
-
-```console
-$ go get github.com/kyoh86/exportloopref/cmd/exportloopref
-```
-
-[homebrew](https://brew.sh/):
-
-```console
-$ brew install kyoh86/tap/exportloopref
-```
-
-[gordon](https://github.com/kyoh86/gordon):
-
-```console
-$ gordon install kyoh86/exportloopref
-```
-
-## Usage
-
-```
-exportloopref [-flag] [package]
-```
-
-### Flags
-
-| Flag | Description |
-| --- | --- |
-| -V | print version and exit |
-| -all | no effect (deprecated) |
-| -c int | display offending line with this many lines of context (default -1) |
-| -cpuprofile string | write CPU profile to this file |
-| -debug string | debug flags, any subset of "fpstv" |
-| -fix | apply all suggested fixes |
-| -flags | print analyzer flags in JSON |
-| -json | emit JSON output |
-| -memprofile string | write memory profile to this file |
-| -source | no effect (deprecated) |
-| -tags string | no effect (deprecated) |
-| -trace string | write trace log to this file |
-| -v | no effect (deprecated) |
-
-# LICENSE
-
-[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg)](http://www.opensource.org/licenses/MIT)
-
-This is distributed under the [MIT License](http://www.opensource.org/licenses/MIT).
diff --git a/vendor/github.com/kyoh86/exportloopref/exportloopref.go b/vendor/github.com/kyoh86/exportloopref/exportloopref.go
deleted file mode 100644
index d071d5c35..000000000
--- a/vendor/github.com/kyoh86/exportloopref/exportloopref.go
+++ /dev/null
@@ -1,334 +0,0 @@
-package exportloopref
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- "go/types"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/ast/inspector"
-)
-
-var Analyzer = &analysis.Analyzer{
- Name: "exportloopref",
- Doc: "checks for pointers to enclosing loop variables",
- Run: run,
- RunDespiteErrors: true,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
-}
-
-func run(pass *analysis.Pass) (interface{}, error) {
- inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
-
- search := &Searcher{
- LoopVars: map[token.Pos]struct{}{},
- LocalVars: map[token.Pos]map[token.Pos]struct{}{},
- Pass: pass,
- }
-
- nodeFilter := []ast.Node{
- (*ast.RangeStmt)(nil),
- (*ast.ForStmt)(nil),
- (*ast.DeclStmt)(nil),
- (*ast.AssignStmt)(nil),
- (*ast.UnaryExpr)(nil),
- }
-
- inspect.WithStack(nodeFilter, search.CheckAndReport)
-
- return nil, nil
-}
-
-type Searcher struct {
- // LoopVars is positions that loop-variables are declared like below.
- // - for <KEY>, <VALUE> := range ...
- // - for <VALUE> := <INIT>; <CONDITION>; <INCREMENT>
- LoopVars map[token.Pos]struct{}
- // LocalVars is positions of loops and the variables declared in them.
- // Use this to determine if a point assignment is an export outside the loop.
- LocalVars map[token.Pos]map[token.Pos]struct{}
-
- Pass *analysis.Pass
-}
-
-// CheckAndReport inspects each node with stack.
-// It is implemented as the I/F of the "golang.org/x/tools/go/analysis/passes/inspect".Analysis.WithStack.
-func (s *Searcher) CheckAndReport(n ast.Node, push bool, stack []ast.Node) bool {
- id, insert, digg := s.Check(n, stack)
- if id == nil {
- // no prob.
- return digg
- }
-
- // suggests fix
- var suggest []analysis.SuggestedFix
- if insert != token.NoPos {
- suggest = []analysis.SuggestedFix{{
- Message: fmt.Sprintf("loop variable %s should be pinned", id.Name),
- TextEdits: []analysis.TextEdit{{
- Pos: insert,
- End: insert,
- NewText: []byte(fmt.Sprintf("%[1]s := %[1]s\n", id.Name)),
- }},
- }}
- }
-
- // report a diagnostic
- d := analysis.Diagnostic{Pos: id.Pos(),
- End: id.End(),
- Message: fmt.Sprintf("exporting a pointer for the loop variable %s", id.Name),
- Category: "exportloopref",
- SuggestedFixes: suggest,
- }
- s.Pass.Report(d)
- return digg
-}
-
-// Check each node and stack, whether it exports loop variables or not.
-// Finding export, report the *ast.Ident of exported loop variable,
-// and token.Pos to insert assignment to fix the diagnostic.
-func (s *Searcher) Check(n ast.Node, stack []ast.Node) (loopVar *ast.Ident, insertPos token.Pos, digg bool) {
- switch typed := n.(type) {
- case *ast.RangeStmt:
- s.parseRangeStmt(typed)
- case *ast.ForStmt:
- s.parseForStmt(typed)
- case *ast.DeclStmt:
- s.parseDeclStmt(typed, stack)
- case *ast.AssignStmt:
- s.parseAssignStmt(typed, stack)
-
- case *ast.UnaryExpr:
- return s.checkUnaryExpr(typed, stack)
- }
- return nil, token.NoPos, true
-}
-
-// parseRangeStmt will check range statement (i.e. `for <KEY>, <VALUE> := range ...`),
-// and collect positions of <KEY> and <VALUE>.
-func (s *Searcher) parseRangeStmt(n *ast.RangeStmt) {
- s.storeLoopVars(n.Key)
- s.storeLoopVars(n.Value)
-}
-
-// parseForStmt will check for statement (i.e. `for <VALUE> := <INIT>; <CONDITION>; <INCREMENT>`),
-// and collect positions of <VALUE>.
-func (s *Searcher) parseForStmt(n *ast.ForStmt) {
- switch post := n.Post.(type) {
- case *ast.AssignStmt:
- // e.g. for p = head; p != nil; p = p.next
- for _, lhs := range post.Lhs {
- s.storeLoopVars(lhs)
- }
- case *ast.IncDecStmt:
- // e.g. for i := 0; i < n; i++
- s.storeLoopVars(post.X)
- }
-}
-
-func (s *Searcher) storeLoopVars(expr ast.Expr) {
- if id, ok := expr.(*ast.Ident); ok {
- s.LoopVars[id.Pos()] = struct{}{}
- }
-}
-
-// parseDeclStmt will parse declaring statement (i.e. `var`, `type`, `const`),
-// and store the position if it is "var" declaration and is in any loop.
-func (s *Searcher) parseDeclStmt(n *ast.DeclStmt, stack []ast.Node) {
- genDecl, ok := n.Decl.(*ast.GenDecl)
- if !ok {
- // (dead branch)
- // if the Decl is not GenDecl (i.e. `var`, `type` or `const` statement), it is ignored
- return
- }
- if genDecl.Tok != token.VAR {
- // if the Decl is not `var` (may be `type` or `const`), it is ignored
- return
- }
-
- loop, _ := s.innermostLoop(stack)
- if loop == nil {
- return
- }
-
- // Register declared variables
- for _, spec := range genDecl.Specs {
- for _, name := range spec.(*ast.ValueSpec).Names {
- s.storeLocalVar(loop, name)
- }
- }
-}
-
-// parseDeclStmt will parse assignment statement (i.e. `<VAR> = <VALUE>`),
-// and store the position if it is .
-func (s *Searcher) parseAssignStmt(n *ast.AssignStmt, stack []ast.Node) {
- if n.Tok != token.DEFINE {
- // if the statement is simple assignment (without definement), it is ignored
- return
- }
-
- loop, _ := s.innermostLoop(stack)
- if loop == nil {
- return
- }
-
- // Find statements declaring local variable
- for _, h := range n.Lhs {
- s.storeLocalVar(loop, h)
- }
-}
-
-func (s *Searcher) storeLocalVar(loop ast.Node, expr ast.Expr) {
- loopPos := loop.Pos()
- id, ok := expr.(*ast.Ident)
- if !ok {
- return
- }
- vars, ok := s.LocalVars[loopPos]
- if !ok {
- vars = map[token.Pos]struct{}{}
- }
- vars[id.Obj.Pos()] = struct{}{}
- s.LocalVars[loopPos] = vars
-}
-
-func insertionPosition(block *ast.BlockStmt) token.Pos {
- if len(block.List) > 0 {
- return block.List[0].Pos()
- }
- return token.NoPos
-}
-
-func (s *Searcher) innermostLoop(stack []ast.Node) (ast.Node, token.Pos) {
- for i := len(stack) - 1; i >= 0; i-- {
- switch typed := stack[i].(type) {
- case *ast.RangeStmt:
- return typed, insertionPosition(typed.Body)
- case *ast.ForStmt:
- return typed, insertionPosition(typed.Body)
- }
- }
- return nil, token.NoPos
-}
-
-// checkUnaryExpr check unary expression (i.e. <OPERATOR><VAR> like `-x`, `*p` or `&v`) and stack.
-// THIS IS THE ESSENTIAL PART OF THIS PARSER.
-func (s *Searcher) checkUnaryExpr(n *ast.UnaryExpr, stack []ast.Node) (*ast.Ident, token.Pos, bool) {
- if n.Op != token.AND {
- return nil, token.NoPos, true
- }
-
- loop, insert := s.innermostLoop(stack)
- if loop == nil {
- return nil, token.NoPos, true
- }
-
- // Get identity of the referred item
- id := s.getIdentity(n.X)
- if id == nil {
- return nil, token.NoPos, true
- }
-
- // If the identity is not the loop statement variable,
- // it will not be reported.
- if _, isDecl := s.LoopVars[id.Obj.Pos()]; !isDecl {
- return nil, token.NoPos, true
- }
-
- // check stack append(), []X{}, map[Type]X{}, Struct{}, &Struct{}, X.(Type), (X)
- // in the <outer> =
- var mayRHPos token.Pos
- for i := len(stack) - 2; i >= 0; i-- {
- switch typed := stack[i].(type) {
- case (*ast.UnaryExpr):
- // noop
- case (*ast.CompositeLit):
- // noop
- case (*ast.KeyValueExpr):
- // noop
- case (*ast.CallExpr):
- fun, ok := typed.Fun.(*ast.Ident)
- if !ok {
- return nil, token.NoPos, false // it's calling a function other of `append`. It cannot be checked
- }
-
- if fun.Name != "append" {
- return nil, token.NoPos, false // it's calling a function other of `append`. It cannot be checked
- }
-
- case (*ast.AssignStmt):
- if len(typed.Rhs) != len(typed.Lhs) {
- return nil, token.NoPos, false // dead logic
- }
-
- // search x where Rhs[x].Pos() == mayRHPos
- var index int
- for ri, rh := range typed.Rhs {
- if rh.Pos() == mayRHPos {
- index = ri
- break
- }
- }
-
- // check Lhs[x] is not local variable
- lh := typed.Lhs[index]
- isVar := s.isVar(loop, lh)
- if !isVar {
- return id, insert, false
- }
-
- return nil, token.NoPos, true
- default:
- // Other statement is not able to be checked.
- return nil, token.NoPos, false
- }
-
- // memory an expr that may be right-hand in the AssignStmt
- mayRHPos = stack[i].Pos()
- }
- return nil, token.NoPos, true
-}
-
-func (s *Searcher) isVar(loop ast.Node, expr ast.Expr) bool {
- vars := s.LocalVars[loop.Pos()] // map[token.Pos]struct{}
- if vars == nil {
- return false
- }
- switch typed := expr.(type) {
- case (*ast.Ident):
- if typed.Obj == nil {
- return false // global var in another file (ref: #13)
- }
- _, isVar := vars[typed.Obj.Pos()]
- return isVar
- case (*ast.IndexExpr): // like X[Y], check X
- return s.isVar(loop, typed.X)
- case (*ast.SelectorExpr): // like X.Y, check X
- return s.isVar(loop, typed.X)
- }
- return false
-}
-
-// Get variable identity
-func (s *Searcher) getIdentity(expr ast.Expr) *ast.Ident {
- switch typed := expr.(type) {
- case *ast.SelectorExpr:
- // Ignore if the parent is pointer ref (fix for #2)
- if _, ok := s.Pass.TypesInfo.Types[typed.X].Type.(*types.Pointer); ok {
- return nil
- }
-
- // Get parent identity; i.e. `a.b` of the `a.b.c`.
- return s.getIdentity(typed.X)
-
- case *ast.Ident:
- // Get simple identity; i.e. `a` of the `a`.
- if typed.Obj == nil {
- return nil
- }
- return typed
- }
- return nil
-}