Skip to content

Commit

Permalink
Merge pull request #1 from gostaticanalysis/ignore-Any
Browse files Browse the repository at this point in the history
Add ignore option
  • Loading branch information
tenntenn authored Jul 11, 2021
2 parents d9c562f + c751b9d commit 8f7ad9e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
45 changes: 26 additions & 19 deletions passes/fieldtype/fieldtype.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"go/ast"
"go/types"
"strconv"
"strings"

"github.com/gostaticanalysis/analysisutil"
"golang.org/x/tools/go/analysis"
Expand All @@ -13,6 +14,10 @@ import (

const doc = "fieldtype finds confliction type of field"

var (
flagIgnoreFuncs string
)

var Analyzer = &analysis.Analyzer{
Name: "fieldtype",
Doc: doc,
Expand All @@ -22,13 +27,20 @@ var Analyzer = &analysis.Analyzer{
},
}

func init() {
Analyzer.Flags.StringVar(&flagIgnoreFuncs, "ignore", "Any", "comma separated ignore function names")
}

func run(pass *analysis.Pass) (interface{}, error) {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
zappkg := zap(pass)
if zappkg == nil {
return nil, nil
}
fs := fieldFuncs(pass, zappkg)
for _, ignore := range strings.Split(flagIgnoreFuncs, ",") {
delete(fs, strings.TrimSpace(ignore))
}

m := make(map[string]string)
nodes := []ast.Node{(*ast.CallExpr)(nil)}
Expand Down Expand Up @@ -56,8 +68,8 @@ func zap(pass *analysis.Pass) *types.Package {
return nil
}

func fieldFuncs(pass *analysis.Pass, zappkg *types.Package) []*types.Func {
var fs []*types.Func
func fieldFuncs(pass *analysis.Pass, zappkg *types.Package) map[string]*types.Func {
fs := make(map[string]*types.Func)
scope := zappkg.Scope()
fieldtyp := scope.Lookup("Field").Type()
for _, name := range scope.Names() {
Expand All @@ -83,12 +95,12 @@ func fieldFuncs(pass *analysis.Pass, zappkg *types.Package) []*types.Func {
continue
}

fs = append(fs, obj)
fs[obj.Name()] = obj
}
return fs
}

func fieldkey(pass *analysis.Pass, fs []*types.Func, call *ast.CallExpr) (funcname, key string) {
func fieldkey(pass *analysis.Pass, fs map[string]*types.Func, call *ast.CallExpr) (funcname, key string) {
var id *ast.Ident
switch fun := call.Fun.(type) {
case *ast.Ident:
Expand All @@ -97,25 +109,20 @@ func fieldkey(pass *analysis.Pass, fs []*types.Func, call *ast.CallExpr) (funcna
id = fun.Sel
}
obj := pass.TypesInfo.ObjectOf(id)
if obj == nil {
f := fs[obj.Name()]
if f == nil || f != obj {
return "", ""
}

for _, f := range fs {
if f == obj {
tv := pass.TypesInfo.Types[call.Args[0]]
if tv.Value == nil {
return "", ""
}

key, err := strconv.Unquote(tv.Value.String())
if err != nil {
return "", ""
}
tv := pass.TypesInfo.Types[call.Args[0]]
if tv.Value == nil {
return "", ""
}

return f.Name(), key
}
key, err := strconv.Unquote(tv.Value.String())
if err != nil {
return "", ""
}

return "", ""
return f.Name(), key
}
1 change: 1 addition & 0 deletions passes/fieldtype/fieldtype_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ import (
// TestAnalyzer is a test for Analyzer.
func TestAnalyzer(t *testing.T) {
testdata := testutil.WithModules(t, analysistest.TestData(), nil)
fieldtype.Analyzer.Flags.Set("ignore", "Any, Reflect")
analysistest.Run(t, testdata, fieldtype.Analyzer, "a")
}
2 changes: 2 additions & 0 deletions passes/fieldtype/testdata/src/a/a.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ import "go.uber.org/zap"
func f() {
zap.String("id", "100")
zap.Int("id", 100) // want `"id" conflict type Int vs String`
zap.Any("id", "100") // OK - ignore
zap.Reflect("id", "100") // OK - ignore
zap.String("xxx", "100") // OK
}

0 comments on commit 8f7ad9e

Please sign in to comment.