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