2017-09-08 9 views
3

私はすべての関数呼び出しをastを使用して関数にリストしようとしています。しかし、どのように使用されるべきかを理解することができない。私はこれまでこれを得ることができました。astを使用して関数内のすべての関数呼び出しを取得する

set := token.NewFileSet() 
packs, err := parser.ParseFile(set, serviceFile, nil, 0) 
if err != nil { 
    fmt.Println("Failed to parse package:", err) 
    os.Exit(1) 
} 

funcs := []*ast.FuncDecl{} 
for _, d := range packs.Decls { 
    if fn, isFn := d.(*ast.FuncDecl); isFn { 
     funcs = append(funcs, fn) 
    } 
} 

私はfuncsを検査しました。私はfuncs[n1].Body.List[n2]に行く。 しかし、これの後に私はどのように私はdata.X.Fun.data.Sel.name(ゴーグランドの評価から得た)の下層を読み取ると仮定していると呼ばれている関数の名前を取得することはできません。

+0

go/astパッケージの使い方を理解しようとすると、[print](https://godoc.org/go/ast#Print)のツリーの例が役立ちます。関数呼び出しを変換から区別する必要がある場合は、go/typesを使用する方が簡単です。 –

+0

検査する目的の関数を記述し、https://golang.org/pkg/go/ast/#Printに似たコードを記述し、コードを読み込んで検査します(直接func.Bodyノードを渡します)。 +/- https://gist.github.com/mh-cbon/3ed5d9c39e9635cfed0f896000098133これは多くのastとの協力に役立ちます。 –

答えて

0

私が見つけたのは、実際にデータを抽出するために多くのキャストが必要なことです。

ここでは、funcでfunc呼び出しを抽出する方法の例を示します。

for _, function := range funcs { 
    extractFuncCallInFunc(function.Body.List) 
} 

func extractFuncCallInFunc(stmts []ast.Stmt) { 
    for _, stmt := range funcs { 
     if exprStmt, ok := stmt.(*ast.ExprStmt); ok { 
      if call, ok := exprStmt.X.(*ast.CallExpr); ok { 
       if fun, ok := call.Fun.(*ast.SelectorExpr); ok { 
        funcName := fun.Sel.Name 
       } 
      } 
     } 
    } 
} 

また、これをキャストするために必要なものを見つけ出すための助けを借りてこれを見つけました。 http://goast.yuroyoro.net/

0

あなたはast.Inspectを使用してノードのタイプを切り替えることができます。

for _, fun := range funcs { 
    ast.Inspect(fun, func(node ast.Node) bool { 
     switch n := node.(type) { 
      case *ast.CallExpr: 
       fmt.Println(n) // prints every func call expression 
     } 
     return true 
    }) 
} 
関連する問題