Search code examples
goabstract-syntax-tree

Is this the correct behavior of ast parsing


I am working on learning how to use and how golang's ast library works. I am parsing https://github.com/modern-go/concurrent, avoiding the test files and the go_below_19.go since it causes errors.

My problem is with the parsing of these lines in the file unbounded_executor.go,

var HandlePanic = func(recovered interface{}, funcName string) {
    ErrorLogger.Println(fmt.Sprintf("%s panic: %v", funcName, recovered))
    ErrorLogger.Println(string(debug.Stack()))
}

The ast.Ident for ErrorLogger in both instances have a nil obj.

But, I believe that it should not be nil and should reference these lines from log.go,

// ErrorLogger is used to print out error, can be set to writer other than stderr
var ErrorLogger = log.New(os.Stderr, "", 0)

Am I wrong, or is there a problem with the parser? I've followed several references on parsing files and reuse a *token.FileSet across each of the files and use ParseComments as the mode.

edit:

There is a large code base surrounding this, so the code demonstrating this will include snippets.

This is performed with the same fset across all non-test go files, without build restrictions that would stop the code from being used with 1.16

parsedFile, parseErr := parser.ParseFile(fset, filePath, nil, parser.ParseComments)

Solution

  • Call ast.NewPackage to resolve identifiers in the AST:

    fset := token.NewFileSet()
    files := make(map[string]*ast.File)
    for _, name := range []string{"unbounded_executor.go", "log.go"} {
        f, err := parser.ParseFile(fset, name, nil, parser.ParseComments)
        if err != nil {
            log.Fatal(err)
        }
        files[name] = f
    }
    
    ast.NewPackage(fset, files, nil, nil)
    
    ast.Inspect(files["unbounded_executor.go"], func(n ast.Node) bool {
        if n, ok := n.(*ast.Ident); ok && n.Name == "ErrorLogger" {
            fmt.Println(n.Obj)
        }
        return true
    })
    

    Because a proper importer is not provided and the list of files does not include all files in the package, NewPackage returns unresolved symbol errors.