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