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 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() { flag.Parse() if *lang != "java" && *javaPkg != "" { log.Fatalf("Invalid option -javapkg for gobind -lang=%s", *lang) } else if *lang != "objc" && *prefix != "" { log.Fatalf("Invalid option -prefix for gobind -lang=%s", *lang) } // Make sure the export data for the packages being compiled is up to // date. Also use the go tool to provide good error messages for any // type checking errors in the provided packages. cmd := exec.Command("go", "install") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Args = append(cmd.Args, flag.Args()...) if err := cmd.Run(); err != nil { fmt.Fprintf(os.Stderr, "%s failed: %v", strings.Join(cmd.Args, " "), err) os.Exit(1) } for _, arg := range flag.Args() { pkg, err := importer.Default().Import(arg) if err != nil { fmt.Fprintf(os.Stderr, "could not import package %s: %v", arg, err) os.Exit(1) } genPkg(pkg) } os.Exit(exitStatus) }
func TestImportBug(t *testing.T) { buildPkg, err := build.Import("github.com/netbrain/importbug/foo", "", build.ImportComment) if err != nil { t.Fatal(err) } fset := token.NewFileSet() packages, err := parser.ParseDir(fset, buildPkg.Dir, nil, 0) if err != nil { t.Fatal(err) } info := &types.Info{ Defs: make(map[*ast.Ident]types.Object), } for pName, p := range packages { files := make([]*ast.File, 0, len(p.Files)) for _, f := range p.Files { files = append(files, f) } conf := &types.Config{ FakeImportC: true, Importer: importer.Default(), } _, err := conf.Check(pName, fset, files, info) if err != nil { log.Fatal(err) } } }
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, Importer: importer.Default(), } 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 }
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 }
// ImportFrom implements the go/types.ImporterFrom interface func (i imp) ImportFrom(pkgpath, srcDir string, mode types.ImportMode) (*types.Package, error) { pkg, has := i.cache[pkgpath] if has { return pkg, nil } if pkgpath == "runtime" { pkg, err := importer.Default().(types.ImporterFrom).ImportFrom(pkgpath, srcDir, mode) i.cache[pkgpath] = pkg // cache even if pkg == nil and err != nil to prevent never ending loops return pkg, err } buildPkg, err := build.Import(pkgpath, srcDir, build.AllowBinary) if err != nil { return nil, err } var ( fset = token.NewFileSet() astFiles []*ast.File ) astFiles, err = ParseAstFiles(fset, buildPkg.Dir, append(buildPkg.GoFiles, buildPkg.CgoFiles...)) if err != nil { return nil, err } pkg, err = i.checkfn(buildPkg.ImportPath, fset, astFiles) i.cache[pkgpath] = pkg // cache even if pkg == nil and err != nil to prevent never ending loops return pkg, err }
//!+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 TestHilbert(t *testing.T) { t.Skip("skipping for gccgo--no importer") // generate source src := program(*H, *out) if *out != "" { ioutil.WriteFile(*out, src, 0666) return } // parse source fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hilbert.go", src, 0) if err != nil { t.Fatal(err) } // type-check file DefPredeclaredTestFuncs() // define assert built-in conf := Config{Importer: importer.Default()} _, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) if err != nil { t.Fatal(err) } }
func (imp *importer) newPackageInfo(path string) *PackageInfo { pkg := types.NewPackage(path, "") info := &PackageInfo{ Pkg: pkg, Info: types.Info{ Types: make(map[ast.Expr]types.TypeAndValue), Defs: make(map[*ast.Ident]types.Object), Uses: make(map[*ast.Ident]types.Object), Implicits: make(map[ast.Node]types.Object), Scopes: make(map[ast.Node]*types.Scope), Selections: make(map[*ast.SelectorExpr]*types.Selection), }, errorFunc: imp.conf.TypeChecker.Error, } // Copy the types.Config so we can vary it across PackageInfos. tc := imp.conf.TypeChecker tc.IgnoreFuncBodies = false if f := imp.conf.TypeCheckFuncBodies; f != nil { tc.IgnoreFuncBodies = !f(path) } tc.Importer = goimporter.Default() tc.Error = info.appendError // appendError wraps the user's Error function info.checker = types.NewChecker(&tc, imp.conf.fset(), pkg, &info.Info) imp.progMu.Lock() imp.prog.AllPackages[pkg] = info imp.progMu.Unlock() return info }
// DefaultWithTestFiles same as Default but it parses test files too func DefaultWithTestFiles() types.Importer { return &customImporter{ imported: make(map[string]*types.Package), base: importer.Default(), skipTestFiles: false, } }
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] }
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 }
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 GetPackageObjects(pkgName string) (objs []Object, err error) { pkg, err := importer.Default().Import(pkgName) if err != nil { return objs, err } for _, n := range pkg.Scope().Names() { obj := pkg.Scope().Lookup(n) if obj.Exported() { switch obj.(type) { case *types.Func: f := obj.(*types.Func) t := encodeType(f.Type()) if err == nil { objs = append(objs, Object{f.Name(), "func", t}) } case *types.Var: v := obj.(*types.Var) t := encodeType(v.Type()) if err == nil { objs = append(objs, Object{v.Name(), "var", t}) } case *types.Const: c := obj.(*types.Const) t := encodeType(c.Type()) if err == nil { objs = append(objs, Object{c.Name(), "const", t}) } } } } return objs, 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 testRegress(t *testing.T, s *suggest.Suggester, testDir string) bool { testDir, err := filepath.Abs(testDir) if err != nil { t.Errorf("Abs failed: %v", err) return false } filename := filepath.Join(testDir, "test.go.in") data, err := ioutil.ReadFile(filename) if err != nil { t.Errorf("ReadFile failed: %v", err) return false } cursor := bytes.IndexByte(data, '@') if cursor < 0 { t.Errorf("Missing @") return false } data = append(data[:cursor], data[cursor+1:]...) candidates, prefixLen := s.Suggest(importer.Default(), filename, data, cursor) var out bytes.Buffer suggest.NiceFormat(&out, candidates, prefixLen) want, err := ioutil.ReadFile(filepath.Join(testDir, "out.expected")) if got := out.Bytes(); !bytes.Equal(got, want) { t.Errorf("%s:\nGot:\n%s\nWant:\n%s\n", testDir, got, want) return false } return true }
func (p *Parser) Parse(path string) error { dir := filepath.Dir(path) files, err := ioutil.ReadDir(dir) if err != nil { fmt.Printf("// [ERROR] Parse(%s) -> ioutil.ReadDir(%#v) -> err=<%#v>\n", path, dir, err) return err } var astFiles []*ast.File var conf loader.Config conf.TypeCheckFuncBodies = func(_ string) bool { return false } conf.TypeChecker.DisableUnusedImportCheck = true conf.TypeChecker.Importer = importer.Default() for _, fi := range files { if filepath.Ext(fi.Name()) != ".go" { continue } fpath := filepath.Join(dir, fi.Name()) f, err := conf.ParseFile(fpath, nil) if err != nil { fmt.Printf("// [ERROR] Parse(%s) -> conf.ParseFile(%#v) -> err=<%#v>\n", path, fpath, err) return err } if fi.Name() == filepath.Base(path) { p.file = f } astFiles = append(astFiles, f) } abs, err := filepath.Abs(path) if err != nil { fmt.Printf("// [ERROR] Parse(%s) -> filepath.Abs(%#v) -> err=<%#v>\n", path, path, err) return err } // Type-check a package consisting of this file. // Type information for the imported packages // comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a. conf.CreateFromFiles(abs, astFiles...) prog, err := conf.Load() if err != nil { fmt.Printf("// [ERROR] Parse(%s) -> conf.Load() -> err=<%#v>\n", path, err) return err } else if len(prog.Created) != 1 { panic("expected only one Created package") } p.path = abs p.pkg = prog.Created[0].Pkg return nil }
func newSrcImporter() srcImporter { return srcImporter{ cfg: types.Config{ Importer: importer.Default(), Error: func(err error) {}, DisableUnusedImportCheck: true, }, } }
func makePkg(t *testing.T, src string) (*Package, error) { fset := token.NewFileSet() file, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors) if err != nil { return nil, err } // use the package name as package path conf := Config{Importer: importer.Default()} return conf.Check(file.Name.Name, fset, []*ast.File{file}, nil) }
func main() { pkg, err := importer.Default().Import("time") if err != nil { fmt.Printf("error: %s\n", err.Error()) return } for _, declName := range pkg.Scope().Names() { fmt.Println(declName) } }
func pkgFor(path, source string, info *Info) (*Package, error) { fset := token.NewFileSet() f, err := parser.ParseFile(fset, path, source, 0) if err != nil { return nil, err } conf := Config{Importer: importer.Default()} return conf.Check(f.Name.Name, fset, []*ast.File{f}, info) }
func checkFiles(t *testing.T, testfiles []string) { // parse files and collect parser errors files, errlist := parseFiles(t, testfiles) pkgName := "<no package>" if len(files) > 0 { pkgName = files[0].Name.Name } if *listErrors && len(errlist) > 0 { t.Errorf("--- %s:", pkgName) for _, err := range errlist { t.Error(err) } } // typecheck and collect typechecker errors var conf Config // special case for importC.src if len(testfiles) == 1 && testfiles[0] == "testdata/importC.src" { conf.FakeImportC = true } conf.Importer = importer.Default() conf.Error = func(err error) { if *listErrors { t.Error(err) return } // Ignore secondary error messages starting with "\t"; // they are clarifying messages for a primary error. if !strings.Contains(err.Error(), ": \t") { errlist = append(errlist, err) } } conf.Check(pkgName, fset, files, nil) if *listErrors { return } // match and eliminate errors; // we are expecting the following errors errmap := errMap(t, pkgName, files) eliminate(t, errmap, errlist) // there should be no expected errors left if len(errmap) > 0 { t.Errorf("--- %s: %d source positions with expected (but not reported) errors:", pkgName, len(errmap)) for pos, list := range errmap { for _, rx := range list { t.Errorf("%s: %q", pos, rx) } } } }
func newHybridImporter(pkgInUse string) *hybridImporter { hi := &hybridImporter{ pkgInUse: pkgInUse, cfg: types.Config{ Importer: importer.Default(), Error: func(err error) {}, DisableUnusedImportCheck: true, }, } return hi }
// 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 }
func (imp *resolveTestImporter) Import(path string) (*Package, error) { if imp.importer == nil { imp.importer = importer.Default() imp.imported = make(map[string]bool) } pkg, err := imp.importer.Import(path) if err != nil { return nil, err } imp.imported[path] = true return pkg, nil }
func loadExportData(pkgs []*build.Package, env []string, args ...string) ([]*types.Package, error) { // Compile the package. This will produce good errors if the package // doesn't typecheck for some reason, and is a necessary step to // building the final output anyway. paths := make([]string, len(pkgs)) for i, p := range pkgs { paths[i] = p.ImportPath } if err := goInstall(paths, env, args...); err != nil { return nil, err } goos, goarch := getenv(env, "GOOS"), getenv(env, "GOARCH") // Assemble a fake GOPATH and trick go/importer into using it. // Ideally the importer package would let us provide this to // it somehow, but this works with what's in Go 1.5 today and // gives us access to the gcimporter package without us having // to make a copy of it. fakegopath := filepath.Join(tmpdir, "fakegopath") if err := removeAll(fakegopath); err != nil { return nil, err } if err := mkdir(filepath.Join(fakegopath, "pkg")); err != nil { return nil, err } typePkgs := make([]*types.Package, len(pkgs)) imp := importer.Default() for i, p := range pkgs { importPath := p.ImportPath src := filepath.Join(pkgdir(env), importPath+".a") dst := filepath.Join(fakegopath, "pkg/"+goos+"_"+goarch+"/"+importPath+".a") if err := copyFile(dst, src); err != nil { return nil, err } if buildN { typePkgs[i] = types.NewPackage(importPath, path.Base(importPath)) continue } oldDefault := build.Default build.Default = ctx // copy build.Default.GOARCH = goarch build.Default.GOPATH = fakegopath p, err := imp.Import(importPath) build.Default = oldDefault if err != nil { return nil, err } typePkgs[i] = p } return typePkgs, nil }
func TestIssue5770(t *testing.T) { src := `package p; type S struct{T}` f, err := parser.ParseFile(fset, "", src, 0) if err != nil { t.Fatal(err) } conf := Config{Importer: importer.Default()} _, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // do not crash want := "undeclared name: T" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("got: %v; want: %s", err, want) } }
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 }