// Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // +build ignore // The gcexportdata command is a diagnostic tool that displays the // contents of gc export data files. package main import ( "flag" "fmt" "go/token" "go/types" "log" "os" "golang.org/x/tools/go/gcexportdata" "golang.org/x/tools/go/types/typeutil" ) var packageFlag = flag.String("package", "", "alternative package to print") func main() { log.SetPrefix("gcexportdata: ") log.SetFlags(0) flag.Usage = func() { fmt.Fprintln(os.Stderr, "usage: gcexportdata [-package path] file.a") } flag.Parse() if flag.NArg() != 1 { flag.Usage() os.Exit(2) } filename := flag.Args()[0] f, err := os.Open(filename) if err != nil { log.Fatal(err) } r, err := gcexportdata.NewReader(f) if err != nil { log.Fatalf("%s: %s", filename, err) } // Decode the package. const primary = "" imports := make(map[string]*types.Package) fset := token.NewFileSet() pkg, err := gcexportdata.Read(r, fset, imports, primary) if err != nil { log.Fatalf("%s: %s", filename, err) } // Optionally select an indirectly mentioned package. if *packageFlag != "" { pkg = imports[*packageFlag] if pkg == nil { fmt.Fprintf(os.Stderr, "export data file %s does not mention %s; has:\n", filename, *packageFlag) for p := range imports { if p != primary { fmt.Fprintf(os.Stderr, "\t%s\n", p) } } os.Exit(1) } } // Print all package-level declarations, including non-exported ones. fmt.Printf("package %s\n", pkg.Name()) for _, imp := range pkg.Imports() { fmt.Printf("import %q\n", imp.Path()) } qual := func(p *types.Package) string { if pkg == p { return "" } return p.Name() } scope := pkg.Scope() for _, name := range scope.Names() { obj := scope.Lookup(name) fmt.Printf("%s: %s\n", fset.Position(obj.Pos()), types.ObjectString(obj, qual)) // For types, print each method. if _, ok := obj.(*types.TypeName); ok { for _, method := range typeutil.IntuitiveMethodSet(obj.Type(), nil) { fmt.Printf("%s: %s\n", fset.Position(method.Obj().Pos()), types.SelectionString(method, qual)) } } } }