func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error { pkg.defs = make(map[*ast.Ident]types.Object) pkg.uses = make(map[*ast.Ident]types.Object) pkg.selectors = make(map[*ast.SelectorExpr]*types.Selection) pkg.spans = make(map[types.Object]Span) pkg.types = make(map[ast.Expr]types.TypeAndValue) config := types.Config{ // We use the same importer for all imports to ensure that // everybody sees identical packages for the given paths. Importer: stdImporter, // By providing a Config with our own error function, it will continue // past the first error. There is no need for that function to do anything. Error: func(error) {}, } info := &types.Info{ Selections: pkg.selectors, Types: pkg.types, Defs: pkg.defs, Uses: pkg.uses, } typesPkg, err := config.Check(pkg.path, fs, astFiles, info) pkg.typesPkg = typesPkg // update spans for id, obj := range pkg.defs { pkg.growSpan(id, obj) } for id, obj := range pkg.uses { pkg.growSpan(id, obj) } return err }
func TestIssue16902(t *testing.T) { const src = ` package a import "unsafe" const _ = unsafe.Offsetof(struct{ x int64 }{}.x) ` fset := token.NewFileSet() f, err := parser.ParseFile(fset, "x.go", src, 0) if err != nil { t.Fatal(err) } info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)} conf := types.Config{ Importer: importer.Default(), Sizes: &types.StdSizes{WordSize: 8, MaxAlign: 8}, } _, err = conf.Check("x", fset, []*ast.File{f}, &info) if err != nil { t.Fatal(err) } for _, tv := range info.Types { _ = conf.Sizes.Sizeof(tv.Type) _ = conf.Sizes.Alignof(tv.Type) } }
func parseFiles(path string) (*token.FileSet, *types.Package, types.Info, *ast.File) { fset := token.NewFileSet() files := []*ast.File{} for _, name := range []string{"server.go", "client.go"} { f, err := parser.ParseFile(fset, filepath.Join(path, name), nil, 0) if err != nil { log.Fatal(err) } files = append(files, f) } info := types.Info{ Types: make(map[ast.Expr]types.TypeAndValue), Defs: make(map[*ast.Ident]types.Object), Uses: make(map[*ast.Ident]types.Object), } var conf types.Config conf.Importer = importer.Default() pkg, err := conf.Check(path, fset, files, &info) if err != nil { log.Fatal(err) } return fset, pkg, info, files[1] }
// TestVeryLongFile tests the position of an import object declared in // a very long input file. Line numbers greater than maxlines are // reported as line 1, not garbage or token.NoPos. func TestVeryLongFile(t *testing.T) { // parse and typecheck longFile := "package foo" + strings.Repeat("\n", 123456) + "var X int" fset1 := token.NewFileSet() f, err := parser.ParseFile(fset1, "foo.go", longFile, 0) if err != nil { t.Fatal(err) } var conf types.Config pkg, err := conf.Check("foo", fset1, []*ast.File{f}, nil) if err != nil { t.Fatal(err) } // export exportdata := gcimporter.BExportData(fset1, pkg) // import imports := make(map[string]*types.Package) fset2 := token.NewFileSet() _, pkg2, err := gcimporter.BImportData(fset2, imports, exportdata, pkg.Path()) if err != nil { t.Fatalf("BImportData(%s): %v", pkg.Path(), err) } // compare posn1 := fset1.Position(pkg.Scope().Lookup("X").Pos()) posn2 := fset2.Position(pkg2.Scope().Lookup("X").Pos()) if want := "foo.go:1:1"; posn2.String() != want { t.Errorf("X position = %s, want %s (orig was %s)", posn2, want, posn1) } }
func main() { f, err := parser.ParseFile(fset, "hello.go", input, 0) if err != nil { log.Fatal(err) // parse error } conf := types.Config{Importer: importer.Default()} info := &types.Info{Types: make(map[ast.Expr]types.TypeAndValue)} if _, err := conf.Check("cmd/hello", fset, []*ast.File{f}, info); err != nil { log.Fatal(err) // type error } //!+inspect // f is a parsed, type-checked *ast.File. ast.Inspect(f, func(n ast.Node) bool { if expr, ok := n.(ast.Expr); ok { if tv, ok := info.Types[expr]; ok { fmt.Printf("%-24s\tmode: %s\n", nodeString(expr), mode(tv)) fmt.Printf("\t\t\t\ttype: %v\n", tv.Type) if tv.Value != nil { fmt.Printf("\t\t\t\tvalue: %v\n", tv.Value) } } } return true }) //!-inspect }
func main() { name := "testdata/import.go" var files []*ast.File fs := token.NewFileSet() file, err := parser.ParseFile(fs, name, nil, 0) if err != nil { log.Fatal(err) } files = append(files, file) config := types.Config{ Importer: importer.Default(), Error: func(error) {}, } info := &types.Info{ Selections: make(map[*ast.SelectorExpr]*types.Selection), Types: make(map[ast.Expr]types.TypeAndValue), Defs: make(map[*ast.Ident]types.Object), Uses: make(map[*ast.Ident]types.Object), } pkg, err := config.Check("testdata", fs, files, info) if err != nil { log.Fatal(err) } fmt.Println(pkg) }
func GetCurrentAppSettings(settings_path string)(settings map[string]string,err error){ fset := token.NewFileSet() f, err := parser.ParseFile(fset, default_settings_path, nil, 0) if err != nil { f, err = parser.ParseFile(fset, default_relative_settings_path, nil, 0) if err!=nil{ return nil,err } } conf := types.Config{Importer: importer.Default()} pkg, err := conf.Check("wapour/settings", fset, []*ast.File{f}, nil) if err != nil { return nil,err } settings=make(map[string]string,0) for word_id := range initial { word:=initial[word_id] existing_set:=pkg.Scope().Lookup(word).(*types.Const).Val().String() settings[word]=existing_set } return settings,err }
func checkPkgFiles(files []*ast.File) { compiler := "gc" if *gccgo { compiler = "gccgo" } type bailout struct{} conf := types.Config{ FakeImportC: true, Error: func(err error) { if !*allErrors && errorCount >= 10 { panic(bailout{}) } report(err) }, Importer: importer.For(compiler, nil), Sizes: sizes, } defer func() { switch p := recover().(type) { case nil, bailout: // normal return or early exit default: // re-panic panic(p) } }() const path = "pkg" // any non-empty string will do for now conf.Check(path, fset, files, nil) }
func typeCheck(t *testing.T, filename string, gopath string) *types.Package { f, err := parser.ParseFile(fset, filename, nil, parser.AllErrors) if err != nil { t.Fatalf("%s: %v", filename, err) } pkgName := filepath.Base(filename) pkgName = strings.TrimSuffix(pkgName, ".go") // typecheck and collect typechecker errors var conf types.Config conf.Error = func(err error) { t.Error(err) } if gopath != "" { conf.Importer = importer.Default() oldDefault := build.Default defer func() { build.Default = oldDefault }() build.Default.GOPATH = gopath } pkg, err := conf.Check(pkgName, fset, []*ast.File{f}, nil) if err != nil { t.Fatal(err) } return pkg }
func main() { fset := token.NewFileSet() // Parse the input string, []byte, or io.Reader, // recording position information in fset. // ParseFile returns an *ast.File, a syntax tree. f, err := parser.ParseFile(fset, "hello.go", hello, 0) if err != nil { log.Fatal(err) // parse error } // A Config controls various options of the type checker. // The defaults work fine except for one setting: // we must specify how to deal with imports. conf := types.Config{Importer: importer.Default()} // Type-check the package containing only file f. // Check returns a *types.Package. pkg, err := conf.Check("cmd/hello", fset, []*ast.File{f}, nil) if err != nil { log.Fatal(err) // type error } fmt.Printf("Package %q\n", pkg.Path()) fmt.Printf("Name: %s\n", pkg.Name()) fmt.Printf("Imports: %s\n", pkg.Imports()) fmt.Printf("Scope: %s\n", pkg.Scope()) }
func getPackage(fset *token.FileSet, a *ast.Package, conf *Config) (*Package, *TypeCheckError) { // pull map into a slice var files []*ast.File for _, f := range a.Files { files = append(files, f) } config := types.Config{ DisableUnusedImportCheck: true, IgnoreFuncBodies: true, } if conf.IgnoreTypeCheckErrors { // no-op allows type checking to proceed in presence of errors // https://godoc.org/golang.org/x/tools/go/types#Config config.Error = func(err error) {} } typesPkg, err := config.Check(a.Name, fset, files, nil) p := &Package{typesPkg, fset, []Type{}} if err != nil { return p, &TypeCheckError{err, conf.IgnoreTypeCheckErrors} } return p, nil }
//Collect going through package and collect info //using conf.Check method. It's using this implementation //of importer for check all inner packages and go/types/importer.Default() //to check all built in packages (without sources) func (_importer *CollectInfoImporter) Collect() (*types.Package, *token.FileSet, error) { var conf types.Config conf.Importer = _importer conf.Error = _importer.errorHandler if _importer.packages == nil { _importer.packages = make(map[string]*types.Package) } var pkg *types.Package var err error var files []string if files, err = fs.SourceFiles(_importer.Pkg, false); err != nil { return nil, nil, err } if _importer.fset, _importer.astFiles, err = doParseFiles(files, _importer.fset); err != nil { return nil, nil, err } //XXX: return positive result if check() returns error. pkg, _ = conf.Check(_importer.Pkg, _importer.fset, _importer.astFiles, _importer.Info) // if pkg, err = conf.Check(_importer.Pkg, _importer.fset, _importer.astFiles, _importer.Info); err != nil { // return pkg, _importer.fset, err // } _importer.packages[_importer.Pkg] = pkg util.Debug("package [%s] successfully parsed\n", pkg.Name()) return pkg, _importer.fset, nil }
//!+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") } } }
func (gas *Analyzer) process(filename string, source interface{}) error { mode := parser.ParseComments root, err := parser.ParseFile(gas.context.FileSet, filename, source, mode) if err == nil { gas.context.Comments = ast.NewCommentMap(gas.context.FileSet, root, root.Comments) gas.context.Root = root // here we get type info gas.context.Info = &types.Info{ Types: make(map[ast.Expr]types.TypeAndValue), Defs: make(map[*ast.Ident]types.Object), Uses: make(map[*ast.Ident]types.Object), Selections: make(map[*ast.SelectorExpr]*types.Selection), Scopes: make(map[ast.Node]*types.Scope), Implicits: make(map[ast.Node]types.Object), } conf := types.Config{Importer: importer.Default()} gas.context.Pkg, _ = conf.Check("pkg", gas.context.FileSet, []*ast.File{root}, gas.context.Info) if err != nil { gas.logger.Println("failed to check imports") return err } ast.Walk(gas, root) gas.Stats.NumFiles++ } return err }
// typeCheckPackage will attempt to return the package even if there are some // errors, so you may check whether the package is nil or not even if you get // an error. func (b *Builder) typeCheckPackage(id string) (*tc.Package, error) { if pkg, ok := b.pkgs[id]; ok { if pkg != nil { return pkg, nil } // We store a nil right before starting work on a package. So // if we get here and it's present and nil, that means there's // another invocation of this function on the call stack // already processing this package. return nil, fmt.Errorf("circular dependency for %q", id) } parsedFiles, ok := b.parsed[id] if !ok { return nil, fmt.Errorf("No files for pkg %q: %#v", id, b.parsed) } files := make([]*ast.File, len(parsedFiles)) for i := range parsedFiles { files[i] = parsedFiles[i].file } b.pkgs[id] = nil c := tc.Config{ IgnoreFuncBodies: true, // Note that importAdater can call b.import which calls this // method. So there can't be cycles in the import graph. Importer: importAdapter{b}, Error: func(err error) { glog.V(2).Infof("type checker error: %v\n", err) }, } pkg, err := c.Check(id, b.fset, files, nil) b.pkgs[id] = pkg // record the result whether or not there was an error return pkg, err }
func TestDependencies(t *testing.T) { packages := make(map[string]*types.Package) conf := types.Config{ Importer: closure(packages), } fset := token.NewFileSet() // All edges go to the right. // /--D--B--A // F \_C_/ // \__E_/ for i, content := range []string{ `package a`, `package c; import (_ "a")`, `package b; import (_ "a")`, `package e; import (_ "c")`, `package d; import (_ "b"; _ "c")`, `package f; import (_ "d"; _ "e")`, } { f, err := parser.ParseFile(fset, fmt.Sprintf("%d.go", i), content, 0) if err != nil { t.Fatal(err) } pkg, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) if err != nil { t.Fatal(err) } packages[pkg.Path()] = pkg } for _, test := range []struct { roots, want string }{ {"a", "a"}, {"b", "ab"}, {"c", "ac"}, {"d", "abcd"}, {"e", "ace"}, {"f", "abcdef"}, {"be", "abce"}, {"eb", "aceb"}, {"de", "abcde"}, {"ed", "acebd"}, {"ef", "acebdf"}, } { var pkgs []*types.Package for _, r := range test.roots { pkgs = append(pkgs, packages[string(r)]) } var got string for _, p := range typeutil.Dependencies(pkgs...) { got += p.Path() } if got != test.want { t.Errorf("Dependencies(%q) = %q, want %q", test.roots, got, test.want) } } }
func importSrcPkg(cfg *types.Config, path string) (*types.Package, error) { fns, _ := pkgFiles(path) var fs []*ast.File for _, fn := range fns { f := parseFile(fn, nil) fs = append(fs, f) } return cfg.Check(path, fset, fs, nil) }
// check type-checks the package. The package must be OK to proceed. func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) { pkg.defs = make(map[*ast.Ident]types.Object) config := types.Config{Importer: importer.Default(), FakeImportC: true} info := &types.Info{ Defs: pkg.defs, } typesPkg, err := config.Check(pkg.dir, fs, astFiles, info) if err != nil { log.Fatalf("checking package: %s", err) } pkg.typesPkg = typesPkg }
// check type-checks the package. The package must be OK to proceed. func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error { pkg.defs = make(map[*ast.Ident]types.Object) config := types.Config{FakeImportC: true} info := &types.Info{ Defs: pkg.defs, } typesPkg, err := config.Check(pkg.dir, fs, astFiles, info) if err != nil { return err } pkg.typesPkg = typesPkg return nil }
func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error { pkg.defs = make(map[*ast.Ident]types.Object) config := types.Config{Importer: importer.Default(), FakeImportC: true} info := &types.Info{ Defs: pkg.defs, } _, err := config.Check(pkg.dir, fs, astFiles, info) if err != nil { return fmt.Errorf("Failed to type check package: %v", err) } return nil }
func typesPackage(source string) (*types.Package, error) { fset := token.NewFileSet() file, err := parser.ParseFile(fset, "x.go", source, parser.ParseComments) if err != nil { return nil, err } conf := types.Config{ IgnoreFuncBodies: true, Error: func(err error) { log.Println(err) }, } return conf.Check("TEST", fset, []*ast.File{file}, nil) }
func main() { var pkg = flag.String("pkg", "", "help message for flagname") var dir = flag.String("dir", "", "help message for dir") var out = flag.String("o", "", "help message for out") flag.Parse() var pkgName = *pkg var absDirPath = *dir if !filepath.IsAbs(absDirPath) { absDirPath = filepath.Join(os.Getenv("PWD"), absDirPath) } fset := token.NewFileSet() pkgs, err := parser.ParseDir(fset, absDirPath, nil, parser.ParseComments|parser.AllErrors) info := types.Info{ Types: make(map[ast.Expr]types.TypeAndValue), Defs: make(map[*ast.Ident]types.Object), Uses: make(map[*ast.Ident]types.Object), } var conf types.Config conf.Importer = importer.Default() files := make([]*ast.File, 0, len(pkgs[pkgName].Files)) for _, file := range pkgs[pkgName].Files { files = append(files, file) } _, err = conf.Check(pkgName, fset, files, &info) if err != nil { fmt.Println("checked", err) return } b := builder{} for _, astFile := range pkgs[pkgName].Files { err = b.extractString(astFile, &info, fset) if err != nil { fmt.Println(err) } } err = b.write(*out) if err != nil { fmt.Errorf("got error during write (%v)\n", err) } }
// check type-checks the package. The package must be OK to proceed. func (f *File) Check() { // TODO typs := make(map[ast.Expr]types.TypeAndValue) defs := make(map[*ast.Ident]types.Object) uses := make(map[*ast.Ident]types.Object) config := types.Config{FakeImportC: true} config.Importer = importer.Default() info := &types.Info{Types: typs, Defs: defs, Uses: uses} astFiles := []*ast.File{f.ast} typesPkg, err := config.Check(fileDir(f), f.fs, astFiles, info) if err != nil { log.Fatalf("checking package: %s", err) } f.Info = info f.Pkg = typesPkg }
func TestIntuitiveMethodSet(t *testing.T) { const source = ` package P type A int func (A) f() func (*A) g() ` fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hello.go", source, 0) if err != nil { t.Fatal(err) } var conf types.Config pkg, err := conf.Check("P", fset, []*ast.File{f}, nil) if err != nil { t.Fatal(err) } qual := types.RelativeTo(pkg) for _, test := range []struct { expr string // type expression want string // intuitive method set }{ {"A", "(A).f (*A).g"}, {"*A", "(*A).f (*A).g"}, {"error", "(error).Error"}, {"*error", ""}, {"struct{A}", "(struct{A}).f (*struct{A}).g"}, {"*struct{A}", "(*struct{A}).f (*struct{A}).g"}, } { tv, err := types.Eval(fset, pkg, 0, test.expr) if err != nil { t.Errorf("Eval(%s) failed: %v", test.expr, err) } var names []string for _, m := range typeutil.IntuitiveMethodSet(tv.Type, nil) { name := fmt.Sprintf("(%s).%s", types.TypeString(m.Recv(), qual), m.Obj().Name()) names = append(names, name) } got := strings.Join(names, " ") if got != test.want { t.Errorf("IntuitiveMethodSet(%s) = %q, want %q", test.expr, got, test.want) } } }
func (imp myImporter) Import(importPath string) (*types.Package, error) { if pkg, ok := imp.cache[importPath]; ok { return pkg, nil } pkgMeta, err := imp.buildCtx.Import(importPath, ".", 0) if err != nil { return nil, fmt.Errorf("cannot locate package: %v", err) } filter := func(fi os.FileInfo) bool { base := filepath.Base(fi.Name()) for _, name := range pkgMeta.GoFiles { if name == base { return true } } for _, name := range pkgMeta.CgoFiles { if name == base { return true } } return false } pkgs, err := parser.ParseDir(imp.fset, pkgMeta.Dir, filter, 0) if err != nil { return nil, fmt.Errorf("cannot parse package: %v", err) } pkgAST, ok := pkgs[pkgMeta.Name] if !ok { return nil, fmt.Errorf("package not found: no %q in %s", pkgMeta.Name, pkgMeta.Dir) } conf := types.Config{ IgnoreFuncBodies: true, FakeImportC: true, // TODO maybe set Error here, to be more lenient? Importer: imp, DisableUnusedImportCheck: true, } pkg, err := conf.Check(importPath, imp.fset, astFiles(pkgAST), nil) if err != nil { return nil, fmt.Errorf("cannot type check package: %v", err) } imp.cache[importPath] = pkg return pkg, nil }
func (i *customImporter) fsPkg(pkg string) (*types.Package, error) { dir, err := gopathDir(pkg) if err != nil { return importOrErr(i.base, pkg, err) } dirFiles, err := ioutil.ReadDir(dir) if err != nil { return importOrErr(i.base, pkg, err) } fset := token.NewFileSet() var files []*ast.File for _, fileInfo := range dirFiles { if fileInfo.IsDir() { continue } n := fileInfo.Name() if path.Ext(fileInfo.Name()) != ".go" { continue } if i.skipTestFiles && strings.Contains(fileInfo.Name(), "_test.go") { continue } file := path.Join(dir, n) src, err := ioutil.ReadFile(file) if err != nil { return nil, err } f, err := parser.ParseFile(fset, file, src, 0) if err != nil { return nil, err } files = append(files, f) } conf := types.Config{ Importer: i, } p, err := conf.Check(pkg, fset, files, nil) if err != nil { return importOrErr(i.base, pkg, err) } return p, nil }
// ExampleNewImporter demonstrates usage of NewImporter to provide type // information for dependencies when type-checking Go source code. func ExampleNewImporter() { const src = `package twopi import "math" const TwoPi = 2 * math.Pi ` fset := token.NewFileSet() f, err := parser.ParseFile(fset, "twopi.go", src, 0) if err != nil { log.Fatal(err) } packages := make(map[string]*types.Package) imp := gcexportdata.NewImporter(fset, packages) conf := types.Config{Importer: imp} pkg, err := conf.Check("twopi", fset, []*ast.File{f}, nil) if err != nil { log.Fatal(err) } // object from imported package pi := packages["math"].Scope().Lookup("Pi") fmt.Printf("const %s.%s %s = %s // %s\n", pi.Pkg().Path(), pi.Name(), pi.Type(), pi.(*types.Const).Val(), slashify(fset.Position(pi.Pos()))) // object in source package twopi := pkg.Scope().Lookup("TwoPi") fmt.Printf("const %s %s = %s // %s\n", twopi.Name(), twopi.Type(), twopi.(*types.Const).Val(), slashify(fset.Position(twopi.Pos()))) // Output: // // const math.Pi untyped float = 3.14159 // $GOROOT/src/math/const.go:11:1 // const TwoPi untyped float = 6.28319 // twopi.go:5:7 }
// ExampleMethodSet prints the method sets of various types. func ExampleMethodSet() { // Parse a single source file. const input = ` package temperature import "fmt" type Celsius float64 func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) } func (c *Celsius) SetF(f float64) { *c = Celsius(f - 32 / 9 * 5) } ` fset := token.NewFileSet() f, err := parser.ParseFile(fset, "celsius.go", input, 0) if err != nil { log.Fatal(err) } // Type-check a package consisting of this file. // Type information for the imported packages // comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a. conf := types.Config{Importer: importer.Default()} pkg, err := conf.Check("temperature", fset, []*ast.File{f}, nil) if err != nil { log.Fatal(err) } // Print the method sets of Celsius and *Celsius. celsius := pkg.Scope().Lookup("Celsius").Type() for _, t := range []types.Type{celsius, types.NewPointer(celsius)} { fmt.Printf("Method set of %s:\n", t) mset := types.NewMethodSet(t) for i := 0; i < mset.Len(); i++ { fmt.Println(mset.At(i)) } fmt.Println() } // Output: // Method set of temperature.Celsius: // method (temperature.Celsius) String() string // // Method set of *temperature.Celsius: // method (*temperature.Celsius) SetF(f float64) // method (*temperature.Celsius) String() string }
// findStructType typechecks src and returns the first struct type encountered. func findStructType(t *testing.T, src string) *types.Struct { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "x.go", src, 0) if err != nil { t.Fatal(err) } info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)} var conf types.Config _, err = conf.Check("x", fset, []*ast.File{f}, &info) if err != nil { t.Fatal(err) } for _, tv := range info.Types { if ts, ok := tv.Type.(*types.Struct); ok { return ts } } t.Fatalf("failed to find a struct type in src:\n%s\n", src) return nil }
func typeCheck(t *testing.T, filename string) *types.Package { f, err := parser.ParseFile(fset, filename, nil, parser.AllErrors) if err != nil { t.Fatalf("%s: %v", filename, err) } pkgName := filepath.Base(filename) pkgName = strings.TrimSuffix(pkgName, ".go") // typecheck and collect typechecker errors var conf types.Config conf.Error = func(err error) { t.Error(err) } pkg, err := conf.Check(pkgName, fset, []*ast.File{f}, nil) if err != nil { t.Fatal(err) } return pkg }