如何在golang ast遍历中从子节点检索父节点?
How to retrieve parent node from child node in golang ast traversal?
这是测试文件
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),然后在某些情况下再去寻找它的parent是不是AssignStmt
我不确定我是否可以从下到上。
调用检查器时管理一堆祖先节点:
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
})
这是测试文件
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),然后在某些情况下再去寻找它的parent是不是AssignStmt
我不确定我是否可以从下到上。
调用检查器时管理一堆祖先节点:
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
})