.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / go / internal / gcimporter / iimport.go
1 // Copyright 2018 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.
4
5 // Indexed package import.
6 // See cmd/compile/internal/gc/iexport.go for the export data format.
7
8 // This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go.
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         "sort"
21 )
22
23 type intReader struct {
24         *bytes.Reader
25         path string
26 }
27
28 func (r *intReader) int64() int64 {
29         i, err := binary.ReadVarint(r.Reader)
30         if err != nil {
31                 errorf("import %q: read varint error: %v", r.path, err)
32         }
33         return i
34 }
35
36 func (r *intReader) uint64() uint64 {
37         i, err := binary.ReadUvarint(r.Reader)
38         if err != nil {
39                 errorf("import %q: read varint error: %v", r.path, err)
40         }
41         return i
42 }
43
44 const predeclReserved = 32
45
46 type itag uint64
47
48 const (
49         // Types
50         definedType itag = iota
51         pointerType
52         sliceType
53         arrayType
54         chanType
55         mapType
56         signatureType
57         structType
58         interfaceType
59 )
60
61 // IImportData imports a package from the serialized package data
62 // and returns 0 and a reference to the package.
63 // If the export data version is not recognized or the format is otherwise
64 // compromised, an error is returned.
65 func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
66         pkgs, err := iimportCommon(fset, imports, data, false, path)
67         if err != nil {
68                 return 0, nil, err
69         }
70         return 0, pkgs[0], nil
71 }
72
73 // IImportBundle imports a set of packages from the serialized package bundle.
74 func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
75         return iimportCommon(fset, imports, data, true, "")
76 }
77
78 func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string) (pkgs []*types.Package, err error) {
79         const currentVersion = 1
80         version := int64(-1)
81         defer func() {
82                 if e := recover(); e != nil {
83                         if version > currentVersion {
84                                 err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
85                         } else {
86                                 err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
87                         }
88                 }
89         }()
90
91         r := &intReader{bytes.NewReader(data), path}
92
93         if bundle {
94                 bundleVersion := r.uint64()
95                 switch bundleVersion {
96                 case bundleVersion:
97                 default:
98                         errorf("unknown bundle format version %d", bundleVersion)
99                 }
100         }
101
102         version = int64(r.uint64())
103         switch version {
104         case currentVersion, 0:
105         default:
106                 errorf("unknown iexport format version %d", version)
107         }
108
109         sLen := int64(r.uint64())
110         dLen := int64(r.uint64())
111
112         whence, _ := r.Seek(0, io.SeekCurrent)
113         stringData := data[whence : whence+sLen]
114         declData := data[whence+sLen : whence+sLen+dLen]
115         r.Seek(sLen+dLen, io.SeekCurrent)
116
117         p := iimporter{
118                 ipath:   path,
119                 version: int(version),
120
121                 stringData:  stringData,
122                 stringCache: make(map[uint64]string),
123                 pkgCache:    make(map[uint64]*types.Package),
124
125                 declData: declData,
126                 pkgIndex: make(map[*types.Package]map[string]uint64),
127                 typCache: make(map[uint64]types.Type),
128
129                 fake: fakeFileSet{
130                         fset:  fset,
131                         files: make(map[string]*token.File),
132                 },
133         }
134
135         for i, pt := range predeclared() {
136                 p.typCache[uint64(i)] = pt
137         }
138
139         pkgList := make([]*types.Package, r.uint64())
140         for i := range pkgList {
141                 pkgPathOff := r.uint64()
142                 pkgPath := p.stringAt(pkgPathOff)
143                 pkgName := p.stringAt(r.uint64())
144                 _ = r.uint64() // package height; unused by go/types
145
146                 if pkgPath == "" {
147                         pkgPath = path
148                 }
149                 pkg := imports[pkgPath]
150                 if pkg == nil {
151                         pkg = types.NewPackage(pkgPath, pkgName)
152                         imports[pkgPath] = pkg
153                 } else if pkg.Name() != pkgName {
154                         errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
155                 }
156
157                 p.pkgCache[pkgPathOff] = pkg
158
159                 nameIndex := make(map[string]uint64)
160                 for nSyms := r.uint64(); nSyms > 0; nSyms-- {
161                         name := p.stringAt(r.uint64())
162                         nameIndex[name] = r.uint64()
163                 }
164
165                 p.pkgIndex[pkg] = nameIndex
166                 pkgList[i] = pkg
167         }
168
169         if bundle {
170                 pkgs = make([]*types.Package, r.uint64())
171                 for i := range pkgs {
172                         pkg := p.pkgAt(r.uint64())
173                         imps := make([]*types.Package, r.uint64())
174                         for j := range imps {
175                                 imps[j] = p.pkgAt(r.uint64())
176                         }
177                         pkg.SetImports(imps)
178                         pkgs[i] = pkg
179                 }
180         } else {
181                 if len(pkgList) == 0 {
182                         errorf("no packages found for %s", path)
183                         panic("unreachable")
184                 }
185                 pkgs = pkgList[:1]
186
187                 // record all referenced packages as imports
188                 list := append(([]*types.Package)(nil), pkgList[1:]...)
189                 sort.Sort(byPath(list))
190                 pkgs[0].SetImports(list)
191         }
192
193         for _, pkg := range pkgs {
194                 if pkg.Complete() {
195                         continue
196                 }
197
198                 names := make([]string, 0, len(p.pkgIndex[pkg]))
199                 for name := range p.pkgIndex[pkg] {
200                         names = append(names, name)
201                 }
202                 sort.Strings(names)
203                 for _, name := range names {
204                         p.doDecl(pkg, name)
205                 }
206
207                 // package was imported completely and without errors
208                 pkg.MarkComplete()
209         }
210
211         for _, typ := range p.interfaceList {
212                 typ.Complete()
213         }
214
215         return pkgs, nil
216 }
217
218 type iimporter struct {
219         ipath   string
220         version int
221
222         stringData  []byte
223         stringCache map[uint64]string
224         pkgCache    map[uint64]*types.Package
225
226         declData []byte
227         pkgIndex map[*types.Package]map[string]uint64
228         typCache map[uint64]types.Type
229
230         fake          fakeFileSet
231         interfaceList []*types.Interface
232 }
233
234 func (p *iimporter) doDecl(pkg *types.Package, name string) {
235         // See if we've already imported this declaration.
236         if obj := pkg.Scope().Lookup(name); obj != nil {
237                 return
238         }
239
240         off, ok := p.pkgIndex[pkg][name]
241         if !ok {
242                 errorf("%v.%v not in index", pkg, name)
243         }
244
245         r := &importReader{p: p, currPkg: pkg}
246         r.declReader.Reset(p.declData[off:])
247
248         r.obj(name)
249 }
250
251 func (p *iimporter) stringAt(off uint64) string {
252         if s, ok := p.stringCache[off]; ok {
253                 return s
254         }
255
256         slen, n := binary.Uvarint(p.stringData[off:])
257         if n <= 0 {
258                 errorf("varint failed")
259         }
260         spos := off + uint64(n)
261         s := string(p.stringData[spos : spos+slen])
262         p.stringCache[off] = s
263         return s
264 }
265
266 func (p *iimporter) pkgAt(off uint64) *types.Package {
267         if pkg, ok := p.pkgCache[off]; ok {
268                 return pkg
269         }
270         path := p.stringAt(off)
271         errorf("missing package %q in %q", path, p.ipath)
272         return nil
273 }
274
275 func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
276         if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) {
277                 return t
278         }
279
280         if off < predeclReserved {
281                 errorf("predeclared type missing from cache: %v", off)
282         }
283
284         r := &importReader{p: p}
285         r.declReader.Reset(p.declData[off-predeclReserved:])
286         t := r.doType(base)
287
288         if base == nil || !isInterface(t) {
289                 p.typCache[off] = t
290         }
291         return t
292 }
293
294 type importReader struct {
295         p          *iimporter
296         declReader bytes.Reader
297         currPkg    *types.Package
298         prevFile   string
299         prevLine   int64
300         prevColumn int64
301 }
302
303 func (r *importReader) obj(name string) {
304         tag := r.byte()
305         pos := r.pos()
306
307         switch tag {
308         case 'A':
309                 typ := r.typ()
310
311                 r.declare(types.NewTypeName(pos, r.currPkg, name, typ))
312
313         case 'C':
314                 typ, val := r.value()
315
316                 r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
317
318         case 'F':
319                 sig := r.signature(nil)
320
321                 r.declare(types.NewFunc(pos, r.currPkg, name, sig))
322
323         case 'T':
324                 // Types can be recursive. We need to setup a stub
325                 // declaration before recursing.
326                 obj := types.NewTypeName(pos, r.currPkg, name, nil)
327                 named := types.NewNamed(obj, nil, nil)
328                 r.declare(obj)
329
330                 underlying := r.p.typAt(r.uint64(), named).Underlying()
331                 named.SetUnderlying(underlying)
332
333                 if !isInterface(underlying) {
334                         for n := r.uint64(); n > 0; n-- {
335                                 mpos := r.pos()
336                                 mname := r.ident()
337                                 recv := r.param()
338                                 msig := r.signature(recv)
339
340                                 named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
341                         }
342                 }
343
344         case 'V':
345                 typ := r.typ()
346
347                 r.declare(types.NewVar(pos, r.currPkg, name, typ))
348
349         default:
350                 errorf("unexpected tag: %v", tag)
351         }
352 }
353
354 func (r *importReader) declare(obj types.Object) {
355         obj.Pkg().Scope().Insert(obj)
356 }
357
358 func (r *importReader) value() (typ types.Type, val constant.Value) {
359         typ = r.typ()
360
361         switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
362         case types.IsBoolean:
363                 val = constant.MakeBool(r.bool())
364
365         case types.IsString:
366                 val = constant.MakeString(r.string())
367
368         case types.IsInteger:
369                 val = r.mpint(b)
370
371         case types.IsFloat:
372                 val = r.mpfloat(b)
373
374         case types.IsComplex:
375                 re := r.mpfloat(b)
376                 im := r.mpfloat(b)
377                 val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
378
379         default:
380                 if b.Kind() == types.Invalid {
381                         val = constant.MakeUnknown()
382                         return
383                 }
384                 errorf("unexpected type %v", typ) // panics
385                 panic("unreachable")
386         }
387
388         return
389 }
390
391 func intSize(b *types.Basic) (signed bool, maxBytes uint) {
392         if (b.Info() & types.IsUntyped) != 0 {
393                 return true, 64
394         }
395
396         switch b.Kind() {
397         case types.Float32, types.Complex64:
398                 return true, 3
399         case types.Float64, types.Complex128:
400                 return true, 7
401         }
402
403         signed = (b.Info() & types.IsUnsigned) == 0
404         switch b.Kind() {
405         case types.Int8, types.Uint8:
406                 maxBytes = 1
407         case types.Int16, types.Uint16:
408                 maxBytes = 2
409         case types.Int32, types.Uint32:
410                 maxBytes = 4
411         default:
412                 maxBytes = 8
413         }
414
415         return
416 }
417
418 func (r *importReader) mpint(b *types.Basic) constant.Value {
419         signed, maxBytes := intSize(b)
420
421         maxSmall := 256 - maxBytes
422         if signed {
423                 maxSmall = 256 - 2*maxBytes
424         }
425         if maxBytes == 1 {
426                 maxSmall = 256
427         }
428
429         n, _ := r.declReader.ReadByte()
430         if uint(n) < maxSmall {
431                 v := int64(n)
432                 if signed {
433                         v >>= 1
434                         if n&1 != 0 {
435                                 v = ^v
436                         }
437                 }
438                 return constant.MakeInt64(v)
439         }
440
441         v := -n
442         if signed {
443                 v = -(n &^ 1) >> 1
444         }
445         if v < 1 || uint(v) > maxBytes {
446                 errorf("weird decoding: %v, %v => %v", n, signed, v)
447         }
448
449         buf := make([]byte, v)
450         io.ReadFull(&r.declReader, buf)
451
452         // convert to little endian
453         // TODO(gri) go/constant should have a more direct conversion function
454         //           (e.g., once it supports a big.Float based implementation)
455         for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
456                 buf[i], buf[j] = buf[j], buf[i]
457         }
458
459         x := constant.MakeFromBytes(buf)
460         if signed && n&1 != 0 {
461                 x = constant.UnaryOp(token.SUB, x, 0)
462         }
463         return x
464 }
465
466 func (r *importReader) mpfloat(b *types.Basic) constant.Value {
467         x := r.mpint(b)
468         if constant.Sign(x) == 0 {
469                 return x
470         }
471
472         exp := r.int64()
473         switch {
474         case exp > 0:
475                 x = constant.Shift(x, token.SHL, uint(exp))
476         case exp < 0:
477                 d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
478                 x = constant.BinaryOp(x, token.QUO, d)
479         }
480         return x
481 }
482
483 func (r *importReader) ident() string {
484         return r.string()
485 }
486
487 func (r *importReader) qualifiedIdent() (*types.Package, string) {
488         name := r.string()
489         pkg := r.pkg()
490         return pkg, name
491 }
492
493 func (r *importReader) pos() token.Pos {
494         if r.p.version >= 1 {
495                 r.posv1()
496         } else {
497                 r.posv0()
498         }
499
500         if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
501                 return token.NoPos
502         }
503         return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
504 }
505
506 func (r *importReader) posv0() {
507         delta := r.int64()
508         if delta != deltaNewFile {
509                 r.prevLine += delta
510         } else if l := r.int64(); l == -1 {
511                 r.prevLine += deltaNewFile
512         } else {
513                 r.prevFile = r.string()
514                 r.prevLine = l
515         }
516 }
517
518 func (r *importReader) posv1() {
519         delta := r.int64()
520         r.prevColumn += delta >> 1
521         if delta&1 != 0 {
522                 delta = r.int64()
523                 r.prevLine += delta >> 1
524                 if delta&1 != 0 {
525                         r.prevFile = r.string()
526                 }
527         }
528 }
529
530 func (r *importReader) typ() types.Type {
531         return r.p.typAt(r.uint64(), nil)
532 }
533
534 func isInterface(t types.Type) bool {
535         _, ok := t.(*types.Interface)
536         return ok
537 }
538
539 func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
540 func (r *importReader) string() string      { return r.p.stringAt(r.uint64()) }
541
542 func (r *importReader) doType(base *types.Named) types.Type {
543         switch k := r.kind(); k {
544         default:
545                 errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
546                 return nil
547
548         case definedType:
549                 pkg, name := r.qualifiedIdent()
550                 r.p.doDecl(pkg, name)
551                 return pkg.Scope().Lookup(name).(*types.TypeName).Type()
552         case pointerType:
553                 return types.NewPointer(r.typ())
554         case sliceType:
555                 return types.NewSlice(r.typ())
556         case arrayType:
557                 n := r.uint64()
558                 return types.NewArray(r.typ(), int64(n))
559         case chanType:
560                 dir := chanDir(int(r.uint64()))
561                 return types.NewChan(dir, r.typ())
562         case mapType:
563                 return types.NewMap(r.typ(), r.typ())
564         case signatureType:
565                 r.currPkg = r.pkg()
566                 return r.signature(nil)
567
568         case structType:
569                 r.currPkg = r.pkg()
570
571                 fields := make([]*types.Var, r.uint64())
572                 tags := make([]string, len(fields))
573                 for i := range fields {
574                         fpos := r.pos()
575                         fname := r.ident()
576                         ftyp := r.typ()
577                         emb := r.bool()
578                         tag := r.string()
579
580                         fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
581                         tags[i] = tag
582                 }
583                 return types.NewStruct(fields, tags)
584
585         case interfaceType:
586                 r.currPkg = r.pkg()
587
588                 embeddeds := make([]types.Type, r.uint64())
589                 for i := range embeddeds {
590                         _ = r.pos()
591                         embeddeds[i] = r.typ()
592                 }
593
594                 methods := make([]*types.Func, r.uint64())
595                 for i := range methods {
596                         mpos := r.pos()
597                         mname := r.ident()
598
599                         // TODO(mdempsky): Matches bimport.go, but I
600                         // don't agree with this.
601                         var recv *types.Var
602                         if base != nil {
603                                 recv = types.NewVar(token.NoPos, r.currPkg, "", base)
604                         }
605
606                         msig := r.signature(recv)
607                         methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
608                 }
609
610                 typ := newInterface(methods, embeddeds)
611                 r.p.interfaceList = append(r.p.interfaceList, typ)
612                 return typ
613         }
614 }
615
616 func (r *importReader) kind() itag {
617         return itag(r.uint64())
618 }
619
620 func (r *importReader) signature(recv *types.Var) *types.Signature {
621         params := r.paramList()
622         results := r.paramList()
623         variadic := params.Len() > 0 && r.bool()
624         return types.NewSignature(recv, params, results, variadic)
625 }
626
627 func (r *importReader) paramList() *types.Tuple {
628         xs := make([]*types.Var, r.uint64())
629         for i := range xs {
630                 xs[i] = r.param()
631         }
632         return types.NewTuple(xs...)
633 }
634
635 func (r *importReader) param() *types.Var {
636         pos := r.pos()
637         name := r.ident()
638         typ := r.typ()
639         return types.NewParam(pos, r.currPkg, name, typ)
640 }
641
642 func (r *importReader) bool() bool {
643         return r.uint64() != 0
644 }
645
646 func (r *importReader) int64() int64 {
647         n, err := binary.ReadVarint(&r.declReader)
648         if err != nil {
649                 errorf("readVarint: %v", err)
650         }
651         return n
652 }
653
654 func (r *importReader) uint64() uint64 {
655         n, err := binary.ReadUvarint(&r.declReader)
656         if err != nil {
657                 errorf("readUvarint: %v", err)
658         }
659         return n
660 }
661
662 func (r *importReader) byte() byte {
663         x, err := r.declReader.ReadByte()
664         if err != nil {
665                 errorf("declReader.ReadByte: %v", err)
666         }
667         return x
668 }