// TODO replace with encoding/gob when reflection is ready func ReadArchive(packages map[string]*types.Package, filename, id string, data io.Reader) ([]byte, *types.Package, error) { r := bufio.NewReader(data) code, err := readUntilSeparator(r) if err != nil { return nil, nil, err } importList, err := readUntilSeparator(r) if err != nil { return nil, nil, err } pkg, err := gcimporter.ImportData(packages, filename, id, r) if err != nil { return nil, nil, err } var imports []*types.Package for _, path := range strings.Split(string(importList), "\n") { if path == "" { continue } impPkg, found := packages[path] if !found { impPkg = types.NewPackage(path, "", types.NewScope(nil)) packages[path] = impPkg } imports = append(imports, impPkg) } pkg.SetImports(imports) return code, pkg, nil }
func (imp *Importer) Import(imports map[string]*types.Package, path string) (pkg *types.Package, err error) { // myimports is different from imports. Imports can contain // dummy packages not loaded by us, while myimports will // be "pure". if pkg, ok := imp.myimports[path]; ok { if pkg == nil { return nil, fmt.Errorf("Previous attempt at loading package failed") } return pkg, nil } var data []byte pkgfile := packageExportsFile(imp.context, path) if path == "unsafe" { // Importing these packages have issues // // unsafe: // If this is actually imported, go.types will panic due to invalid type conversions. // This because it is a built in package (http://tip.golang.org/doc/spec#Package_unsafe) // and thus shouldn't be treated as a normal package anyway. } else { data, _ = ioutil.ReadFile(pkgfile) } if data != nil { // Need to load dependencies first for _, match := range importsRe.FindAllStringSubmatch(string(data), -1) { if _, ok := imp.myimports[match[1]]; !ok { _, err := imp.Import(imports, match[1]) if err != nil { return nil, err } } } pkg, err = gcimporter.ImportData(imports, pkgfile, path, bufio.NewReader(bytes.NewBuffer(data))) if err == nil { tracef("Loaded import data from: %s", pkgfile) } } if pkg == nil || err != nil { if data != nil { return nil, fmt.Errorf("Failed to load package %s: %v", path, err) } // Package has not been compiled yet, so fall back to // the standard GcImport. tracef("Falling back to gc import data for: %s", path) pkg, err = gcimporter.Import(imports, path) } imp.myimports[path] = pkg imports[path] = pkg return pkg, err }
func UnmarshalArchive(filename, id string, data []byte, importContext *ImportContext) (*Archive, error) { var a Archive _, err := asn1.Unmarshal(data, &a) if err != nil { return nil, err } pkg, err := gcimporter.ImportData(importContext.Packages, filename, id, bytes.NewReader(a.GcData)) if err != nil { return nil, err } importContext.Packages[pkg.Path()] = pkg return &a, nil }
func (t *Translator) ReadArchive(filename, id string, data []byte) (*Archive, error) { var a Archive _, err := asn1.Unmarshal(data, &a) if err != nil { return nil, err } pkg, err := gcimporter.ImportData(t.typesPackages, filename, id, bytes.NewReader(a.GcData)) if err != nil { return nil, err } t.typesPackages[pkg.Path()] = pkg return &a, nil }
func gcImportData(imports map[string]*types.Package, data []byte, path string) (*types.Package, error) { filename := fmt.Sprintf("<filename for %s>", path) // so we have a decent error message if necessary return gcimporter.ImportData(imports, filename, path, bufio.NewReader(bytes.NewBuffer(data))) }