Here is test file
func demo() {
name:=xxx()
fmt.Println(name)
}
And my ast traversal code
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
})
I find I have to travel ast from up to down like this. Find AssignStmt and then get AssignStmt->Lhs
But I need to find ast.Ident(name) first and then to find whether its parent is AssignStmt in some cases.
I am not sure is it possible that I can go from bottom to top.
Manage a stack of ancestor nodes as the inspector is called:
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
})