Uniquely identifying function declarations in Go AST for Linter

655 Views Asked by At

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.

Properties of the function object

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.

0

There are 0 best solutions below