Пример #1
0
// 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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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)))
}