// Copyright 2011 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.

// Package gcimporter implements Import for gc-generated object files.
package gcimporter // import "go/internal/gcimporter" import ( ) // debugging/development support const debug = false var pkgExts = [...]string{".a", ".o"} // FindPkg returns the filename and unique package id for an import // path based on package information provided by build.Import (using // the build.Default build.Context). A relative srcDir is interpreted // relative to the current working directory. // If no file was found, an empty filename is returned. // func (, string) (, string) { if == "" { return } var string switch { default: // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" // Don't require the source files to be present. if , := filepath.Abs(); == nil { // see issue 14282 = } , := build.Import(, , build.FindOnly|build.AllowBinary) if .PkgObj == "" { = // make sure we have an id to print in error message return } = strings.TrimSuffix(.PkgObj, ".a") = .ImportPath case build.IsLocalImport(): // "./x" -> "/this/directory/x.ext", "/this/directory/x" = filepath.Join(, ) = case filepath.IsAbs(): // for completeness only - go/build.Import // does not support absolute imports // "/x" -> "/x.ext", "/x" = = } if false { // for debugging if != { fmt.Printf("%s -> %s\n", , ) } } // try extensions for , := range pkgExts { = + if , := os.Stat(); == nil && !.IsDir() { return } } = "" // not found return } // Import imports a gc-generated package given its import path and srcDir, adds // the corresponding package object to the packages map, and returns the object. // The packages map must contain all packages already imported. // func ( *token.FileSet, map[string]*types.Package, , string, func( string) (io.ReadCloser, error)) ( *types.Package, error) { var io.ReadCloser var string if != nil { // With custom lookup specified, assume that caller has // converted path to a canonical import path for use in the map. if == "unsafe" { return types.Unsafe, nil } = // No need to re-import if the package was imported completely before. if = []; != nil && .Complete() { return } , := () if != nil { return nil, } = } else { var string , = FindPkg(, ) if == "" { if == "unsafe" { return types.Unsafe, nil } return nil, fmt.Errorf("can't find import: %q", ) } // no need to re-import if the package was imported completely before if = []; != nil && .Complete() { return } // open file , := os.Open() if != nil { return nil, } defer func() { if != nil { // add file name to error = fmt.Errorf("%s: %v", , ) } }() = } defer .Close() var string := bufio.NewReader() if , = FindExportData(); != nil { return } switch { case "$$\n": = fmt.Errorf("import %q: old textual export format no longer supported (recompile library)", ) case "$$B\n": var []byte , = io.ReadAll() if != nil { break } // The indexed export format starts with an 'i'; the older // binary export format starts with a 'c', 'd', or 'v' // (from "version"). Select appropriate importer. if len() > 0 && [0] == 'i' { _, , = iImportData(, , [1:], ) } else { = fmt.Errorf("import %q: old binary export format no longer supported (recompile library)", ) } default: = fmt.Errorf("import %q: unknown export data header: %q", , ) } return } type byPath []*types.Package func ( byPath) () int { return len() } func ( byPath) (, int) { [], [] = [], [] } func ( byPath) (, int) bool { return [].Path() < [].Path() }