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  }