为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 go/analysis 找到 Ident 的声明?

如何使用 go/analysis 找到 Ident 的声明?

Go
波斯汪 2022-08-15 16:21:26
我使用go/analysis来创建自己的静态分析工具。我仍然不知道如何从ast中找到def信息。同上。这是我的测试数据package randomcheckfunc xxx() {}func demo()  {    xxx()}还有我自己的分析仪import (    "fmt"    "go/ast"    "golang.org/x/tools/go/analysis"    "golang.org/x/tools/go/analysis/passes/inspect")var name string // -name flagvar Analyzer = &analysis.Analyzer{    Name:     "fft",    Requires: []*analysis.Analyzer{inspect.Analyzer},    Run:      run,}//pass.Fset.Position(name.Pos())func run(pass *analysis.Pass) (interface{}, error) {    for _, f := range pass.Files {        ast.Inspect(f, func(node ast.Node) bool {            name,ok := node.(*ast.Ident)            if !ok {                return true            }            if name == nil {                return true            }            if pass.TypesInfo.Defs[name] != nil {                fmt.Println("def: " ,name)            } else {                fmt.Println("use: ", name)            }            return true        })    }    return nil, nil}output:use:  randomcheckdef:  xxxdef:  demouse:  xxx我需要直接从 use:xxx 找到 def 信息 def:xxx,但我找不到有用的信息。类型信息
查看完整描述

1 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

你在寻找方法吗?以下是经过一些修改的版本:ObjectOf


func run(pass *analysis.Pass) (interface{}, error) {

    for _, f := range pass.Files {

        ast.Inspect(f, func(node ast.Node) bool {

            name, ok := node.(*ast.Ident)

            if !ok {

                return true

            }

            if name == nil {

                return true

            }


            fmt.Println("ident:", nodeString(node, pass.Fset))

            obj := pass.TypesInfo.ObjectOf(name)

            fmt.Println(obj)

            if obj != nil {

                fmt.Println("  pos:", pass.Fset.Position(obj.Pos()))

            }

            return true

        })

    }


    return nil, nil

}


// nodeString formats a syntax tree in the style of gofmt.

func nodeString(n ast.Node, fset *token.FileSet) string {

    var buf bytes.Buffer

    format.Node(&buf, fset, n)

    return buf.String()

}

在示例输入文件上运行时,它显示:


ident: randomcheck

<nil>

ident: xxx

func command-line-arguments.xxx()

  pos: /home/eliben/temp/randomcheck.go:3:6

ident: demo

func command-line-arguments.demo()

  pos: /home/eliben/temp/randomcheck.go:5:6

ident: xxx

func command-line-arguments.xxx()

  pos: /home/eliben/temp/randomcheck.go:3:6

请注意,最后一个 id 是作为对顶级函数的引用及其正确位置等找到的。xxxxxx()


查看完整回答
反对 回复 2022-08-15
  • 1 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信