...

Source file src/golang.org/x/tools/internal/gcimporter/main.go

Documentation: golang.org/x/tools/internal/gcimporter

     1  // Copyright 2024 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  
     7  // The gcimporter command reads the compiler's export data for the
     8  // named packages and prints the decoded type information.
     9  //
    10  // It is provided for debugging export data problems.
    11  package main
    12  
    13  import (
    14  	"bytes"
    15  	"flag"
    16  	"fmt"
    17  	"go/token"
    18  	"go/types"
    19  	"log"
    20  	"os"
    21  	"sort"
    22  
    23  	"golang.org/x/tools/go/gcexportdata"
    24  	"golang.org/x/tools/go/packages"
    25  	"golang.org/x/tools/go/types/typeutil"
    26  	"golang.org/x/tools/internal/gcimporter"
    27  )
    28  
    29  func main() {
    30  	flag.Parse()
    31  	cfg := &packages.Config{
    32  		Fset: token.NewFileSet(),
    33  		// Don't request NeedTypes: we want to be certain that
    34  		// we loaded the types ourselves, from export data.
    35  		Mode: packages.NeedName | packages.NeedExportFile,
    36  	}
    37  	pkgs, err := packages.Load(cfg, flag.Args()...)
    38  	if err != nil {
    39  		log.Fatal(err)
    40  	}
    41  	if packages.PrintErrors(pkgs) > 0 {
    42  		os.Exit(1)
    43  	}
    44  
    45  	for _, pkg := range pkgs {
    46  		// Read types from compiler's unified export data file.
    47  		// This Package may included non-exported functions if they
    48  		// are called by inlinable exported functions.
    49  		var tpkg1 *types.Package
    50  		{
    51  			export, err := os.ReadFile(pkg.ExportFile)
    52  			if err != nil {
    53  				log.Fatalf("can't read %q export data: %v", pkg.PkgPath, err)
    54  			}
    55  			r, err := gcexportdata.NewReader(bytes.NewReader(export))
    56  			if err != nil {
    57  				log.Fatalf("reading export data %s: %v", pkg.ExportFile, err)
    58  			}
    59  			tpkg1, err = gcexportdata.Read(r, cfg.Fset, make(map[string]*types.Package), pkg.PkgPath)
    60  			if err != nil {
    61  				log.Fatalf("decoding export data: %v", err)
    62  			}
    63  		}
    64  		fmt.Println("# Read from compiler's unified export data:")
    65  		printPackage(tpkg1)
    66  
    67  		// Now reexport as indexed (deep) export data, and reimport.
    68  		// The Package will contain only exported symbols.
    69  		var tpkg2 *types.Package
    70  		{
    71  			var out bytes.Buffer
    72  			if err := gcimporter.IExportData(&out, cfg.Fset, tpkg1); err != nil {
    73  				log.Fatal(err)
    74  			}
    75  			var err error
    76  			_, tpkg2, err = gcimporter.IImportData(cfg.Fset, make(map[string]*types.Package), out.Bytes(), tpkg1.Path())
    77  			if err != nil {
    78  				log.Fatal(err)
    79  			}
    80  		}
    81  		fmt.Println("# After round-tripping through indexed export data:")
    82  		printPackage(tpkg2)
    83  	}
    84  }
    85  
    86  func printPackage(pkg *types.Package) {
    87  	fmt.Printf("package %s %q\n", pkg.Name(), pkg.Path())
    88  
    89  	if !pkg.Complete() {
    90  		fmt.Printf("\thas incomplete exported type info\n")
    91  	}
    92  
    93  	// imports
    94  	var lines []string
    95  	for _, imp := range pkg.Imports() {
    96  		lines = append(lines, fmt.Sprintf("\timport %q", imp.Path()))
    97  	}
    98  	sort.Strings(lines)
    99  	for _, line := range lines {
   100  		fmt.Println(line)
   101  	}
   102  
   103  	// types of package members
   104  	qual := types.RelativeTo(pkg)
   105  	scope := pkg.Scope()
   106  	for _, name := range scope.Names() {
   107  		obj := scope.Lookup(name)
   108  		fmt.Printf("\t%s\n", types.ObjectString(obj, qual))
   109  		if _, ok := obj.(*types.TypeName); ok {
   110  			for _, meth := range typeutil.IntuitiveMethodSet(obj.Type(), nil) {
   111  				fmt.Printf("\t%s\n", types.SelectionString(meth, qual))
   112  			}
   113  		}
   114  	}
   115  
   116  	fmt.Println()
   117  }
   118  

View as plain text