抽象语法树 (AST) 扫描

时间:2021-08-01 13:58:16

标签: go casting abstract-syntax-tree

我正在尝试从 go AST 中提取函数调用

$ cat main.go
package main
import ("fmt"; "go/ast"; "go/token"; "go/parser"; "io/ioutil")

func CalledFuncs(n ast.Node) bool {
    switch n.(type) {
    case *ast.CallExpr:
        l := ast.CallExpr(n).Lparen
        r := ast.CallExpr(n).Right
        fmt.Printf("call %d( ... %d)\n",l,r)
    }
    return true
}

func main() {
    fset := token.NewFileSet()
    src,_ := ioutil.ReadFile("simple.go")
    f, _ := parser.ParseFile(fset,">>",src,0)
    ast.Inspect(f, CalledFuncs)
}

但是 go 编译器抱怨我无法进行转换:

$ go build -o main main.go
# command-line-arguments
./main.go:7:26: cannot convert n (type ast.Node) to type ast.CallExpr
./main.go:8:26: cannot convert n (type ast.Node) to type ast.CallExpr

我可能在这里遗漏了一些东西。

1 个答案:

答案 0 :(得分:1)

https://golang.org/ref/spec#Type_switches

<块引用>

TypeSwitchGuard 可能包含 short variable declaration。什么时候 使用这种形式,变量在最后声明 TypeSwitchCase 在每个子句的 implicit block 中。在带有 a 的子句中 case 只列出一种类型,变量具有该类型;否则, 变量具有 TypeSwitchGuard 中表达式的类型。

这意味着您可以执行以下操作:

func CalledFuncs(n ast.Node) bool {
    switch x := n.(type) {
    case *ast.CallExpr:
        l := x.Lparen
        r := x.Rparen
        fmt.Printf("call %d( ... %d)\n", l, r)
    }
    return true
}