Source file src/cmd/compile/internal/importer/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 implements the Import function for tests to use gc-generated object files.
     6  
     7  package importer
     8  
     9  import (
    10  	"bufio"
    11  	"fmt"
    12  	"internal/exportdata"
    13  	"internal/pkgbits"
    14  	"io"
    15  	"os"
    16  
    17  	"cmd/compile/internal/types2"
    18  )
    19  
    20  // Import imports a gc-generated package given its import path and srcDir, adds
    21  // the corresponding package object to the packages map, and returns the object.
    22  // The packages map must contain all packages already imported.
    23  //
    24  // This function should only be used in tests.
    25  func Import(packages map[string]*types2.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types2.Package, err error) {
    26  	var rc io.ReadCloser
    27  	var id string
    28  	if lookup != nil {
    29  		// With custom lookup specified, assume that caller has
    30  		// converted path to a canonical import path for use in the map.
    31  		if path == "unsafe" {
    32  			return types2.Unsafe, nil
    33  		}
    34  		id = path
    35  
    36  		// No need to re-import if the package was imported completely before.
    37  		if pkg = packages[id]; pkg != nil && pkg.Complete() {
    38  			return
    39  		}
    40  		f, err := lookup(path)
    41  		if err != nil {
    42  			return nil, err
    43  		}
    44  		rc = f
    45  	} else {
    46  		var filename string
    47  		filename, id, err = exportdata.FindPkg(path, srcDir)
    48  		if filename == "" {
    49  			if path == "unsafe" {
    50  				return types2.Unsafe, nil
    51  			}
    52  			return nil, err
    53  		}
    54  
    55  		// no need to re-import if the package was imported completely before
    56  		if pkg = packages[id]; pkg != nil && pkg.Complete() {
    57  			return
    58  		}
    59  
    60  		// open file
    61  		f, err := os.Open(filename)
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  		defer func() {
    66  			if err != nil {
    67  				// add file name to error
    68  				err = fmt.Errorf("%s: %v", filename, err)
    69  			}
    70  		}()
    71  		rc = f
    72  	}
    73  	defer rc.Close()
    74  
    75  	buf := bufio.NewReader(rc)
    76  	data, err := exportdata.ReadUnified(buf)
    77  	if err != nil {
    78  		err = fmt.Errorf("import %q: %v", path, err)
    79  		return
    80  	}
    81  	s := string(data)
    82  
    83  	input := pkgbits.NewPkgDecoder(id, s)
    84  	pkg = ReadPackage(nil, packages, input)
    85  
    86  	return
    87  }
    88  

View as plain text