I'm trying to parse function calls from a code using go/ast
package.
To do that, I first find all function calls like:
ast.Inspect(f, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.FuncDecl:
processFunction(x)
}
return true
})
And then, processFunction() looks like this:
func processFunction(e *ast.FuncDecl) {
// Save wrapper function name
f := e.Name.Name
for _, expression := range e.Body.List {
logrus.Printf("Current stmt: %#v", expression)
pkg := expression.(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr).X.(*ast.Ident).Name
fn := expression.(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr).Sel.Name
fcall := fmt.Sprintf("%s.%s", pkg, fn)
logrus.Printf("Yay. found my function call: ", fcall)
}
}
The problem with this code is that if that particular hierarchy is not found in AST, the program panics. I know that we can do interface conversions gracefully via
x, ok := x.(type)
But, if I do each conversion like this, my code will be huge. Trying to use that in this fails of course.
pkg, ok := expression.(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr).X.(*ast.Ident).Name
if !ok {
continue
}
Error:
./parser.go:41: assignment count mismatch: 2 = 1
Is there a concise way to do these series of conversions and also fail gracefully if this hierarchy is not found?