func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
	var rc io.ReadCloser
	var filename, id string
	if lookup != nil {
		if path == "unsafe" {
			return types.Unsafe, nil
		}
		id = path
		if pkg = packages[id]; pkg != nil && pkg.Complete() {
			return
		}
		f, err := lookup(path)
		if err != nil {
			return nil, err
		}
		rc = f
	} else {
		filename, id = FindPkg(path, srcDir)
		if filename == "" {
			if path == "unsafe" {
				return types.Unsafe, nil
			}
			return nil, fmt.Errorf("can't find import: %q", id)
		}
		if pkg = packages[id]; pkg != nil && pkg.Complete() {
			return
		}
		f, err := os.Open(filename)
		if err != nil {
			return nil, err
		}
		defer func() {
			if err != nil {
				err = fmt.Errorf("%s: %v", filename, err)
			}
		}()
		rc = f
	}
	defer rc.Close()
	var hdr string
	buf := bufio.NewReader(rc)
	if hdr, err = FindExportData(buf); err != nil {
		return
	}
	switch hdr {
	case "$$\n":
		if filename == "" {
			filename = path
		}
		return ImportData(packages, filename, id, buf)
	case "$$B\n":
		var data []byte
		data, err = ioutil.ReadAll(buf)
		if err != nil {
			break
		}
		fset := token.NewFileSet()
		if len(data) > 0 && data[0] == 'i' {
			_, pkg, err = IImportData(fset, packages, data[1:], id)
		} else {
			_, pkg, err = BImportData(fset, packages, data, id)
		}
	default:
		err = fmt.Errorf("unknown export data header: %q", hdr)
	}
	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.
package gcimporter  
import (
	"bufio"
	"errors"
	"fmt"
	"go/build"
	"go/constant"
	"go/token"
	"go/types"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"text/scanner"
)
const debug = false
var pkgExts = [...]string{".a", ".o"}
func FindPkg(path, srcDir string) (filename, id string) {
	if path == "" {
		return
	}
	var noext string
	switch {
	default:
		if abs, err := filepath.Abs(srcDir); err == nil {  
			srcDir = abs
		}
		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
		if bp.PkgObj == "" {
			id = path  
			return
		}
		noext = strings.TrimSuffix(bp.PkgObj, ".a")
		id = bp.ImportPath
	case build.IsLocalImport(path):
		noext = filepath.Join(srcDir, path)
		id = noext
	case filepath.IsAbs(path):
		noext = path
		id = path
	}
	if false {  
		if path != id {
			fmt.Printf("%s -> %s\n", path, id)
		}
	}
	for _, ext := range pkgExts {
		filename = noext + ext
		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
			return
		}
	}
	filename = ""  
	return
}
func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) {
	defer func() {
		switch r := recover().(type) {
		case nil:
		case importError:
			err = r
		default:
			panic(r)  
		}
	}()
	var p parser
	p.init(filename, id, data, packages)
	pkg = p.parseExport()
	return
}