github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/gcexportdata/main.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build ignore 6 // +build ignore 7 8 // The gcexportdata command is a diagnostic tool that displays the 9 // contents of gc export data files. 10 package main 11 12 import ( 13 "flag" 14 "fmt" 15 "go/token" 16 "go/types" 17 "log" 18 "os" 19 20 "github.com/powerman/golang-tools/go/gcexportdata" 21 "github.com/powerman/golang-tools/go/types/typeutil" 22 ) 23 24 var packageFlag = flag.String("package", "", "alternative package to print") 25 26 func main() { 27 log.SetPrefix("gcexportdata: ") 28 log.SetFlags(0) 29 flag.Usage = func() { 30 fmt.Fprintln(os.Stderr, "usage: gcexportdata [-package path] file.a") 31 } 32 flag.Parse() 33 if flag.NArg() != 1 { 34 flag.Usage() 35 os.Exit(2) 36 } 37 filename := flag.Args()[0] 38 39 f, err := os.Open(filename) 40 if err != nil { 41 log.Fatal(err) 42 } 43 44 r, err := gcexportdata.NewReader(f) 45 if err != nil { 46 log.Fatalf("%s: %s", filename, err) 47 } 48 49 // Decode the package. 50 const primary = "<primary>" 51 imports := make(map[string]*types.Package) 52 fset := token.NewFileSet() 53 pkg, err := gcexportdata.Read(r, fset, imports, primary) 54 if err != nil { 55 log.Fatalf("%s: %s", filename, err) 56 } 57 58 // Optionally select an indirectly mentioned package. 59 if *packageFlag != "" { 60 pkg = imports[*packageFlag] 61 if pkg == nil { 62 fmt.Fprintf(os.Stderr, "export data file %s does not mention %s; has:\n", 63 filename, *packageFlag) 64 for p := range imports { 65 if p != primary { 66 fmt.Fprintf(os.Stderr, "\t%s\n", p) 67 } 68 } 69 os.Exit(1) 70 } 71 } 72 73 // Print all package-level declarations, including non-exported ones. 74 fmt.Printf("package %s\n", pkg.Name()) 75 for _, imp := range pkg.Imports() { 76 fmt.Printf("import %q\n", imp.Path()) 77 } 78 qual := func(p *types.Package) string { 79 if pkg == p { 80 return "" 81 } 82 return p.Name() 83 } 84 scope := pkg.Scope() 85 for _, name := range scope.Names() { 86 obj := scope.Lookup(name) 87 fmt.Printf("%s: %s\n", 88 fset.Position(obj.Pos()), 89 types.ObjectString(obj, qual)) 90 91 // For types, print each method. 92 if _, ok := obj.(*types.TypeName); ok { 93 for _, method := range typeutil.IntuitiveMethodSet(obj.Type(), nil) { 94 fmt.Printf("%s: %s\n", 95 fset.Position(method.Obj().Pos()), 96 types.SelectionString(method, qual)) 97 } 98 } 99 } 100 }