Golang静态标识符解析 [英] Golang static identifier resolution

查看:121
本文介绍了Golang静态标识符解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 go / parse go / token 对Go项目中的函数调用进行一些静态分析c $ c>和 go / ast 模块,但我无法弄清楚如何确定给定的 ast.Ident object。



例如,如果解析这样的内容:

  textToContain:= bytes.NewBuffer([] byte {})
//很多其他代码
text:= textToContain.String()//< - 我关心这个函数调用

(这是从这里解析的: file )编辑:它花了很多代码来解析这个所以我没有在这里发布,但您可以在 https:// gist上找到它。 github.com/EricChiang/6735340c5fa3d2de2b73



我得到以下代码prin使用 ast.Print function

  0 * ast.CallExpr {
1。有趣:* ast.SelectorExpr {
2。 。 X:* ast.Ident {
4。 。 。名称:textToContain
5。 。 。 Obj:* ast.Object {
6。 。 。 。种类:var
7。 。 。 。名称:textToContain
8。 。 。 。申报:* ast.AssignStmt {
9。 。 。 。 。 Lhs:[] ast.Expr(len = 1){
10。 。 。 。 。 。 0:* ast.Ident {
12。 。 。 。 。 。 。名称:textToContain
13。 。 。 。 。 。 。 Obj:*(obj @ 5)
14。 。 。 。 。 。 }
15。 。 。 。 。 }
17。 。 。 。 。 Tok::=
18。 。 。 。 。 Rhs:[] ast.Expr(len = 1){
19。 。 。 。 。 。 0:* ast.CallExpr {
20。 。 。 。 。 。 。趣味:* ast.SelectorExpr {
21。 。 。 。 。 。 。 。 X:* ast.Ident {
23。 。 。 。 。 。 。 。 。名称:字节
24。 。 。 。 。 。 。 。 }
25。 。 。 。 。 。 。 。 Sel:* ast.Ident {
27。 。 。 。 。 。 。 。 。名称:NewBuffer
28。 。 。 。 。 。 。 。 }
29。 。 。 。 。 。 。 }
31。 。 。 。 。 。 。参数:[] ast.Expr(len = 1){
32。 。 。 。 。 。 。 。 0:* ast.CompositeLit {
33。 。 。 。 。 。 。 。 。类型:* ast.ArrayType {
35。 。 。 。 。 。 。 。 。 。 Elt:* ast.Ident {
37。 。 。 。 。 。 。 。 。 。 。名称:字节
38。 。 。 。 。 。 。 。 。 。 }
39。 。 。 。 。 。 。 。 。 }
42。 。 。 。 。 。 。 。 }
43。 。 。 。 。 。 。 }
44。 。 。 。 。 。 。省略号: -
46。 。 。 。 。 。 }
47。 。 。 。 。 }
48。 。 。 。 }
49。 。 。 }
50。 。 }
51。 。 Sel:* ast.Ident {
53。 。 。名称:字符串
54。 。 }
55。 }
57。省略号: -
59}

但我无法看到哪里可以推断出类型的 textToContain



我知道一堆可以做到这一点的工具,例如这个例子,但我认为我会走错方向。

解决方案

3of3是对的;你需要类型检查器,它是 golang.org/x/tools/go/types 。通常,表达式的类型取决于导入依赖关系传递闭包的类型信息,因此您可能需要使用 golang.org/x/tools/go/loader 包(我维护),它为您处理许多具有挑战性的细节。它的 stdlib_test.go 可能是一个有用的起点。



一旦确定了感兴趣的表达,可以在AST包的 types.Info 结构中的一个映射中找到它的类型。



情况下,表达式是一个引用标识符( * ast.Ident ),所以查看使用映射来查找<它引用的code> types.Object (命名实体)---一个局部变量( * types.Var )案件。对于标识符以外的表达式, Types 映射会告诉你它的类型。


I'm attempting to do some static analysis on function calls in a Go project using the go/parse, go/token and go/ast modules, but I can't figure out how to determine the type of a given ast.Ident object.

For instance if parse something like this:

textToContain := bytes.NewBuffer([]byte{})
// lots of other code
text := textToContain.String() // <- I care about this function call

(this is parsed from here: file)

EDIT: It took a lot of code to parse this so I didn't post it here, but you can find it as a gist at: https://gist.github.com/EricChiang/6735340c5fa3d2de2b73

I get the following code printed using the ast.Print function

 0  *ast.CallExpr {
 1  .  Fun: *ast.SelectorExpr {
 2  .  .  X: *ast.Ident {
 4  .  .  .  Name: "textToContain"
 5  .  .  .  Obj: *ast.Object {
 6  .  .  .  .  Kind: var
 7  .  .  .  .  Name: "textToContain"
 8  .  .  .  .  Decl: *ast.AssignStmt {
 9  .  .  .  .  .  Lhs: []ast.Expr (len = 1) {
10  .  .  .  .  .  .  0: *ast.Ident {
12  .  .  .  .  .  .  .  Name: "textToContain"
13  .  .  .  .  .  .  .  Obj: *(obj @ 5)
14  .  .  .  .  .  .  }
15  .  .  .  .  .  }
17  .  .  .  .  .  Tok: :=
18  .  .  .  .  .  Rhs: []ast.Expr (len = 1) {
19  .  .  .  .  .  .  0: *ast.CallExpr {
20  .  .  .  .  .  .  .  Fun: *ast.SelectorExpr {
21  .  .  .  .  .  .  .  .  X: *ast.Ident {
23  .  .  .  .  .  .  .  .  .  Name: "bytes"
24  .  .  .  .  .  .  .  .  }
25  .  .  .  .  .  .  .  .  Sel: *ast.Ident {
27  .  .  .  .  .  .  .  .  .  Name: "NewBuffer"
28  .  .  .  .  .  .  .  .  }
29  .  .  .  .  .  .  .  }
31  .  .  .  .  .  .  .  Args: []ast.Expr (len = 1) {
32  .  .  .  .  .  .  .  .  0: *ast.CompositeLit {
33  .  .  .  .  .  .  .  .  .  Type: *ast.ArrayType {
35  .  .  .  .  .  .  .  .  .  .  Elt: *ast.Ident {
37  .  .  .  .  .  .  .  .  .  .  .  Name: "byte"
38  .  .  .  .  .  .  .  .  .  .  }
39  .  .  .  .  .  .  .  .  .  }
42  .  .  .  .  .  .  .  .  }
43  .  .  .  .  .  .  .  }
44  .  .  .  .  .  .  .  Ellipsis: -
46  .  .  .  .  .  .  }
47  .  .  .  .  .  }
48  .  .  .  .  }
49  .  .  .  }
50  .  .  }
51  .  .  Sel: *ast.Ident {
53  .  .  .  Name: "String"
54  .  .  }
55  .  }
57  .  Ellipsis: -
59  }

But I can't see where I could infer the type of textToContain

I know a bunch of tools that can do this, for instance this example from the go blog, but I think I'm going in the wrong direction.

解决方案

3of3 is right; you need the type checker, which is golang.org/x/tools/go/types. In general, the type of an expression depends on type information for the transitive closure of import dependencies, so you will probably want to use the golang.org/x/tools/go/loader package (which I maintain), which takes care of many challenging details for you. Its stdlib_test.go may be a useful starting point.

Once you've identified the expression of interest, you can find its type in one of the mappings within the types.Info structure for the AST's package.

In this case, the expression is a referring identifier (*ast.Ident) so look in the Uses mapping to find the types.Object (named entity) to which it refers---a local variable (*types.Var) in this case. For expressions other than identifiers, the Types mapping will tell you its type.

这篇关于Golang静态标识符解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆