full diff: https://github.com/dominikh/go-tools/compare/2019.2.3...2020.1.3 Also updates tests to accomodate updated rules: --- FAIL: TestSourcesFromTestdataWithIssuesDir/staticcheck.go (0.43s) linters_test.go:137: [run --disable-all --print-issued-lines=false --print-linter-name=false --out-format=line-number --max-same-issues=10 -Estaticcheck --no-config testdata/staticcheck.go] linters_test.go:33: Error Trace: linters_test.go:33 linters_test.go:138 linters_test.go:53 Error: Received unexpected error: staticcheck.go:11: no match for `self-assignment of x to x` vs ["SA4006: this value of `x` is never used"] in: staticcheck.go:11:2: SA4006: this value of `x` is never used unmatched errors staticcheck.go:11:2: SA4006: this value of `x` is never used Test: TestSourcesFromTestdataWithIssuesDir/staticcheck.go Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
		
			
				
	
	
		
			59 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Package lintdsl provides helpers for implementing static analysis
 | 
						||
// checks. Dot-importing this package is encouraged.
 | 
						||
package lintdsl
 | 
						||
 | 
						||
import (
 | 
						||
	"bytes"
 | 
						||
	"fmt"
 | 
						||
	"go/ast"
 | 
						||
	"go/format"
 | 
						||
 | 
						||
	"golang.org/x/tools/go/analysis"
 | 
						||
	"honnef.co/go/tools/pattern"
 | 
						||
)
 | 
						||
 | 
						||
func Inspect(node ast.Node, fn func(node ast.Node) bool) {
 | 
						||
	if node == nil {
 | 
						||
		return
 | 
						||
	}
 | 
						||
	ast.Inspect(node, fn)
 | 
						||
}
 | 
						||
 | 
						||
func Match(pass *analysis.Pass, q pattern.Pattern, node ast.Node) (*pattern.Matcher, bool) {
 | 
						||
	// Note that we ignore q.Relevant – callers of Match usually use
 | 
						||
	// AST inspectors that already filter on nodes we're interested
 | 
						||
	// in.
 | 
						||
	m := &pattern.Matcher{TypesInfo: pass.TypesInfo}
 | 
						||
	ok := m.Match(q.Root, node)
 | 
						||
	return m, ok
 | 
						||
}
 | 
						||
 | 
						||
func MatchAndEdit(pass *analysis.Pass, before, after pattern.Pattern, node ast.Node) (*pattern.Matcher, []analysis.TextEdit, bool) {
 | 
						||
	m, ok := Match(pass, before, node)
 | 
						||
	if !ok {
 | 
						||
		return m, nil, false
 | 
						||
	}
 | 
						||
	r := pattern.NodeToAST(after.Root, m.State)
 | 
						||
	buf := &bytes.Buffer{}
 | 
						||
	format.Node(buf, pass.Fset, r)
 | 
						||
	edit := []analysis.TextEdit{{
 | 
						||
		Pos:     node.Pos(),
 | 
						||
		End:     node.End(),
 | 
						||
		NewText: buf.Bytes(),
 | 
						||
	}}
 | 
						||
	return m, edit, true
 | 
						||
}
 | 
						||
 | 
						||
func Selector(x, sel string) *ast.SelectorExpr {
 | 
						||
	return &ast.SelectorExpr{
 | 
						||
		X:   &ast.Ident{Name: x},
 | 
						||
		Sel: &ast.Ident{Name: sel},
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// ExhaustiveTypeSwitch panics when called. It can be used to ensure
 | 
						||
// that type switches are exhaustive.
 | 
						||
func ExhaustiveTypeSwitch(v interface{}) {
 | 
						||
	panic(fmt.Sprintf("internal error: unhandled case %T", v))
 | 
						||
}
 |