package main import ( "fmt" "go/ast" "go/importer" "go/parser" "go/token" "go/types" "log" "strings" ) // !+input const hello = ` package main import "fmt" // append func main() { // fmt fmt.Println("Hello, world") // main main, x := 1, 2 // main print(main, x) // x } // x ` //!-input // !+main func main() { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hello.go", hello, parser.ParseComments) if err != nil { log.Fatal(err) // parse error } conf := types.Config{Importer: importer.Default()} pkg, err := conf.Check("cmd/hello", fset, []*ast.File{f}, nil) if err != nil { log.Fatal(err) // type error } // Each comment contains a name. // Look up that name in the innermost scope enclosing the comment. for _, comment := range f.Comments { pos := comment.Pos() name := strings.TrimSpace(comment.Text()) fmt.Printf("At %s,\t%q = ", fset.Position(pos), name) inner := pkg.Scope().Innermost(pos) if _, obj := inner.LookupParent(name, pos); obj != nil { fmt.Println(obj) } else { fmt.Println("not found") } } } //!-main /* //!+output $ go build golang.org/x/example/gotypes/lookup $ ./lookup At hello.go:6:1, "append" = builtin append At hello.go:8:9, "fmt" = package fmt At hello.go:10:9, "main" = func cmd/hello.main() At hello.go:12:9, "main" = var main int At hello.go:14:9, "x" = var x int At hello.go:16:1, "x" = not found //!-output */