Skip to content

Commit

Permalink
feat: extend matching
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez committed Jul 16, 2022
1 parent 6114a44 commit 52ca441
Show file tree
Hide file tree
Showing 12 changed files with 305 additions and 264 deletions.
25 changes: 15 additions & 10 deletions asasalint.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package asasalint

import (
"bytes"
"fmt"
"go/ast"
"go/printer"
"go/token"
"go/types"
"log"
"regexp"
"strings"

Expand All @@ -13,7 +16,7 @@ import (
"golang.org/x/tools/go/ast/inspector"
)

const BuiltinExclusions = `^(Print|Fprint|Sprint|Fatal|Panic|Error|Warn|Warning|Info|Debug)(|f|ln)$`
const BuiltinExclusions = `^(fmt|log|logger)\.(Print|Fprint|Sprint|Fatal|Panic|Error|Warn|Warning|Info|Debug)(|f|ln)$`

type LinterSetting struct {
Exclude []string
Expand Down Expand Up @@ -91,7 +94,11 @@ func (a *analyzer) AsCheckVisitor(pass *analysis.Pass) func(ast.Node) {
return
}

fnName := getFuncName(caller)
fnName, err := getFuncName(pass.Fset, caller)
if err != nil {
log.Println(err)
return
}

for _, exclude := range a.excludes {
if exclude.MatchString(fnName) {
Expand Down Expand Up @@ -126,15 +133,13 @@ func (a *analyzer) AsCheckVisitor(pass *analysis.Pass) func(ast.Node) {
}
}

func getFuncName(caller *ast.CallExpr) string {
switch n := caller.Fun.(type) {
case *ast.Ident:
return n.Name
case *ast.SelectorExpr:
return n.Sel.Name
default:
return ""
func getFuncName(fset *token.FileSet, caller *ast.CallExpr) (string, error) {
buf := new(bytes.Buffer)
if err := printer.Fprint(buf, fset, caller.Fun); err != nil {
return "", fmt.Errorf("unable to print node at %s: %w", fset.Position(caller.Fun.Pos()), err)
}

return buf.String(), nil
}

func isSliceAnyVariadicFuncType(typ types.Type) (r bool) {
Expand Down
72 changes: 54 additions & 18 deletions asasalint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,33 +54,69 @@ func TestIsSliceAnyVariadicFuncType(t *testing.T) {
}

func TestGetFuncName(t *testing.T) {
src := `package p
testCases := []struct {
desc string
src string
expected string
}{
{
desc: "function",
src: `package p
func hello(a int, b ...any) {}
func hello2(a int, b int) { hello(a, b)}
`,
expected: "hello",
},
{
desc: "method",
src: `package p
type A struct {}
func (a *A) hello(a int, b ...any) {
hello(a, b...)
}
func (a *A) hello(a int, b ...any) {}
func (a *A) hello2(a int, b int) {
a.hello(a, b)
}
`
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "src.go", src, 0)
if err != nil {
panic(err)
`,
expected: "a.hello",
},
{
desc: "function inside a method",
src: `package p
type A struct {}
func (a *A) hello(a int, b ...any) {
hello(a, b...)
}
`,
expected: "hello",
},
}

ast.Inspect(f, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.CallExpr:
s := getFuncName(x)
if s != "hello" {
t.Errorf("getFuncName(%#v) = %v, want hello", x.Fun, s)
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()

fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "src.go", test.src, 0)
if err != nil {
panic(err)
}
}
return true
})

ast.Inspect(f, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.CallExpr:
s, err := getFuncName(fset, x)
if err != nil {
t.Fatal(err)
}

if s != test.expected {
t.Errorf("%s: got %s, want %s", fset.Position(x.Fun.Pos()), s, test.expected)
}
}
return true
})
})
}
}

func TestAnalyzer(t *testing.T) {
Expand Down
50 changes: 25 additions & 25 deletions testdata/src/basic/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,38 +34,38 @@ type Logger interface {
Panicln(args ...interface{})
}

func fromLogger(l Logger) {
func fromLogger(logger Logger) {
var a = []any{1, 2, 3}

l.Debug(a)
l.Debugf("%v", a)
l.Debugln(a)
logger.Debug(a)
logger.Debugf("%v", a)
logger.Debugln(a)

l.Info(a)
l.Infof("%v", a)
l.Infoln(a)
logger.Info(a)
logger.Infof("%v", a)
logger.Infoln(a)

l.Print(a)
l.Printf("%v", a)
l.Println(a)
logger.Print(a)
logger.Printf("%v", a)
logger.Println(a)

l.Warn(a)
l.Warnf("%v", a)
l.Warnln(a)
logger.Warn(a)
logger.Warnf("%v", a)
logger.Warnln(a)

l.Warning(a)
l.Warningf("%v", a)
l.Warningln(a)
logger.Warning(a)
logger.Warningf("%v", a)
logger.Warningln(a)

l.Error(a)
l.Errorf("%v", a)
l.Errorln(a)
logger.Error(a)
logger.Errorf("%v", a)
logger.Errorln(a)

l.Fatal(a)
l.Fatalf("%v", a)
l.Fatalln(a)
logger.Fatal(a)
logger.Fatalf("%v", a)
logger.Fatalln(a)

l.Panic(a)
l.Panicf("%v", a)
l.Panicln(a)
logger.Panic(a)
logger.Panicf("%v", a)
logger.Panicln(a)
}
50 changes: 25 additions & 25 deletions testdata/src/basic/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,39 @@ package main
import "testing"

func TestLogger(t *testing.T) {
var l Logger
var logger Logger

var a = []any{1, 2, 3}

l.Debug(a)
l.Debugf("%v", a)
l.Debugln(a)
logger.Debug(a)
logger.Debugf("%v", a)
logger.Debugln(a)

l.Info(a)
l.Infof("%v", a)
l.Infoln(a)
logger.Info(a)
logger.Infof("%v", a)
logger.Infoln(a)

l.Print(a)
l.Printf("%v", a)
l.Println(a)
logger.Print(a)
logger.Printf("%v", a)
logger.Println(a)

l.Warn(a)
l.Warnf("%v", a)
l.Warnln(a)
logger.Warn(a)
logger.Warnf("%v", a)
logger.Warnln(a)

l.Warning(a)
l.Warningf("%v", a)
l.Warningln(a)
logger.Warning(a)
logger.Warningf("%v", a)
logger.Warningln(a)

l.Error(a)
l.Errorf("%v", a)
l.Errorln(a)
logger.Error(a)
logger.Errorf("%v", a)
logger.Errorln(a)

l.Fatal(a)
l.Fatalf("%v", a)
l.Fatalln(a)
logger.Fatal(a)
logger.Fatalf("%v", a)
logger.Fatalln(a)

l.Panic(a)
l.Panicf("%v", a)
l.Panicln(a)
logger.Panic(a)
logger.Panicf("%v", a)
logger.Panicln(a)
}
50 changes: 25 additions & 25 deletions testdata/src/custom/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,38 +34,38 @@ type Logger interface {
Panicln(args ...interface{})
}

func fromLogger(l Logger) {
func fromLogger(logger Logger) {
var a = []any{1, 2, 3}

l.Debug(a)
l.Debugf("%v", a)
l.Debugln(a)
logger.Debug(a)
logger.Debugf("%v", a)
logger.Debugln(a)

l.Info(a)
l.Infof("%v", a)
l.Infoln(a)
logger.Info(a)
logger.Infof("%v", a)
logger.Infoln(a)

l.Print(a)
l.Printf("%v", a)
l.Println(a)
logger.Print(a)
logger.Printf("%v", a)
logger.Println(a)

l.Warn(a)
l.Warnf("%v", a)
l.Warnln(a)
logger.Warn(a)
logger.Warnf("%v", a)
logger.Warnln(a)

l.Warning(a)
l.Warningf("%v", a)
l.Warningln(a)
logger.Warning(a)
logger.Warningf("%v", a)
logger.Warningln(a)

l.Error(a)
l.Errorf("%v", a)
l.Errorln(a)
logger.Error(a)
logger.Errorf("%v", a)
logger.Errorln(a)

l.Fatal(a)
l.Fatalf("%v", a)
l.Fatalln(a)
logger.Fatal(a)
logger.Fatalf("%v", a)
logger.Fatalln(a)

l.Panic(a)
l.Panicf("%v", a)
l.Panicln(a)
logger.Panic(a)
logger.Panicf("%v", a)
logger.Panicln(a)
}
Loading

0 comments on commit 52ca441

Please sign in to comment.