1
2
3
4
5
6
7
8 package gcimporter
9
10 import (
11 "bytes"
12 "encoding/binary"
13 "fmt"
14 "go/constant"
15 "go/token"
16 "go/types"
17 "io"
18 "math/big"
19 "slices"
20 "sort"
21 "strings"
22
23 "golang.org/x/tools/go/types/objectpath"
24 "golang.org/x/tools/internal/aliases"
25 "golang.org/x/tools/internal/typesinternal"
26 )
27
28 type intReader struct {
29 *bytes.Reader
30 path string
31 }
32
33 func (r *intReader) int64() int64 {
34 i, err := binary.ReadVarint(r.Reader)
35 if err != nil {
36 errorf("import %q: read varint error: %v", r.path, err)
37 }
38 return i
39 }
40
41 func (r *intReader) uint64() uint64 {
42 i, err := binary.ReadUvarint(r.Reader)
43 if err != nil {
44 errorf("import %q: read varint error: %v", r.path, err)
45 }
46 return i
47 }
48
49
50 const (
51 iexportVersionGo1_11 = 0
52 iexportVersionPosCol = 1
53 iexportVersionGo1_18 = 2
54 iexportVersionGenerics = 2
55 iexportVersionGenericMethods = 3
56 iexportVersion = iexportVersionGenericMethods
57
58 iexportVersionCurrent = 3
59 )
60
61 type ident struct {
62 pkg *types.Package
63 name string
64 }
65
66 const predeclReserved = 32
67
68 type itag uint64
69
70 const (
71
72 definedType itag = iota
73 pointerType
74 sliceType
75 arrayType
76 chanType
77 mapType
78 signatureType
79 structType
80 interfaceType
81 typeParamType
82 instanceType
83 unionType
84 aliasType
85 )
86
87
88 const (
89 varTag = 'V'
90 funcTag = 'F'
91 genericFuncTag = 'G'
92 constTag = 'C'
93 aliasTag = 'A'
94 genericAliasTag = 'B'
95 typeParamTag = 'P'
96 typeTag = 'T'
97 genericTypeTag = 'U'
98 )
99
100
101
102
103
104 func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
105 pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, false, path, false, nil)
106 if err != nil {
107 return 0, nil, err
108 }
109 return 0, pkgs[0], nil
110 }
111
112
113 func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
114 return iimportCommon(fset, GetPackagesFromMap(imports), data, true, "", false, nil)
115 }
116
117
118
119
120
121
122
123
124 type GetPackagesFunc = func(items []GetPackagesItem) error
125
126
127
128 type GetPackagesItem struct {
129 Name, Path string
130 Pkg *types.Package
131
132
133 pathOffset uint64
134 nameIndex map[string]uint64
135 }
136
137
138
139
140
141
142 func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc {
143 return func(items []GetPackagesItem) error {
144 for i, item := range items {
145 pkg, ok := m[item.Path]
146 if !ok {
147 pkg = types.NewPackage(item.Path, item.Name)
148 m[item.Path] = pkg
149 }
150 items[i].Pkg = pkg
151 }
152 return nil
153 }
154 }
155
156 func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, bundle bool, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) {
157 const currentVersion = iexportVersionCurrent
158 version := int64(-1)
159 if !debug {
160 defer func() {
161 if e := recover(); e != nil {
162 if bundle {
163 err = fmt.Errorf("%v", e)
164 } else if version > currentVersion {
165 err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
166 } else {
167 err = fmt.Errorf("internal error while importing %q (%v); please report an issue", path, e)
168 }
169 }
170 }()
171 }
172
173 r := &intReader{bytes.NewReader(data), path}
174
175 if bundle {
176 if v := r.uint64(); v != bundleVersion {
177 errorf("unknown bundle format version %d", v)
178 }
179 }
180
181 version = int64(r.uint64())
182 switch version {
183 case iexportVersionGenericMethods, iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
184 default:
185 if version > iexportVersionGenericMethods {
186 errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
187 } else {
188 errorf("unknown iexport format version %d", version)
189 }
190 }
191
192 sLen := int64(r.uint64())
193 var fLen int64
194 var fileOffset []uint64
195 if shallow {
196
197 fLen = int64(r.uint64())
198 fileOffset = make([]uint64, r.uint64())
199 for i := range fileOffset {
200 fileOffset[i] = r.uint64()
201 }
202 }
203 dLen := int64(r.uint64())
204
205 whence, _ := r.Seek(0, io.SeekCurrent)
206 stringData := data[whence : whence+sLen]
207 fileData := data[whence+sLen : whence+sLen+fLen]
208 declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen]
209 r.Seek(sLen+fLen+dLen, io.SeekCurrent)
210
211 p := iimporter{
212 version: int(version),
213 ipath: path,
214 shallow: shallow,
215 reportf: reportf,
216
217 stringData: stringData,
218 stringCache: make(map[uint64]string),
219 fileOffset: fileOffset,
220 fileData: fileData,
221 fileCache: make([]*token.File, len(fileOffset)),
222 pkgCache: make(map[uint64]*types.Package),
223
224 declData: declData,
225 pkgIndex: make(map[*types.Package]map[string]uint64),
226 typCache: make(map[uint64]types.Type),
227
228
229 tparamIndex: make(map[ident]types.Type),
230
231 fake: fakeFileSet{
232 fset: fset,
233 files: make(map[string]*fileInfo),
234 },
235 }
236 defer p.fake.setLines()
237
238 for i, pt := range predeclared() {
239 p.typCache[uint64(i)] = pt
240 }
241
242
243 items := make([]GetPackagesItem, r.uint64())
244 uniquePkgPaths := make(map[string]bool)
245 for i := range items {
246 pkgPathOff := r.uint64()
247 pkgPath := p.stringAt(pkgPathOff)
248 pkgName := p.stringAt(r.uint64())
249 _ = r.uint64()
250
251 if pkgPath == "" {
252 pkgPath = path
253 }
254 items[i].Name = pkgName
255 items[i].Path = pkgPath
256 items[i].pathOffset = pkgPathOff
257
258
259 nameIndex := make(map[string]uint64)
260 nSyms := r.uint64()
261
262 assert(!(shallow && i > 0 && nSyms != 0))
263 for ; nSyms > 0; nSyms-- {
264 name := p.stringAt(r.uint64())
265 nameIndex[name] = r.uint64()
266 }
267
268 items[i].nameIndex = nameIndex
269
270 uniquePkgPaths[pkgPath] = true
271 }
272
273 if len(uniquePkgPaths) != len(items) {
274 reportf("found duplicate PkgPaths while reading export data manifest: %v", items)
275 }
276
277
278
279 if err := getPackages(items); err != nil {
280 return nil, err
281 }
282
283
284 pkgList := make([]*types.Package, len(items))
285 for i, item := range items {
286 pkg := item.Pkg
287 if pkg == nil {
288 errorf("internal error: getPackages returned nil package for %q", item.Path)
289 } else if pkg.Path() != item.Path {
290 errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path)
291 } else if pkg.Name() != item.Name {
292 errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name)
293 }
294 p.pkgCache[item.pathOffset] = pkg
295 p.pkgIndex[pkg] = item.nameIndex
296 pkgList[i] = pkg
297 }
298
299 if bundle {
300 pkgs = make([]*types.Package, r.uint64())
301 for i := range pkgs {
302 pkg := p.pkgAt(r.uint64())
303 imps := make([]*types.Package, r.uint64())
304 for j := range imps {
305 imps[j] = p.pkgAt(r.uint64())
306 }
307 pkg.SetImports(imps)
308 pkgs[i] = pkg
309 }
310 } else {
311 if len(pkgList) == 0 {
312 errorf("no packages found for %s", path)
313 panic("unreachable")
314 }
315 pkgs = pkgList[:1]
316
317
318 list := slices.Clone(pkgList[1:])
319 sort.Sort(byPath(list))
320 pkgs[0].SetImports(list)
321 }
322
323 for _, pkg := range pkgs {
324 if pkg.Complete() {
325 continue
326 }
327
328 names := make([]string, 0, len(p.pkgIndex[pkg]))
329 for name := range p.pkgIndex[pkg] {
330 names = append(names, name)
331 }
332 sort.Strings(names)
333 for _, name := range names {
334 p.doDecl(pkg, name)
335 }
336
337
338 pkg.MarkComplete()
339 }
340
341
342
343
344
345
346 for _, d := range p.later {
347 d.t.SetConstraint(d.constraint)
348 }
349
350 for _, typ := range p.interfaceList {
351 typ.Complete()
352 }
353
354
355 for _, typ := range p.instanceList {
356 if iface, _ := typ.Underlying().(*types.Interface); iface != nil {
357 iface.Complete()
358 }
359 }
360
361 return pkgs, nil
362 }
363
364 type setConstraintArgs struct {
365 t *types.TypeParam
366 constraint types.Type
367 }
368
369 type iimporter struct {
370 version int
371 ipath string
372
373 shallow bool
374 reportf ReportFunc
375
376 stringData []byte
377 stringCache map[uint64]string
378 fileOffset []uint64
379 fileData []byte
380 fileCache []*token.File
381 pkgCache map[uint64]*types.Package
382
383 declData []byte
384 pkgIndex map[*types.Package]map[string]uint64
385 typCache map[uint64]types.Type
386 tparamIndex map[ident]types.Type
387
388 fake fakeFileSet
389 interfaceList []*types.Interface
390
391
392
393
394
395 instanceList []types.Type
396
397
398 later []setConstraintArgs
399
400 indent int
401 }
402
403 func (p *iimporter) trace(format string, args ...any) {
404 if !trace {
405
406
407 return
408 }
409 fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
410 }
411
412 func (p *iimporter) doDecl(pkg *types.Package, name string) {
413 if debug {
414 p.trace("import decl %s", name)
415 p.indent++
416 defer func() {
417 p.indent--
418 p.trace("=> %s", name)
419 }()
420 }
421
422 if obj := pkg.Scope().Lookup(name); obj != nil {
423 return
424 }
425
426 off, ok := p.pkgIndex[pkg][name]
427 if !ok {
428
429
430
431 errorf("%v.%v not in index", pkg, name)
432 }
433
434 r := &importReader{p: p}
435 r.declReader.Reset(p.declData[off:])
436
437 r.obj(pkg, name)
438 }
439
440 func (p *iimporter) stringAt(off uint64) string {
441 if s, ok := p.stringCache[off]; ok {
442 return s
443 }
444
445 slen, n := binary.Uvarint(p.stringData[off:])
446 if n <= 0 {
447 errorf("varint failed")
448 }
449 spos := off + uint64(n)
450 s := string(p.stringData[spos : spos+slen])
451 p.stringCache[off] = s
452 return s
453 }
454
455 func (p *iimporter) fileAt(index uint64) *token.File {
456 file := p.fileCache[index]
457 if file == nil {
458 off := p.fileOffset[index]
459 file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath})
460 p.fileCache[index] = file
461 }
462 return file
463 }
464
465 func (p *iimporter) decodeFile(rd intReader) *token.File {
466 filename := p.stringAt(rd.uint64())
467 size := int(rd.uint64())
468 file := p.fake.fset.AddFile(filename, -1, size)
469
470
471
472
473
474
475
476
477
478
479 lines := make([]int, int(rd.uint64()))
480 var index, offset int
481 for i, n := 0, int(rd.uint64()); i < n; i++ {
482 index += int(rd.uint64())
483 offset += int(rd.uint64())
484 lines[index] = offset
485
486
487 for j := index - 1; j > 0 && lines[j] == 0; j-- {
488 lines[j] = lines[j+1] - 1
489 }
490 }
491
492
493 for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- {
494 size--
495 lines[j] = size
496 }
497
498 if !file.SetLines(lines) {
499 errorf("SetLines failed: %d", lines)
500 }
501 return file
502 }
503
504 func (p *iimporter) pkgAt(off uint64) *types.Package {
505 if pkg, ok := p.pkgCache[off]; ok {
506 return pkg
507 }
508 path := p.stringAt(off)
509 errorf("missing package %q in %q", path, p.ipath)
510 return nil
511 }
512
513 func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
514 if t, ok := p.typCache[off]; ok && canReuse(base, t) {
515 return t
516 }
517
518 if off < predeclReserved {
519 errorf("predeclared type missing from cache: %v", off)
520 }
521
522 r := &importReader{p: p}
523 r.declReader.Reset(p.declData[off-predeclReserved:])
524 t := r.doType(base)
525
526 if canReuse(base, t) {
527 p.typCache[off] = t
528 }
529 return t
530 }
531
532
533
534
535
536
537
538 func canReuse(def *types.Named, rhs types.Type) bool {
539 if def == nil {
540 return true
541 }
542 iface, _ := types.Unalias(rhs).(*types.Interface)
543 if iface == nil {
544 return true
545 }
546
547 return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
548 }
549
550 type importReader struct {
551 p *iimporter
552 declReader bytes.Reader
553 prevFile string
554 prevLine int64
555 prevColumn int64
556 }
557
558
559
560
561
562
563
564 var markBlack = func(name *types.TypeName) {}
565
566
567 func (r *importReader) obj(pkg *types.Package, name string) {
568 tag := r.byte()
569 pos := r.pos()
570
571 switch tag {
572 case aliasTag, genericAliasTag:
573 var tparams []*types.TypeParam
574 if tag == genericAliasTag {
575 tparams = r.tparamList()
576 }
577 typ := r.typ()
578 obj := aliases.New(pos, pkg, name, typ, tparams)
579 markBlack(obj)
580 r.declare(obj)
581
582 case constTag:
583 typ, val := r.value()
584
585 r.declare(types.NewConst(pos, pkg, name, typ, val))
586
587 case funcTag, genericFuncTag:
588 var tparams []*types.TypeParam
589 if tag == genericFuncTag {
590 tparams = r.tparamList()
591 }
592 sig := r.signature(pkg, nil, nil, tparams)
593 r.declare(types.NewFunc(pos, pkg, name, sig))
594
595 case typeTag, genericTypeTag:
596
597
598 obj := types.NewTypeName(pos, pkg, name, nil)
599 named := types.NewNamed(obj, nil, nil)
600
601 markBlack(obj)
602
603
604
605 r.declare(obj)
606 if tag == genericTypeTag {
607 tparams := r.tparamList()
608 named.SetTypeParams(tparams)
609 }
610
611 underlying := r.p.typAt(r.uint64(), named).Underlying()
612 named.SetUnderlying(underlying)
613
614 if !isInterface(underlying) {
615 for n := r.uint64(); n > 0; n-- {
616 mpos := r.pos()
617 mname := r.ident()
618 var tpars []*types.TypeParam
619 if r.p.version >= iexportVersionGenericMethods && r.bool() {
620 tpars = r.tparamList()
621 }
622 recv := r.param(pkg)
623
624
625
626
627 _, recvNamed := typesinternal.ReceiverNamed(recv)
628 targs := recvNamed.TypeArgs()
629 var rparams []*types.TypeParam
630 if targs.Len() > 0 {
631 rparams = make([]*types.TypeParam, targs.Len())
632 for i := range rparams {
633 rparams[i] = types.Unalias(targs.At(i)).(*types.TypeParam)
634 }
635 }
636 msig := r.signature(pkg, recv, rparams, tpars)
637 named.AddMethod(types.NewFunc(mpos, pkg, mname, msig))
638 }
639 }
640
641 case typeParamTag:
642
643
644
645 if r.p.version < iexportVersionGenerics {
646 errorf("unexpected type param type")
647 }
648 name0 := tparamName(name)
649 tn := types.NewTypeName(pos, pkg, name0, nil)
650 t := types.NewTypeParam(tn, nil)
651
652
653
654 id := ident{pkg, name}
655 r.p.tparamIndex[id] = t
656 var implicit bool
657 if r.p.version >= iexportVersionGo1_18 {
658 implicit = r.bool()
659 }
660 constraint := r.typ()
661 if implicit {
662 iface, _ := types.Unalias(constraint).(*types.Interface)
663 if iface == nil {
664 errorf("non-interface constraint marked implicit")
665 }
666 iface.MarkImplicit()
667 }
668
669
670
671
672 r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint})
673
674 case varTag:
675 typ := r.typ()
676
677 v := types.NewVar(pos, pkg, name, typ)
678 typesinternal.SetVarKind(v, typesinternal.PackageVar)
679 r.declare(v)
680
681 default:
682 errorf("unexpected tag: %v", tag)
683 }
684 }
685
686 func (r *importReader) declare(obj types.Object) {
687 obj.Pkg().Scope().Insert(obj)
688 }
689
690 func (r *importReader) value() (typ types.Type, val constant.Value) {
691 typ = r.typ()
692 if r.p.version >= iexportVersionGo1_18 {
693
694 _ = constant.Kind(r.int64())
695 }
696
697 switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
698 case types.IsBoolean:
699 val = constant.MakeBool(r.bool())
700
701 case types.IsString:
702 val = constant.MakeString(r.string())
703
704 case types.IsInteger:
705 var x big.Int
706 r.mpint(&x, b)
707 val = constant.Make(&x)
708
709 case types.IsFloat:
710 val = r.mpfloat(b)
711
712 case types.IsComplex:
713 re := r.mpfloat(b)
714 im := r.mpfloat(b)
715 val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
716
717 default:
718 if b.Kind() == types.Invalid {
719 val = constant.MakeUnknown()
720 return
721 }
722 errorf("unexpected type %v", typ)
723 panic("unreachable")
724 }
725
726 return
727 }
728
729 func intSize(b *types.Basic) (signed bool, maxBytes uint) {
730 if (b.Info() & types.IsUntyped) != 0 {
731 return true, 64
732 }
733
734 switch b.Kind() {
735 case types.Float32, types.Complex64:
736 return true, 3
737 case types.Float64, types.Complex128:
738 return true, 7
739 }
740
741 signed = (b.Info() & types.IsUnsigned) == 0
742 switch b.Kind() {
743 case types.Int8, types.Uint8:
744 maxBytes = 1
745 case types.Int16, types.Uint16:
746 maxBytes = 2
747 case types.Int32, types.Uint32:
748 maxBytes = 4
749 default:
750 maxBytes = 8
751 }
752
753 return
754 }
755
756 func (r *importReader) mpint(x *big.Int, typ *types.Basic) {
757 signed, maxBytes := intSize(typ)
758
759 maxSmall := 256 - maxBytes
760 if signed {
761 maxSmall = 256 - 2*maxBytes
762 }
763 if maxBytes == 1 {
764 maxSmall = 256
765 }
766
767 n, _ := r.declReader.ReadByte()
768 if uint(n) < maxSmall {
769 v := int64(n)
770 if signed {
771 v >>= 1
772 if n&1 != 0 {
773 v = ^v
774 }
775 }
776 x.SetInt64(v)
777 return
778 }
779
780 v := -n
781 if signed {
782 v = -(n &^ 1) >> 1
783 }
784 if v < 1 || uint(v) > maxBytes {
785 errorf("weird decoding: %v, %v => %v", n, signed, v)
786 }
787 b := make([]byte, v)
788 io.ReadFull(&r.declReader, b)
789 x.SetBytes(b)
790 if signed && n&1 != 0 {
791 x.Neg(x)
792 }
793 }
794
795 func (r *importReader) mpfloat(typ *types.Basic) constant.Value {
796 var mant big.Int
797 r.mpint(&mant, typ)
798 var f big.Float
799 f.SetInt(&mant)
800 if f.Sign() != 0 {
801 f.SetMantExp(&f, int(r.int64()))
802 }
803 return constant.Make(&f)
804 }
805
806 func (r *importReader) ident() string {
807 return r.string()
808 }
809
810 func (r *importReader) qualifiedIdent() (*types.Package, string) {
811 name := r.string()
812 pkg := r.pkg()
813 return pkg, name
814 }
815
816 func (r *importReader) pos() token.Pos {
817 if r.p.shallow {
818
819 return r.posv2()
820 }
821 if r.p.version >= iexportVersionPosCol {
822 r.posv1()
823 } else {
824 r.posv0()
825 }
826
827 if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
828 return token.NoPos
829 }
830 return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
831 }
832
833 func (r *importReader) posv0() {
834 delta := r.int64()
835 if delta != deltaNewFile {
836 r.prevLine += delta
837 } else if l := r.int64(); l == -1 {
838 r.prevLine += deltaNewFile
839 } else {
840 r.prevFile = r.string()
841 r.prevLine = l
842 }
843 }
844
845 func (r *importReader) posv1() {
846 delta := r.int64()
847 r.prevColumn += delta >> 1
848 if delta&1 != 0 {
849 delta = r.int64()
850 r.prevLine += delta >> 1
851 if delta&1 != 0 {
852 r.prevFile = r.string()
853 }
854 }
855 }
856
857 func (r *importReader) posv2() token.Pos {
858 file := r.uint64()
859 if file == 0 {
860 return token.NoPos
861 }
862 tf := r.p.fileAt(file - 1)
863 return tf.Pos(int(r.uint64()))
864 }
865
866 func (r *importReader) typ() types.Type {
867 return r.p.typAt(r.uint64(), nil)
868 }
869
870 func isInterface(t types.Type) bool {
871 _, ok := types.Unalias(t).(*types.Interface)
872 return ok
873 }
874
875 func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
876 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
877
878 func (r *importReader) doType(base *types.Named) (res types.Type) {
879 k := r.kind()
880 if debug {
881 r.p.trace("importing type %d (base: %v)", k, base)
882 r.p.indent++
883 defer func() {
884 r.p.indent--
885 r.p.trace("=> %s", res)
886 }()
887 }
888 switch k {
889 default:
890 errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
891 return nil
892
893 case aliasType, definedType:
894 pkg, name := r.qualifiedIdent()
895 r.p.doDecl(pkg, name)
896 return pkg.Scope().Lookup(name).(*types.TypeName).Type()
897 case pointerType:
898 return types.NewPointer(r.typ())
899 case sliceType:
900 return types.NewSlice(r.typ())
901 case arrayType:
902 n := r.uint64()
903 return types.NewArray(r.typ(), int64(n))
904 case chanType:
905 dir := chanDir(int(r.uint64()))
906 return types.NewChan(dir, r.typ())
907 case mapType:
908 return types.NewMap(r.typ(), r.typ())
909 case signatureType:
910 paramPkg := r.pkg()
911 return r.signature(paramPkg, nil, nil, nil)
912
913 case structType:
914 fieldPkg := r.pkg()
915
916 fields := make([]*types.Var, r.uint64())
917 tags := make([]string, len(fields))
918 for i := range fields {
919 var field *types.Var
920 if r.p.shallow {
921 field, _ = r.objectPathObject().(*types.Var)
922 }
923
924 fpos := r.pos()
925 fname := r.ident()
926 ftyp := r.typ()
927 emb := r.bool()
928 tag := r.string()
929
930
931
932
933
934
935
936 if field == nil {
937 field = types.NewField(fpos, fieldPkg, fname, ftyp, emb)
938 }
939
940 fields[i] = field
941 tags[i] = tag
942 }
943 return types.NewStruct(fields, tags)
944
945 case interfaceType:
946 methodPkg := r.pkg()
947
948 embeddeds := make([]types.Type, r.uint64())
949 for i := range embeddeds {
950 _ = r.pos()
951 embeddeds[i] = r.typ()
952 }
953
954 methods := make([]*types.Func, r.uint64())
955 for i := range methods {
956 var method *types.Func
957 if r.p.shallow {
958 method, _ = r.objectPathObject().(*types.Func)
959 }
960
961 mpos := r.pos()
962 mname := r.ident()
963
964
965
966 var recv *types.Var
967 if base != nil {
968 recv = types.NewVar(token.NoPos, methodPkg, "", base)
969 }
970 msig := r.signature(methodPkg, recv, nil, nil)
971
972 if method == nil {
973 method = types.NewFunc(mpos, methodPkg, mname, msig)
974 }
975 methods[i] = method
976 }
977
978 typ := types.NewInterfaceType(methods, embeddeds)
979 r.p.interfaceList = append(r.p.interfaceList, typ)
980 return typ
981
982 case typeParamType:
983 if r.p.version < iexportVersionGenerics {
984 errorf("unexpected type param type")
985 }
986 pkg, name := r.qualifiedIdent()
987 id := ident{pkg, name}
988 if t, ok := r.p.tparamIndex[id]; ok {
989
990 return t
991 }
992
993 r.p.doDecl(pkg, name)
994 return r.p.tparamIndex[id]
995
996 case instanceType:
997 if r.p.version < iexportVersionGenerics {
998 errorf("unexpected instantiation type")
999 }
1000
1001
1002 _ = r.pos()
1003 len := r.uint64()
1004 targs := make([]types.Type, len)
1005 for i := range targs {
1006 targs[i] = r.typ()
1007 }
1008 baseType := r.typ()
1009
1010
1011
1012 t, _ := types.Instantiate(nil, baseType, targs, false)
1013
1014
1015 r.p.instanceList = append(r.p.instanceList, t)
1016 return t
1017
1018 case unionType:
1019 if r.p.version < iexportVersionGenerics {
1020 errorf("unexpected instantiation type")
1021 }
1022 terms := make([]*types.Term, r.uint64())
1023 for i := range terms {
1024 terms[i] = types.NewTerm(r.bool(), r.typ())
1025 }
1026 return types.NewUnion(terms)
1027 }
1028 }
1029
1030 func (r *importReader) kind() itag {
1031 return itag(r.uint64())
1032 }
1033
1034
1035
1036
1037
1038
1039 func (r *importReader) objectPathObject() types.Object {
1040 objPath := objectpath.Path(r.string())
1041 if objPath == "" {
1042 return nil
1043 }
1044 pkg := r.pkg()
1045 obj, err := objectpath.Object(pkg, objPath)
1046 if err != nil {
1047 if r.p.reportf != nil {
1048 r.p.reportf("failed to find object for objectPath %q: %v", objPath, err)
1049 }
1050 }
1051 return obj
1052 }
1053
1054 func (r *importReader) signature(paramPkg *types.Package, recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature {
1055 params := r.paramList(paramPkg)
1056 results := r.paramList(paramPkg)
1057 variadic := params.Len() > 0 && r.bool()
1058 return types.NewSignatureType(recv, rparams, tparams, params, results, variadic)
1059 }
1060
1061 func (r *importReader) tparamList() []*types.TypeParam {
1062 n := r.uint64()
1063 if n == 0 {
1064 return nil
1065 }
1066 xs := make([]*types.TypeParam, n)
1067 for i := range xs {
1068
1069
1070 xs[i] = types.Unalias(r.typ()).(*types.TypeParam)
1071 }
1072 return xs
1073 }
1074
1075 func (r *importReader) paramList(pkg *types.Package) *types.Tuple {
1076 xs := make([]*types.Var, r.uint64())
1077 for i := range xs {
1078 xs[i] = r.param(pkg)
1079 }
1080 return types.NewTuple(xs...)
1081 }
1082
1083 func (r *importReader) param(pkg *types.Package) *types.Var {
1084 pos := r.pos()
1085 name := r.ident()
1086 typ := r.typ()
1087 return types.NewParam(pos, pkg, name, typ)
1088 }
1089
1090 func (r *importReader) bool() bool {
1091 return r.uint64() != 0
1092 }
1093
1094 func (r *importReader) int64() int64 {
1095 n, err := binary.ReadVarint(&r.declReader)
1096 if err != nil {
1097 errorf("readVarint: %v", err)
1098 }
1099 return n
1100 }
1101
1102 func (r *importReader) uint64() uint64 {
1103 n, err := binary.ReadUvarint(&r.declReader)
1104 if err != nil {
1105 errorf("readUvarint: %v", err)
1106 }
1107 return n
1108 }
1109
1110 func (r *importReader) byte() byte {
1111 x, err := r.declReader.ReadByte()
1112 if err != nil {
1113 errorf("declReader.ReadByte: %v", err)
1114 }
1115 return x
1116 }
1117
1118 type byPath []*types.Package
1119
1120 func (a byPath) Len() int { return len(a) }
1121 func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
1122 func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
1123
View as plain text