使用ast模块来获取函数中的所有函数调用。

huangapple go评论172阅读模式
英文:

Use ast to get all function calls in a function

问题

我正在尝试使用ast列出函数中的所有函数调用。但是我对如何使用它感到困惑。我已经做到了这一点。

  1. set := token.NewFileSet()
  2. packs, err := parser.ParseFile(set, serviceFile, nil, 0)
  3. if err != nil {
  4. fmt.Println("Failed to parse package:", err)
  5. os.Exit(1)
  6. }
  7. funcs := []*ast.FuncDecl{}
  8. for _, d := range packs.Decls {
  9. if fn, isFn := d.(*ast.FuncDecl); isFn {
  10. funcs = append(funcs, fn)
  11. }
  12. }

我已经检查了funcs。我到达了funcs[n1].Body.List[n2]
但是在这之后,我不明白我应该如何读取底层的data.X.Fun.data.Sel.name(从gogland的评估中获得),以获取被调用函数的名称。

英文:

I'm trying to list all function call in a function using ast. But having trouble understanding how it is suppose to be used. I have been able to get this far.

  1. set := token.NewFileSet()
  2. packs, err := parser.ParseFile(set, serviceFile, nil, 0)
  3. if err != nil {
  4. fmt.Println("Failed to parse package:", err)
  5. os.Exit(1)
  6. }
  7. funcs := []*ast.FuncDecl{}
  8. for _, d := range packs.Decls {
  9. if fn, isFn := d.(*ast.FuncDecl); isFn {
  10. funcs = append(funcs, fn)
  11. }
  12. }

I have inspected funcs. I get to funcs[n1].Body.List[n2].
But after this i don't understand how i'm suppose to read the underlaying data.X.Fun.data.Sel.name (got it from evaluation in gogland) to get name of the function being called.

答案1

得分: 2

你可以使用ast.Inspect来实现这个功能,并根据节点的类型使用switch语句。

  1. for _, fun := range funcs {
  2. ast.Inspect(fun, func(node ast.Node) bool {
  3. switch n := node.(type) {
  4. case *ast.CallExpr:
  5. fmt.Println(n) // 打印每个函数调用表达式
  6. }
  7. return true
  8. })
  9. }
英文:

you can use ast.Inspect for that and use a switch on the type of the node.

  1. for _, fun := range funcs {
  2. ast.Inspect(fun, func(node ast.Node) bool {
  3. switch n := node.(type) {
  4. case *ast.CallExpr:
  5. fmt.Println(n) // prints every func call expression
  6. }
  7. return true
  8. })
  9. }

答案2

得分: 0

好的,以下是翻译好的内容:

好的,我发现你需要进行很多类型转换才能提取数据。

这是一个示例,演示如何在函数中提取函数调用。

  1. for _, function := range funcs {
  2. extractFuncCallInFunc(function.Body.List)
  3. }
  4. func extractFuncCallInFunc(stmts []ast.Stmt) {
  5. for _, stmt := range stmts {
  6. if exprStmt, ok := stmt.(*ast.ExprStmt); ok {
  7. if call, ok := exprStmt.X.(*ast.CallExpr); ok {
  8. if fun, ok := call.Fun.(*ast.SelectorExpr); ok {
  9. funcName := fun.Sel.Name
  10. }
  11. }
  12. }
  13. }
  14. }

我还找到了一个有助于找出需要进行类型转换的内容的网站。
http://goast.yuroyoro.net/

英文:

Ok so what i found is that you have to a lot of casting to actually extract the data.

Here is an example on how to do extract the func call in a func.

  1. for _, function := range funcs {
  2. extractFuncCallInFunc(function.Body.List)
  3. }
  4. func extractFuncCallInFunc(stmts []ast.Stmt) {
  5. for _, stmt := range funcs {
  6. if exprStmt, ok := stmt.(*ast.ExprStmt); ok {
  7. if call, ok := exprStmt.X.(*ast.CallExpr); ok {
  8. if fun, ok := call.Fun.(*ast.SelectorExpr); ok {
  9. funcName := fun.Sel.Name
  10. }
  11. }
  12. }
  13. }
  14. }

I also found this with kind of help with finding out what you need to cast it to.
http://goast.yuroyoro.net/

huangapple
  • 本文由 发表于 2017年9月8日 19:20:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/46115312.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定