在Go AST中为Linter

时间:2017-09-21 21:45:08

标签: go abstract-syntax-tree linter golint

我为Go创建了一个自定义的linter,它验证了&f; foo'的某些参数。以下示例中的函数。

我们假设我们有sample.go,看起来像这样。

// 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")
}

然后我们有另一个名为bar.go的文件,它为 foo 函数实现了一个linter(检查它的长度' s参数),如下所示:

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
    })
}

我如何知道,调用表达式ce, ok := n.(*ast.CallExpr)实际上是在bar.go而不是其他源文件中调用 foo 函数?

我能够进入调用表达式的函数声明对象 - funDec,但它的所有属性似乎都没有帮助唯一地标识函数声明/签名。

Properties of the function object

我可以找到与我合作的代码here。从本质上讲,我所寻找的有点像哈希码&#39; Go中函数声明的实现。

0 个答案:

没有答案