func Generate(prog *loader.Program, getFileBytes func(string) ([]byte, error), writerFor func(importPath, filename string) io.WriteCloser) { for _, pkgInfo := range prog.InitialPackages() { defs = pkgInfo.Defs _types = pkgInfo.Types pkg = pkgInfo.Pkg path := pkg.Path() if !pkgInfo.Importable && strings.HasSuffix(pkgInfo.Pkg.Name(), "_test") { // EXTERNAL TEST package, strip the _test to find the path path = strings.TrimSuffix(pkg.Path(), "_test") } idents.pkgScope = generatePackageScopeIdent(pkgInfo) for i, f := range pkgInfo.Files { fs = prog.Fset fname := fs.Position(f.Pos()).Filename if strings.HasSuffix(fname, "/C") { continue } b, err := getFileBytes(fname) if err != nil { fmt.Fprint(os.Stderr, "Error reading file:", err) os.Exit(1) } b = normalizeCRLF(b) quotedContents := rawQuote(string(b)) ast1, fs1 := parseCgoFile(fname, b) if ast1 != nil { f = ast1 fs = fs1 } generateGodebugIdentifiers(f) ast.Walk(&visitor{context: f, scopeVar: idents.fileScope}, f) importName := idents.godebug if importName == "godebug" { importName = "" } astutil.AddNamedImport(fs, f, importName, "github.com/mailgun/godebug/lib") cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8} out := writerFor(path, fname) defer out.Close() _ = cfg.Fprint(out, fs, f) fmt.Fprintln(out, "\nvar", idents.fileContents, "=", quotedContents) if i == 0 { err := generatePackageFile(idents.pkgScope, pkgInfo, out) if err != nil { fmt.Fprint(os.Stderr, "Error writing package file:", err) os.Exit(1) } } } } }
func checkForUnusedBreakpoints(subcommand string, prog *loader.Program, stdLib map[string]bool) { initialPkgs := make(map[*loader.PackageInfo]bool) for _, pkg := range prog.InitialPackages() { initialPkgs[pkg] = true } // For now we'll look at all of the non-stdlib-source files. // As an optimization, we could just look at files that have been changed. for _, pkg := range prog.AllPackages { if stdLib[pkg.String()] || initialPkgs[pkg] { continue } for _, f := range pkg.Files { ast.Inspect(f, func(node ast.Node) bool { if gen.IsBreakpoint(node) { pos := prog.Fset.Position(node.Pos()) fmt.Printf("godebug %s: Ignoring breakpoint at %s:%d because package %q has not been flagged for instrumentation. See 'godebug help %s'.\n\n", subcommand, filepath.Join(pkg.String(), filepath.Base(pos.Filename)), pos.Line, pkg.Pkg.Name(), subcommand) } return true }) } } }