I'm creating a custom linter for Go which validates certain parameters of the 'foo' function in the example below.
Let's assume we have a sample.go
, which looks something like this.
// Package pkg does something.
package pkg
import (
"fmt"
)
func foo(use string, items ...interface{}) {
s := "lol"
fmt.Sprint(s)
}
func yolo() {
foo("lol", "p1", "p2", "ppp3:", "p4")
}
We then have another file called bar.go
which implements a linter for the foo function (checking the length of it's parameters) as follows:
func (f *file) checkForValidFoo() {
f.walk(func(n ast.Node) bool {
ce, ok := n.(*ast.CallExpr)
if !ok || len(ce.Args) <= 1 {
return true
}
expr, ok := ce.Fun.(*ast.Ident)
if expr.Name == "foo" {
decl, _ := ce.Fun.(*ast.Ident)
funDec := decl.Obj.Decl.(*ast.FuncDecl)
// How do I know this is the foo function I want, and not some other one?
for i, arg := range ce.Args[1:] {
if i%2 == 0 {
realArg := arg.(*ast.BasicLit)
if(len(realArg.Value) > 2) {
break
}
}
}
}
return true
})
}
How do I know, that the call expression ce, ok := n.(*ast.CallExpr)
, is actually calling the foo function in the bar.go
and not some other source file?
I was able to get into the function declaration object of the call expression - funDec
, but none of it's properties seem to help in uniquely identifying the function declaration/signature.
The code that I'm working with can be found here. In essence, what I'm looking for is kind of like a 'hashcode' implementation for a function declaration in Go.