github.com/amarpal/go-tools@v0.0.0-20240422043104-40142f59f616/debug/debug.go (about) 1 // Package debug contains helpers for debugging static analyses. 2 package debug 3 4 import ( 5 "bytes" 6 "go/ast" 7 "go/format" 8 "go/importer" 9 "go/parser" 10 "go/token" 11 "go/types" 12 ) 13 14 // TypeCheck parses and type-checks a single-file Go package from a string. 15 // The package must not have any imports. 16 func TypeCheck(src string) (*ast.File, *types.Package, *types.Info, error) { 17 fset := token.NewFileSet() 18 f, err := parser.ParseFile(fset, "foo.go", src, parser.ParseComments|parser.SkipObjectResolution) 19 if err != nil { 20 return nil, nil, nil, err 21 } 22 pkg := types.NewPackage("foo", f.Name.Name) 23 info := &types.Info{ 24 Types: map[ast.Expr]types.TypeAndValue{}, 25 Defs: map[*ast.Ident]types.Object{}, 26 Uses: map[*ast.Ident]types.Object{}, 27 Implicits: map[ast.Node]types.Object{}, 28 Selections: map[*ast.SelectorExpr]*types.Selection{}, 29 Scopes: map[ast.Node]*types.Scope{}, 30 InitOrder: []*types.Initializer{}, 31 Instances: map[*ast.Ident]types.Instance{}, 32 } 33 tcfg := &types.Config{ 34 Importer: importer.Default(), 35 } 36 if err := types.NewChecker(tcfg, fset, pkg, info).Files([]*ast.File{f}); err != nil { 37 return nil, nil, nil, err 38 } 39 return f, pkg, info, nil 40 } 41 42 func FormatNode(node ast.Node) string { 43 var buf bytes.Buffer 44 fset := token.NewFileSet() 45 format.Node(&buf, fset, node) 46 return buf.String() 47 }