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.
21 type importer
struct {
22 imports
map[string]*types
.Package
25 buf
[]byte // for reading strings
26 version
int // export format version
29 strList
[]string // in order of appearance
30 pathList
[]string // in order of appearance
31 pkgList
[]*types
.Package
// in order of appearance
32 typList
[]types
.Type
// in order of appearance
33 interfaceList
[]*types
.Interface
// for delayed completion only
41 files
map[string]*token
.File
45 read
int // bytes read
48 // BImportData imports a package from the serialized package data
49 // and returns the number of bytes consumed and a reference to the package.
50 // If the export data version is not recognized or the format is otherwise
51 // compromised, an error is returned.
52 func BImportData(fset
*token
.FileSet
, imports
map[string]*types
.Package
, data
[]byte, path
string) (_
int, pkg
*types
.Package
, err error
) {
53 // catch panics and return them as errors
55 if e
:= recover(); e
!= nil {
56 // The package (filename) causing the problem is added to this
57 // error by a wrapper in the caller (Import in gcimporter.go).
58 // Return a (possibly nil or incomplete) package unchanged (see #16088).
59 err
= fmt
.Errorf("cannot import, possibly version skew (%v) - reinstall package", e
)
67 version
: -1, // unknown version
68 strList
: []string{""}, // empty string is mapped to 0
69 pathList
: []string{""}, // empty string is mapped to 0
71 files
: make(map[string]*token
.File
),
76 if b
:= p
.rawByte(); b
== 'c' || b
== 'd' {
77 // Go1.7 encoding; first byte encodes low-level
78 // encoding format (compact vs debug).
79 // For backward-compatibility only (avoid problems with
80 // old installed packages). Newly compiled packages use
81 // the extensible format string.
82 // TODO(gri) Remove this support eventually; after Go1.8.
86 p
.trackAllTypes
= p
.rawByte() == 'a'
87 p
.posInfoFormat
= p
.int() != 0
88 versionstr
= p
.string()
89 if versionstr
== "v1" {
93 // Go1.8 extensible encoding
94 // read version string and extract version number (ignore anything after the version number)
95 versionstr
= p
.rawStringln(b
)
96 if s
:= strings
.SplitN(versionstr
, " ", 3); len(s
) >= 2 && s
[0] == "version" {
97 if v
, err
:= strconv
.Atoi(s
[1]); err
== nil && v
> 0 {
103 // read version specific flags - extend as necessary
109 p
.debugFormat
= p
.rawStringln(p
.rawByte()) == "debug"
110 p
.trackAllTypes
= p
.int() != 0
111 p
.posInfoFormat
= p
.int() != 0
113 // Go1.7 encoding format - nothing to do here
115 errorf("unknown export format version %d (%q)", p
.version
, versionstr
)
118 // --- generic export data ---
120 // populate typList with predeclared "known" types
121 p
.typList
= append(p
.typList
, predeclared
...)
126 // read objects of phase 1 only (see cmd/compiler/internal/gc/bexport.go)
129 tag
:= p
.tagOrIndex()
138 if count
:= p
.int(); count
!= objcount
{
139 errorf("got %d objects; want %d", objcount
, count
)
142 // ignore compiler-specific import data
144 // complete interfaces
145 // TODO(gri) re-investigate if we still need to do this in a delayed fashion
146 for _
, typ
:= range p
.interfaceList
{
150 // record all referenced packages as imports
151 list
:= append(([]*types
.Package
)(nil), p
.pkgList
[1:]...)
152 sort
.Sort(byPath(list
))
155 // package was imported completely and without errors
158 return p
.read
, pkg
, nil
161 func errorf(format
string, args
...interface{}) {
162 panic(fmt
.Sprintf(format
, args
...))
165 func (p
*importer
) pkg() *types
.Package
{
166 // if the package was seen before, i is its index (>= 0)
172 // otherwise, i is the package tag (< 0)
174 errorf("unexpected package tag %d version %d", i
, p
.version
)
186 // we should never see an empty package name
188 errorf("empty package name in import")
191 // an empty path denotes the package we are currently importing;
192 // it must be the first package we see
193 if (path
== "") != (len(p
.pkgList
) == 0) {
194 errorf("package path %q for pkg index %d", path
, len(p
.pkgList
))
197 // if the package was imported before, use that one; otherwise create a new one
201 pkg
:= p
.imports
[path
]
203 pkg
= types
.NewPackage(path
, name
)
204 p
.imports
[path
] = pkg
205 } else if pkg
.Name() != name
{
206 errorf("conflicting names %s and %s for package %q", pkg
.Name(), name
, path
)
208 p
.pkgList
= append(p
.pkgList
, pkg
)
213 // objTag returns the tag value for each object kind.
214 func objTag(obj types
.Object
) int {
218 case *types
.TypeName
:
225 errorf("unexpected object: %v (%T)", obj
, obj
) // panics
230 func sameObj(a
, b types
.Object
) bool {
231 // Because unnamed types are not canonicalized, we cannot simply compare types for
232 // (pointer) identity.
233 // Ideally we'd check equality of constant values as well, but this is good enough.
234 return objTag(a
) == objTag(b
) && types
.Identical(a
.Type(), b
.Type())
237 func (p
*importer
) declare(obj types
.Object
) {
239 if alt
:= pkg
.Scope().Insert(obj
); alt
!= nil {
240 // This can only trigger if we import a (non-type) object a second time.
241 // Excluding type aliases, this cannot happen because 1) we only import a package
242 // once; and b) we ignore compiler-specific export data which may contain
243 // functions whose inlined function bodies refer to other functions that
244 // were already imported.
245 // However, type aliases require reexporting the original type, so we need
246 // to allow it (see also the comment in cmd/compile/internal/gc/bimport.go,
247 // method importer.obj, switch case importing functions).
248 // TODO(gri) review/update this comment once the gc compiler handles type aliases.
249 if !sameObj(obj
, alt
) {
250 errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj
, alt
)
255 func (p
*importer
) obj(tag
int) {
259 pkg
, name
:= p
.qualifiedName()
262 p
.declare(types
.NewConst(pos
, pkg
, name
, typ
, val
))
265 // TODO(gri) verify type alias hookup is correct
267 pkg
, name
:= p
.qualifiedName()
269 p
.declare(types
.NewTypeName(pos
, pkg
, name
, typ
))
276 pkg
, name
:= p
.qualifiedName()
278 p
.declare(types
.NewVar(pos
, pkg
, name
, typ
))
282 pkg
, name
:= p
.qualifiedName()
283 params
, isddd
:= p
.paramList()
284 result
, _
:= p
.paramList()
285 sig
:= types
.NewSignature(nil, params
, result
, isddd
)
286 p
.declare(types
.NewFunc(pos
, pkg
, name
, sig
))
289 errorf("unexpected object tag %d", tag
)
293 const deltaNewFile
= -64 // see cmd/compile/internal/gc/bexport.go
295 func (p
*importer
) pos() token
.Pos
{
296 if !p
.posInfoFormat
{
305 if delta
== deltaNewFile
{
306 if n
:= p
.int(); n
>= 0 {
314 if n
:= p
.int(); n
>= 0 {
316 file
= p
.prevFile
[:n
] + p
.string()
324 // Synthesize a token.Pos
326 // Since we don't know the set of needed file positions, we
327 // reserve maxlines positions per file.
328 const maxlines
= 64 * 1024
331 f
= p
.fset
.AddFile(file
, -1, maxlines
)
333 // Allocate the fake linebreak indices on first use.
334 // TODO(adonovan): opt: save ~512KB using a more complex scheme?
335 fakeLinesOnce
.Do(func() {
336 fakeLines
= make([]int, maxlines
)
337 for i
:= range fakeLines
{
341 f
.SetLines(fakeLines
)
348 // Treat the file as if it contained only newlines
349 // and column=1: use the line number as the offset.
350 return f
.Pos(line
- 1)
355 fakeLinesOnce sync
.Once
358 func (p
*importer
) qualifiedName() (pkg
*types
.Package
, name
string) {
364 func (p
*importer
) record(t types
.Type
) {
365 p
.typList
= append(p
.typList
, t
)
368 // A dddSlice is a types.Type representing ...T parameters.
369 // It only appears for parameter types and does not escape
371 type dddSlice
struct {
375 func (t
*dddSlice
) Underlying() types
.Type
{ return t
}
376 func (t
*dddSlice
) String() string { return "..." + t
.elem
.String() }
378 // parent is the package which declared the type; parent == nil means
379 // the package currently imported. The parent package is needed for
380 // exported struct fields and interface methods which don't contain
381 // explicit package information in the export data.
382 func (p
*importer
) typ(parent
*types
.Package
) types
.Type
{
383 // if the type was seen before, i is its index (>= 0)
389 // otherwise, i is the type tag (< 0)
394 parent
, name
:= p
.qualifiedName()
395 scope
:= parent
.Scope()
396 obj
:= scope
.Lookup(name
)
398 // if the object doesn't exist yet, create and insert it
400 obj
= types
.NewTypeName(pos
, parent
, name
, nil)
404 if _
, ok
:= obj
.(*types
.TypeName
); !ok
{
405 errorf("pkg = %s, name = %s => %s", parent
, name
, obj
)
408 // associate new named type with obj if it doesn't exist yet
409 t0
:= types
.NewNamed(obj
.(*types
.TypeName
), nil, nil)
411 // but record the existing type, if any
412 t
:= obj
.Type().(*types
.Named
)
415 // read underlying type
416 t0
.SetUnderlying(p
.typ(parent
))
418 // interfaces don't have associated methods
419 if types
.IsInterface(t0
) {
423 // read associated methods
424 for i
:= p
.int(); i
> 0; i
-- {
425 // TODO(gri) replace this with something closer to fieldName
432 recv
, _
:= p
.paramList() // TODO(gri) do we need a full param list for the receiver?
433 params
, isddd
:= p
.paramList()
434 result
, _
:= p
.paramList()
435 p
.int() // go:nointerface pragma - discarded
437 sig
:= types
.NewSignature(recv
.At(0), params
, result
, isddd
)
438 t0
.AddMethod(types
.NewFunc(pos
, parent
, name
, sig
))
444 t
:= new(types
.Array
)
450 *t
= *types
.NewArray(p
.typ(parent
), n
)
454 t
:= new(types
.Slice
)
459 *t
= *types
.NewSlice(p
.typ(parent
))
468 t
.elem
= p
.typ(parent
)
472 t
:= new(types
.Struct
)
477 *t
= *types
.NewStruct(p
.fieldList(parent
))
481 t
:= new(types
.Pointer
)
486 *t
= *types
.NewPointer(p
.typ(parent
))
490 t
:= new(types
.Signature
)
495 params
, isddd
:= p
.paramList()
496 result
, _
:= p
.paramList()
497 *t
= *types
.NewSignature(nil, params
, result
, isddd
)
501 // Create a dummy entry in the type list. This is safe because we
502 // cannot expect the interface type to appear in a cycle, as any
503 // such cycle must contain a named type which would have been
504 // first defined earlier.
510 var embeddeds
[]*types
.Named
511 for n
:= p
.int(); n
> 0; n
-- {
513 embeddeds
= append(embeddeds
, p
.typ(parent
).(*types
.Named
))
516 t
:= types
.NewInterface(p
.methodList(parent
), embeddeds
)
517 p
.interfaceList
= append(p
.interfaceList
, t
)
531 *t
= *types
.NewMap(key
, val
)
540 var dir types
.ChanDir
541 // tag values must match the constants in cmd/compile/internal/gc/go.go
542 switch d
:= p
.int(); d
{
550 errorf("unexpected channel dir %d", d
)
553 *t
= *types
.NewChan(dir
, val
)
557 errorf("unexpected type tag %d", i
) // panics
562 func (p
*importer
) fieldList(parent
*types
.Package
) (fields
[]*types
.Var
, tags
[]string) {
563 if n
:= p
.int(); n
> 0 {
564 fields
= make([]*types
.Var
, n
)
565 tags
= make([]string, n
)
566 for i
:= range fields
{
567 fields
[i
], tags
[i
] = p
.field(parent
)
573 func (p
*importer
) field(parent
*types
.Package
) (*types
.Var
, string) {
575 pkg
, name
, alias
:= p
.fieldName(parent
)
581 // anonymous field - typ must be T or *T and T must be a type name
582 switch typ
:= deref(typ
).(type) {
583 case *types
.Basic
: // basic types are named types
584 pkg
= nil // // objects defined in Universe scope have no package
587 name
= typ
.Obj().Name()
589 errorf("named base type expected")
593 // anonymous field: we have an explicit name because it's an alias
597 return types
.NewField(pos
, pkg
, name
, typ
, anonymous
), tag
600 func (p
*importer
) methodList(parent
*types
.Package
) (methods
[]*types
.Func
) {
601 if n
:= p
.int(); n
> 0 {
602 methods
= make([]*types
.Func
, n
)
603 for i
:= range methods
{
604 methods
[i
] = p
.method(parent
)
610 func (p
*importer
) method(parent
*types
.Package
) *types
.Func
{
612 pkg
, name
, _
:= p
.fieldName(parent
)
613 params
, isddd
:= p
.paramList()
614 result
, _
:= p
.paramList()
615 sig
:= types
.NewSignature(nil, params
, result
, isddd
)
616 return types
.NewFunc(pos
, pkg
, name
, sig
)
619 func (p
*importer
) fieldName(parent
*types
.Package
) (pkg
*types
.Package
, name
string, alias
bool) {
623 // use the imported package instead
626 if p
.version
== 0 && name
== "_" {
627 // version 0 didn't export a package for _ fields
632 // 1) field name matches base type name and is exported: nothing to do
634 // 2) field name matches base type name and is not exported: need package
638 // 3) field name doesn't match type name (alias)
650 func (p
*importer
) paramList() (*types
.Tuple
, bool) {
655 // negative length indicates unnamed parameters
662 params
:= make([]*types
.Var
, n
)
664 for i
:= range params
{
665 params
[i
], isddd
= p
.param(named
)
667 return types
.NewTuple(params
...), isddd
670 func (p
*importer
) param(named
bool) (*types
.Var
, bool) {
672 td
, isddd
:= t
.(*dddSlice
)
674 t
= types
.NewSlice(td
.elem
)
677 var pkg
*types
.Package
682 errorf("expected named parameter")
687 if i
:= strings
.Index(name
, "·"); i
> 0 {
688 name
= name
[:i
] // cut off gc-specific parameter numbering
692 // read and discard compiler-specific info
695 return types
.NewVar(token
.NoPos
, pkg
, name
, t
), isddd
698 func exported(name
string) bool {
699 ch
, _
:= utf8
.DecodeRuneInString(name
)
700 return unicode
.IsUpper(ch
)
703 func (p
*importer
) value() constant
.Value
{
704 switch tag
:= p
.tagOrIndex(); tag
{
706 return constant
.MakeBool(false)
708 return constant
.MakeBool(true)
710 return constant
.MakeInt64(p
.int64())
716 return constant
.BinaryOp(re
, token
.ADD
, constant
.MakeImag(im
))
718 return constant
.MakeString(p
.string())
720 return constant
.MakeUnknown()
722 errorf("unexpected value tag %d", tag
) // panics
727 func (p
*importer
) float() constant
.Value
{
730 return constant
.MakeInt64(0)
734 mant
:= []byte(p
.string()) // big endian
736 // remove leading 0's if any
737 for len(mant
) > 0 && mant
[0] == 0 {
741 // convert to little endian
742 // TODO(gri) go/constant should have a more direct conversion function
743 // (e.g., once it supports a big.Float based implementation)
744 for i
, j
:= 0, len(mant
)-1; i
< j
; i
, j
= i
+1, j
-1 {
745 mant
[i
], mant
[j
] = mant
[j
], mant
[i
]
748 // adjust exponent (constant.MakeFromBytes creates an integer value,
749 // but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
750 exp
-= len(mant
) << 3
752 for msd
:= mant
[len(mant
)-1]; msd
&0x80 == 0; msd
<<= 1 {
757 x
:= constant
.MakeFromBytes(mant
)
760 d
:= constant
.Shift(constant
.MakeInt64(1), token
.SHL
, uint(-exp
))
761 x
= constant
.BinaryOp(x
, token
.QUO
, d
)
763 x
= constant
.Shift(x
, token
.SHL
, uint(exp
))
767 x
= constant
.UnaryOp(token
.SUB
, x
, 0)
772 // ----------------------------------------------------------------------------
773 // Low-level decoders
775 func (p
*importer
) tagOrIndex() int {
780 return int(p
.rawInt64())
783 func (p
*importer
) int() int {
785 if int64(int(x
)) != x
{
786 errorf("exported integer too large")
791 func (p
*importer
) int64() int64 {
799 func (p
*importer
) path() string {
803 // if the path was seen before, i is its index (>= 0)
804 // (the empty string is at index 0)
809 // otherwise, i is the negative path length (< 0)
810 a
:= make([]string, -i
)
814 s
:= strings
.Join(a
, "/")
815 p
.pathList
= append(p
.pathList
, s
)
819 func (p
*importer
) string() string {
823 // if the string was seen before, i is its index (>= 0)
824 // (the empty string is at index 0)
829 // otherwise, i is the negative string length (< 0)
830 if n
:= int(-i
); n
<= cap(p
.buf
) {
833 p
.buf
= make([]byte, n
)
835 for i
:= range p
.buf
{
836 p
.buf
[i
] = p
.rawByte()
839 p
.strList
= append(p
.strList
, s
)
843 func (p
*importer
) marker(want
byte) {
844 if got
:= p
.rawByte(); got
!= want
{
845 errorf("incorrect marker: got %c; want %c (pos = %d)", got
, want
, p
.read
)
849 if n
:= int(p
.rawInt64()); n
!= pos
{
850 errorf("incorrect position: got %d; want %d", n
, pos
)
854 // rawInt64 should only be used by low-level decoders.
855 func (p
*importer
) rawInt64() int64 {
856 i
, err
:= binary
.ReadVarint(p
)
858 errorf("read error: %v", err
)
863 // rawStringln should only be used to read the initial version string.
864 func (p
*importer
) rawStringln(b
byte) string {
867 p
.buf
= append(p
.buf
, b
)
873 // needed for binary.ReadVarint in rawInt64
874 func (p
*importer
) ReadByte() (byte, error
) {
875 return p
.rawByte(), nil
878 // byte is the bottleneck interface for reading p.data.
879 // It unescapes '|' 'S' to '$' and '|' '|' to '|'.
880 // rawByte should only be used by low-level decoders.
881 func (p
*importer
) rawByte() byte {
893 errorf("unexpected escape sequence in export data")
902 // ----------------------------------------------------------------------------
905 // Tags. Must be < 0.
908 packageTag
= -(iota + 1)
932 fractionTag
// not used by gc
935 nilTag
// only used by gc (appears in exported inlined function bodies)
936 unknownTag
// not used by gc (only appears in packages with errors)
942 var predeclared
= []types
.Type
{
944 types
.Typ
[types
.Bool
],
945 types
.Typ
[types
.Int
],
946 types
.Typ
[types
.Int8
],
947 types
.Typ
[types
.Int16
],
948 types
.Typ
[types
.Int32
],
949 types
.Typ
[types
.Int64
],
950 types
.Typ
[types
.Uint
],
951 types
.Typ
[types
.Uint8
],
952 types
.Typ
[types
.Uint16
],
953 types
.Typ
[types
.Uint32
],
954 types
.Typ
[types
.Uint64
],
955 types
.Typ
[types
.Uintptr
],
956 types
.Typ
[types
.Float32
],
957 types
.Typ
[types
.Float64
],
958 types
.Typ
[types
.Complex64
],
959 types
.Typ
[types
.Complex128
],
960 types
.Typ
[types
.String
],
962 // basic type aliases
963 types
.Universe
.Lookup("byte").Type(),
964 types
.Universe
.Lookup("rune").Type(),
967 types
.Universe
.Lookup("error").Type(),
970 types
.Typ
[types
.UntypedBool
],
971 types
.Typ
[types
.UntypedInt
],
972 types
.Typ
[types
.UntypedRune
],
973 types
.Typ
[types
.UntypedFloat
],
974 types
.Typ
[types
.UntypedComplex
],
975 types
.Typ
[types
.UntypedString
],
976 types
.Typ
[types
.UntypedNil
],
979 types
.Typ
[types
.UnsafePointer
],
982 types
.Typ
[types
.Invalid
], // only appears in packages with errors
984 // used internally by gc; never used by this package or in .a files
988 type anyType
struct{}
990 func (t anyType
) Underlying() types
.Type
{ return t
}
991 func (t anyType
) String() string { return "any" }