2

这是测试文件

func demo()  {
    name:=xxx()
    fmt.Println(name)
}

还有我的 ast 遍历代码

ast.Inspect(f, func(node ast.Node) bool {
    assign, ok := node.(*ast.AssignStmt) // find -> name:=xxx()
    if !ok {
        return true
    }
    if assign == nil {
        return true
    }
    var expr = assign.Lhs[0]
    fmt.Println(expr) // find -> name
    fmt.Println(nodeString(assign,pass.Fset))
    return true
})

我发现我必须像这样从上到下旅行。找到AssignStmt,然​​后得到AssignStmt->Lhs

但是在某些情况下,我需要先找到 ast.Ident(name) ,然后再查找其父项是否为 AssignStmt。

我不确定我是否可以从下到上。

4

1 回答 1

3

在调用检查器时管理一堆祖先节点:

var stack []ast.Node
ast.Inspect(f, func(n ast.Node) bool {

    // Look for the identifier.

    if n, ok := n.(*ast.Ident); ok {
        if n.Name == "name" {

            // Parent is stack[len(stack)-1]

            fmt.Println("found name")
            for _, n := range stack {
                fmt.Printf("%T\n", n)
            }
        }
    }

    // Manage the stack. Inspect calls a function like this:
    //   f(node)
    //   for each child {
    //      f(child) // and recursively for child's children
    //   }
    //   f(nil)
    if n == nil {
        // Done with node's children. Pop.
        stack = stack[:len(stack)-1]
    } else {
        // Push the current node for children.
        stack = append(stack, n)
    }

    return true
})

在操场上运行它

于 2021-03-26T03:07:28.197 回答