1 // Copyright 2015 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.
5 // This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go.
23 type importer struct {
24 imports map[string]*types.Package
27 buf []byte // for reading strings
28 version int // export format version
31 strList []string // in order of appearance
32 pathList []string // in order of appearance
33 pkgList []*types.Package // in order of appearance
34 typList []types.Type // in order of appearance
35 interfaceList []*types.Interface // for delayed completion only
46 read int // bytes read
49 // BImportData imports a package from the serialized package data
50 // and returns the number of bytes consumed and a reference to the package.
51 // If the export data version is not recognized or the format is otherwise
52 // compromised, an error is returned.
53 func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
54 // catch panics and return them as errors
55 const currentVersion = 6
56 version := -1 // unknown version
58 if e := recover(); e != nil {
59 // Return a (possibly nil or incomplete) package unchanged (see #16088).
60 if version > currentVersion {
61 err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
63 err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
73 strList: []string{""}, // empty string is mapped to 0
74 pathList: []string{""}, // empty string is mapped to 0
77 files: make(map[string]*token.File),
83 if b := p.rawByte(); b == 'c' || b == 'd' {
84 // Go1.7 encoding; first byte encodes low-level
85 // encoding format (compact vs debug).
86 // For backward-compatibility only (avoid problems with
87 // old installed packages). Newly compiled packages use
88 // the extensible format string.
89 // TODO(gri) Remove this support eventually; after Go1.8.
93 p.trackAllTypes = p.rawByte() == 'a'
94 p.posInfoFormat = p.int() != 0
95 versionstr = p.string()
96 if versionstr == "v1" {
100 // Go1.8 extensible encoding
101 // read version string and extract version number (ignore anything after the version number)
102 versionstr = p.rawStringln(b)
103 if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
104 if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
111 // read version specific flags - extend as necessary
113 // case currentVersion:
116 case currentVersion, 5, 4, 3, 2, 1:
117 p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
118 p.trackAllTypes = p.int() != 0
119 p.posInfoFormat = p.int() != 0
121 // Go1.7 encoding format - nothing to do here
123 errorf("unknown bexport format version %d (%q)", p.version, versionstr)
126 // --- generic export data ---
128 // populate typList with predeclared "known" types
129 p.typList = append(p.typList, predeclared()...)
134 // read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go)
137 tag := p.tagOrIndex()
146 if count := p.int(); count != objcount {
147 errorf("got %d objects; want %d", objcount, count)
150 // ignore compiler-specific import data
152 // complete interfaces
153 // TODO(gri) re-investigate if we still need to do this in a delayed fashion
154 for _, typ := range p.interfaceList {
158 // record all referenced packages as imports
159 list := append(([]*types.Package)(nil), p.pkgList[1:]...)
160 sort.Sort(byPath(list))
163 // package was imported completely and without errors
166 return p.read, pkg, nil
169 func errorf(format string, args ...interface{}) {
170 panic(fmt.Sprintf(format, args...))
173 func (p *importer) pkg() *types.Package {
174 // if the package was seen before, i is its index (>= 0)
180 // otherwise, i is the package tag (< 0)
182 errorf("unexpected package tag %d version %d", i, p.version)
194 p.int() // package height; unused by go/types
197 // we should never see an empty package name
199 errorf("empty package name in import")
202 // an empty path denotes the package we are currently importing;
203 // it must be the first package we see
204 if (path == "") != (len(p.pkgList) == 0) {
205 errorf("package path %q for pkg index %d", path, len(p.pkgList))
208 // if the package was imported before, use that one; otherwise create a new one
212 pkg := p.imports[path]
214 pkg = types.NewPackage(path, name)
215 p.imports[path] = pkg
216 } else if pkg.Name() != name {
217 errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path)
219 p.pkgList = append(p.pkgList, pkg)
224 // objTag returns the tag value for each object kind.
225 func objTag(obj types.Object) int {
229 case *types.TypeName:
236 errorf("unexpected object: %v (%T)", obj, obj) // panics
241 func sameObj(a, b types.Object) bool {
242 // Because unnamed types are not canonicalized, we cannot simply compare types for
243 // (pointer) identity.
244 // Ideally we'd check equality of constant values as well, but this is good enough.
245 return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type())
248 func (p *importer) declare(obj types.Object) {
250 if alt := pkg.Scope().Insert(obj); alt != nil {
251 // This can only trigger if we import a (non-type) object a second time.
252 // Excluding type aliases, this cannot happen because 1) we only import a package
253 // once; and b) we ignore compiler-specific export data which may contain
254 // functions whose inlined function bodies refer to other functions that
255 // were already imported.
256 // However, type aliases require reexporting the original type, so we need
257 // to allow it (see also the comment in cmd/compile/internal/gc/bimport.go,
258 // method importer.obj, switch case importing functions).
259 // TODO(gri) review/update this comment once the gc compiler handles type aliases.
260 if !sameObj(obj, alt) {
261 errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt)
266 func (p *importer) obj(tag int) {
270 pkg, name := p.qualifiedName()
271 typ := p.typ(nil, nil)
273 p.declare(types.NewConst(pos, pkg, name, typ, val))
276 // TODO(gri) verify type alias hookup is correct
278 pkg, name := p.qualifiedName()
279 typ := p.typ(nil, nil)
280 p.declare(types.NewTypeName(pos, pkg, name, typ))
287 pkg, name := p.qualifiedName()
288 typ := p.typ(nil, nil)
289 p.declare(types.NewVar(pos, pkg, name, typ))
293 pkg, name := p.qualifiedName()
294 params, isddd := p.paramList()
295 result, _ := p.paramList()
296 sig := types.NewSignature(nil, params, result, isddd)
297 p.declare(types.NewFunc(pos, pkg, name, sig))
300 errorf("unexpected object tag %d", tag)
304 const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
306 func (p *importer) pos() token.Pos {
307 if !p.posInfoFormat {
316 if delta == deltaNewFile {
317 if n := p.int(); n >= 0 {
325 if n := p.int(); n >= 0 {
327 file = p.prevFile[:n] + p.string()
335 return p.fake.pos(file, line)
338 // Synthesize a token.Pos
339 type fakeFileSet struct {
341 files map[string]*token.File
344 func (s *fakeFileSet) pos(file string, line int) token.Pos {
345 // Since we don't know the set of needed file positions, we
346 // reserve maxlines positions per file.
347 const maxlines = 64 * 1024
350 f = s.fset.AddFile(file, -1, maxlines)
352 // Allocate the fake linebreak indices on first use.
353 // TODO(adonovan): opt: save ~512KB using a more complex scheme?
354 fakeLinesOnce.Do(func() {
355 fakeLines = make([]int, maxlines)
356 for i := range fakeLines {
360 f.SetLines(fakeLines)
367 // Treat the file as if it contained only newlines
368 // and column=1: use the line number as the offset.
369 return f.Pos(line - 1)
374 fakeLinesOnce sync.Once
377 func (p *importer) qualifiedName() (pkg *types.Package, name string) {
383 func (p *importer) record(t types.Type) {
384 p.typList = append(p.typList, t)
387 // A dddSlice is a types.Type representing ...T parameters.
388 // It only appears for parameter types and does not escape
390 type dddSlice struct {
394 func (t *dddSlice) Underlying() types.Type { return t }
395 func (t *dddSlice) String() string { return "..." + t.elem.String() }
397 // parent is the package which declared the type; parent == nil means
398 // the package currently imported. The parent package is needed for
399 // exported struct fields and interface methods which don't contain
400 // explicit package information in the export data.
402 // A non-nil tname is used as the "owner" of the result type; i.e.,
403 // the result type is the underlying type of tname. tname is used
404 // to give interface methods a named receiver type where possible.
405 func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type {
406 // if the type was seen before, i is its index (>= 0)
412 // otherwise, i is the type tag (< 0)
417 parent, name := p.qualifiedName()
418 scope := parent.Scope()
419 obj := scope.Lookup(name)
421 // if the object doesn't exist yet, create and insert it
423 obj = types.NewTypeName(pos, parent, name, nil)
427 if _, ok := obj.(*types.TypeName); !ok {
428 errorf("pkg = %s, name = %s => %s", parent, name, obj)
431 // associate new named type with obj if it doesn't exist yet
432 t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
434 // but record the existing type, if any
435 tname := obj.Type().(*types.Named) // tname is either t0 or the existing type
438 // read underlying type
439 t0.SetUnderlying(p.typ(parent, t0))
441 // interfaces don't have associated methods
442 if types.IsInterface(t0) {
446 // read associated methods
447 for i := p.int(); i > 0; i-- {
448 // TODO(gri) replace this with something closer to fieldName
455 recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
456 params, isddd := p.paramList()
457 result, _ := p.paramList()
458 p.int() // go:nointerface pragma - discarded
460 sig := types.NewSignature(recv.At(0), params, result, isddd)
461 t0.AddMethod(types.NewFunc(pos, parent, name, sig))
467 t := new(types.Array)
473 *t = *types.NewArray(p.typ(parent, nil), n)
477 t := new(types.Slice)
482 *t = *types.NewSlice(p.typ(parent, nil))
491 t.elem = p.typ(parent, nil)
495 t := new(types.Struct)
500 *t = *types.NewStruct(p.fieldList(parent))
504 t := new(types.Pointer)
509 *t = *types.NewPointer(p.typ(parent, nil))
513 t := new(types.Signature)
518 params, isddd := p.paramList()
519 result, _ := p.paramList()
520 *t = *types.NewSignature(nil, params, result, isddd)
524 // Create a dummy entry in the type list. This is safe because we
525 // cannot expect the interface type to appear in a cycle, as any
526 // such cycle must contain a named type which would have been
527 // first defined earlier.
528 // TODO(gri) Is this still true now that we have type aliases?
535 var embeddeds []types.Type
536 for n := p.int(); n > 0; n-- {
538 embeddeds = append(embeddeds, p.typ(parent, nil))
541 t := newInterface(p.methodList(parent, tname), embeddeds)
542 p.interfaceList = append(p.interfaceList, t)
554 key := p.typ(parent, nil)
555 val := p.typ(parent, nil)
556 *t = *types.NewMap(key, val)
565 dir := chanDir(p.int())
566 val := p.typ(parent, nil)
567 *t = *types.NewChan(dir, val)
571 errorf("unexpected type tag %d", i) // panics
576 func chanDir(d int) types.ChanDir {
577 // tag values must match the constants in cmd/compile/internal/gc/go.go
580 return types.RecvOnly
582 return types.SendOnly
584 return types.SendRecv
586 errorf("unexpected channel dir %d", d)
591 func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) {
592 if n := p.int(); n > 0 {
593 fields = make([]*types.Var, n)
594 tags = make([]string, n)
595 for i := range fields {
596 fields[i], tags[i] = p.field(parent)
602 func (p *importer) field(parent *types.Package) (*types.Var, string) {
604 pkg, name, alias := p.fieldName(parent)
605 typ := p.typ(parent, nil)
610 // anonymous field - typ must be T or *T and T must be a type name
611 switch typ := deref(typ).(type) {
612 case *types.Basic: // basic types are named types
613 pkg = nil // // objects defined in Universe scope have no package
616 name = typ.Obj().Name()
618 errorf("named base type expected")
622 // anonymous field: we have an explicit name because it's an alias
626 return types.NewField(pos, pkg, name, typ, anonymous), tag
629 func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) {
630 if n := p.int(); n > 0 {
631 methods = make([]*types.Func, n)
632 for i := range methods {
633 methods[i] = p.method(parent, baseType)
639 func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func {
641 pkg, name, _ := p.fieldName(parent)
642 // If we don't have a baseType, use a nil receiver.
643 // A receiver using the actual interface type (which
644 // we don't know yet) will be filled in when we call
645 // types.Interface.Complete.
648 recv = types.NewVar(token.NoPos, parent, "", baseType)
650 params, isddd := p.paramList()
651 result, _ := p.paramList()
652 sig := types.NewSignature(recv, params, result, isddd)
653 return types.NewFunc(pos, pkg, name, sig)
656 func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) {
660 // use the imported package instead
663 if p.version == 0 && name == "_" {
664 // version 0 didn't export a package for _ fields
669 // 1) field name matches base type name and is exported: nothing to do
671 // 2) field name matches base type name and is not exported: need package
675 // 3) field name doesn't match type name (alias)
687 func (p *importer) paramList() (*types.Tuple, bool) {
692 // negative length indicates unnamed parameters
699 params := make([]*types.Var, n)
701 for i := range params {
702 params[i], isddd = p.param(named)
704 return types.NewTuple(params...), isddd
707 func (p *importer) param(named bool) (*types.Var, bool) {
709 td, isddd := t.(*dddSlice)
711 t = types.NewSlice(td.elem)
714 var pkg *types.Package
719 errorf("expected named parameter")
724 if i := strings.Index(name, "·"); i > 0 {
725 name = name[:i] // cut off gc-specific parameter numbering
729 // read and discard compiler-specific info
732 return types.NewVar(token.NoPos, pkg, name, t), isddd
735 func exported(name string) bool {
736 ch, _ := utf8.DecodeRuneInString(name)
737 return unicode.IsUpper(ch)
740 func (p *importer) value() constant.Value {
741 switch tag := p.tagOrIndex(); tag {
743 return constant.MakeBool(false)
745 return constant.MakeBool(true)
747 return constant.MakeInt64(p.int64())
753 return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
755 return constant.MakeString(p.string())
757 return constant.MakeUnknown()
759 errorf("unexpected value tag %d", tag) // panics
764 func (p *importer) float() constant.Value {
767 return constant.MakeInt64(0)
771 mant := []byte(p.string()) // big endian
773 // remove leading 0's if any
774 for len(mant) > 0 && mant[0] == 0 {
778 // convert to little endian
779 // TODO(gri) go/constant should have a more direct conversion function
780 // (e.g., once it supports a big.Float based implementation)
781 for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
782 mant[i], mant[j] = mant[j], mant[i]
785 // adjust exponent (constant.MakeFromBytes creates an integer value,
786 // but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
787 exp -= len(mant) << 3
789 for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
794 x := constant.MakeFromBytes(mant)
797 d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
798 x = constant.BinaryOp(x, token.QUO, d)
800 x = constant.Shift(x, token.SHL, uint(exp))
804 x = constant.UnaryOp(token.SUB, x, 0)
809 // ----------------------------------------------------------------------------
810 // Low-level decoders
812 func (p *importer) tagOrIndex() int {
817 return int(p.rawInt64())
820 func (p *importer) int() int {
822 if int64(int(x)) != x {
823 errorf("exported integer too large")
828 func (p *importer) int64() int64 {
836 func (p *importer) path() string {
840 // if the path was seen before, i is its index (>= 0)
841 // (the empty string is at index 0)
846 // otherwise, i is the negative path length (< 0)
847 a := make([]string, -i)
851 s := strings.Join(a, "/")
852 p.pathList = append(p.pathList, s)
856 func (p *importer) string() string {
860 // if the string was seen before, i is its index (>= 0)
861 // (the empty string is at index 0)
866 // otherwise, i is the negative string length (< 0)
867 if n := int(-i); n <= cap(p.buf) {
870 p.buf = make([]byte, n)
872 for i := range p.buf {
873 p.buf[i] = p.rawByte()
876 p.strList = append(p.strList, s)
880 func (p *importer) marker(want byte) {
881 if got := p.rawByte(); got != want {
882 errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
886 if n := int(p.rawInt64()); n != pos {
887 errorf("incorrect position: got %d; want %d", n, pos)
891 // rawInt64 should only be used by low-level decoders.
892 func (p *importer) rawInt64() int64 {
893 i, err := binary.ReadVarint(p)
895 errorf("read error: %v", err)
900 // rawStringln should only be used to read the initial version string.
901 func (p *importer) rawStringln(b byte) string {
904 p.buf = append(p.buf, b)
910 // needed for binary.ReadVarint in rawInt64
911 func (p *importer) ReadByte() (byte, error) {
912 return p.rawByte(), nil
915 // byte is the bottleneck interface for reading p.data.
916 // It unescapes '|' 'S' to '$' and '|' '|' to '|'.
917 // rawByte should only be used by low-level decoders.
918 func (p *importer) rawByte() byte {
930 errorf("unexpected escape sequence in export data")
939 // ----------------------------------------------------------------------------
942 // Tags. Must be < 0.
945 packageTag = -(iota + 1)
969 fractionTag // not used by gc
972 nilTag // only used by gc (appears in exported inlined function bodies)
973 unknownTag // not used by gc (only appears in packages with errors)
979 var predecl []types.Type // initialized lazily
981 func predeclared() []types.Type {
983 // initialize lazily to be sure that all
984 // elements have been initialized before
985 predecl = []types.Type{ // basic types
986 types.Typ[types.Bool],
987 types.Typ[types.Int],
988 types.Typ[types.Int8],
989 types.Typ[types.Int16],
990 types.Typ[types.Int32],
991 types.Typ[types.Int64],
992 types.Typ[types.Uint],
993 types.Typ[types.Uint8],
994 types.Typ[types.Uint16],
995 types.Typ[types.Uint32],
996 types.Typ[types.Uint64],
997 types.Typ[types.Uintptr],
998 types.Typ[types.Float32],
999 types.Typ[types.Float64],
1000 types.Typ[types.Complex64],
1001 types.Typ[types.Complex128],
1002 types.Typ[types.String],
1004 // basic type aliases
1005 types.Universe.Lookup("byte").Type(),
1006 types.Universe.Lookup("rune").Type(),
1009 types.Universe.Lookup("error").Type(),
1012 types.Typ[types.UntypedBool],
1013 types.Typ[types.UntypedInt],
1014 types.Typ[types.UntypedRune],
1015 types.Typ[types.UntypedFloat],
1016 types.Typ[types.UntypedComplex],
1017 types.Typ[types.UntypedString],
1018 types.Typ[types.UntypedNil],
1021 types.Typ[types.UnsafePointer],
1024 types.Typ[types.Invalid], // only appears in packages with errors
1026 // used internally by gc; never used by this package or in .a files
1033 type anyType struct{}
1035 func (t anyType) Underlying() types.Type { return t }
1036 func (t anyType) String() string { return "any" }