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

     1  // Copyright 2011 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  // This file is a reduced copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go.
     6  
     7  // Package gcimporter provides various functions for reading
     8  // gc-generated object files that can be used to implement the
     9  // Importer interface defined by the Go 1.5 standard library package.
    10  //
    11  // The encoding is deterministic: if the encoder is applied twice to
    12  // the same types.Package data structure, both encodings are equal.
    13  // This property may be important to avoid spurious changes in
    14  // applications such as build systems.
    15  //
    16  // However, the encoder is not necessarily idempotent. Importing an
    17  // exported package may yield a types.Package that, while it
    18  // represents the same set of Go types as the original, may differ in
    19  // the details of its internal representation. Because of these
    20  // differences, re-encoding the imported package may yield a
    21  // different, but equally valid, encoding of the package.
    22  package gcimporter // import "golang.org/x/tools/internal/gcimporter"
    23  
    24  import (
    25  	"bufio"
    26  	"fmt"
    27  	"go/token"
    28  	"go/types"
    29  	"io"
    30  	"os"
    31  )
    32  
    33  const (
    34  	// Enable debug during development: it adds some additional checks, and
    35  	// prevents errors from being recovered.
    36  	debug = false
    37  
    38  	// If trace is set, debugging output is printed to std out.
    39  	trace = false
    40  )
    41  
    42  // Import imports a gc-generated package given its import path and srcDir, adds
    43  // the corresponding package object to the packages map, and returns the object.
    44  // The packages map must contain all packages already imported.
    45  //
    46  // Import is only used in tests.
    47  func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
    48  	var rc io.ReadCloser
    49  	var id string
    50  	if lookup != nil {
    51  		// With custom lookup specified, assume that caller has
    52  		// converted path to a canonical import path for use in the map.
    53  		if path == "unsafe" {
    54  			return types.Unsafe, nil
    55  		}
    56  		id = path
    57  
    58  		// No need to re-import if the package was imported completely before.
    59  		if pkg = packages[id]; pkg != nil && pkg.Complete() {
    60  			return
    61  		}
    62  		f, err := lookup(path)
    63  		if err != nil {
    64  			return nil, err
    65  		}
    66  		rc = f
    67  	} else {
    68  		var filename string
    69  		filename, id, err = FindPkg(path, srcDir)
    70  		if filename == "" {
    71  			if path == "unsafe" {
    72  				return types.Unsafe, nil
    73  			}
    74  			return nil, err
    75  		}
    76  
    77  		// no need to re-import if the package was imported completely before
    78  		if pkg = packages[id]; pkg != nil && pkg.Complete() {
    79  			return
    80  		}
    81  
    82  		// open file
    83  		f, err := os.Open(filename)
    84  		if err != nil {
    85  			return nil, err
    86  		}
    87  		defer func() {
    88  			if err != nil {
    89  				// add file name to error
    90  				err = fmt.Errorf("%s: %v", filename, err)
    91  			}
    92  		}()
    93  		rc = f
    94  	}
    95  	defer rc.Close()
    96  
    97  	buf := bufio.NewReader(rc)
    98  	data, err := ReadUnified(buf)
    99  	if err != nil {
   100  		err = fmt.Errorf("import %q: %v", path, err)
   101  		return
   102  	}
   103  
   104  	// unified: emitted by cmd/compile since go1.20.
   105  	_, pkg, err = UImportData(fset, packages, data, id)
   106  
   107  	return
   108  }
   109  

View as plain text