Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / internal / gcimporter / iexport.go
1 // Copyright 2019 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 binary package export.
6 // This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go;
7 // see that file for specification of the format.
8
9 package gcimporter
10
11 import (
12         "bytes"
13         "encoding/binary"
14         "go/ast"
15         "go/constant"
16         "go/token"
17         "go/types"
18         "io"
19         "math/big"
20         "reflect"
21         "sort"
22 )
23
24 // Current indexed export format version. Increase with each format change.
25 // 0: Go1.11 encoding
26 const iexportVersion = 0
27
28 // IExportData returns the binary export data for pkg.
29 //
30 // If no file set is provided, position info will be missing.
31 // The package path of the top-level package will not be recorded,
32 // so that calls to IImportData can override with a provided package path.
33 func IExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
34         defer func() {
35                 if e := recover(); e != nil {
36                         if ierr, ok := e.(internalError); ok {
37                                 err = ierr
38                                 return
39                         }
40                         // Not an internal error; panic again.
41                         panic(e)
42                 }
43         }()
44
45         p := iexporter{
46                 out:         bytes.NewBuffer(nil),
47                 fset:        fset,
48                 allPkgs:     map[*types.Package]bool{},
49                 stringIndex: map[string]uint64{},
50                 declIndex:   map[types.Object]uint64{},
51                 typIndex:    map[types.Type]uint64{},
52                 localpkg:    pkg,
53         }
54
55         for i, pt := range predeclared() {
56                 p.typIndex[pt] = uint64(i)
57         }
58         if len(p.typIndex) > predeclReserved {
59                 panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved))
60         }
61
62         // Initialize work queue with exported declarations.
63         scope := pkg.Scope()
64         for _, name := range scope.Names() {
65                 if ast.IsExported(name) {
66                         p.pushDecl(scope.Lookup(name))
67                 }
68         }
69
70         // Loop until no more work.
71         for !p.declTodo.empty() {
72                 p.doDecl(p.declTodo.popHead())
73         }
74
75         // Append indices to data0 section.
76         dataLen := uint64(p.data0.Len())
77         w := p.newWriter()
78         w.writeIndex(p.declIndex)
79         w.flush()
80
81         // Assemble header.
82         var hdr intWriter
83         hdr.WriteByte('i')
84         hdr.uint64(iexportVersion)
85         hdr.uint64(uint64(p.strings.Len()))
86         hdr.uint64(dataLen)
87
88         // Flush output.
89         io.Copy(p.out, &hdr)
90         io.Copy(p.out, &p.strings)
91         io.Copy(p.out, &p.data0)
92
93         return p.out.Bytes(), nil
94 }
95
96 // writeIndex writes out an object index. mainIndex indicates whether
97 // we're writing out the main index, which is also read by
98 // non-compiler tools and includes a complete package description
99 // (i.e., name and height).
100 func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
101         // Build a map from packages to objects from that package.
102         pkgObjs := map[*types.Package][]types.Object{}
103
104         // For the main index, make sure to include every package that
105         // we reference, even if we're not exporting (or reexporting)
106         // any symbols from it.
107         pkgObjs[w.p.localpkg] = nil
108         for pkg := range w.p.allPkgs {
109                 pkgObjs[pkg] = nil
110         }
111
112         for obj := range index {
113                 pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], obj)
114         }
115
116         var pkgs []*types.Package
117         for pkg, objs := range pkgObjs {
118                 pkgs = append(pkgs, pkg)
119
120                 sort.Slice(objs, func(i, j int) bool {
121                         return objs[i].Name() < objs[j].Name()
122                 })
123         }
124
125         sort.Slice(pkgs, func(i, j int) bool {
126                 return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j])
127         })
128
129         w.uint64(uint64(len(pkgs)))
130         for _, pkg := range pkgs {
131                 w.string(w.exportPath(pkg))
132                 w.string(pkg.Name())
133                 w.uint64(uint64(0)) // package height is not needed for go/types
134
135                 objs := pkgObjs[pkg]
136                 w.uint64(uint64(len(objs)))
137                 for _, obj := range objs {
138                         w.string(obj.Name())
139                         w.uint64(index[obj])
140                 }
141         }
142 }
143
144 type iexporter struct {
145         fset *token.FileSet
146         out  *bytes.Buffer
147
148         localpkg *types.Package
149
150         // allPkgs tracks all packages that have been referenced by
151         // the export data, so we can ensure to include them in the
152         // main index.
153         allPkgs map[*types.Package]bool
154
155         declTodo objQueue
156
157         strings     intWriter
158         stringIndex map[string]uint64
159
160         data0     intWriter
161         declIndex map[types.Object]uint64
162         typIndex  map[types.Type]uint64
163 }
164
165 // stringOff returns the offset of s within the string section.
166 // If not already present, it's added to the end.
167 func (p *iexporter) stringOff(s string) uint64 {
168         off, ok := p.stringIndex[s]
169         if !ok {
170                 off = uint64(p.strings.Len())
171                 p.stringIndex[s] = off
172
173                 p.strings.uint64(uint64(len(s)))
174                 p.strings.WriteString(s)
175         }
176         return off
177 }
178
179 // pushDecl adds n to the declaration work queue, if not already present.
180 func (p *iexporter) pushDecl(obj types.Object) {
181         // Package unsafe is known to the compiler and predeclared.
182         assert(obj.Pkg() != types.Unsafe)
183
184         if _, ok := p.declIndex[obj]; ok {
185                 return
186         }
187
188         p.declIndex[obj] = ^uint64(0) // mark n present in work queue
189         p.declTodo.pushTail(obj)
190 }
191
192 // exportWriter handles writing out individual data section chunks.
193 type exportWriter struct {
194         p *iexporter
195
196         data     intWriter
197         currPkg  *types.Package
198         prevFile string
199         prevLine int64
200 }
201
202 func (w *exportWriter) exportPath(pkg *types.Package) string {
203         if pkg == w.p.localpkg {
204                 return ""
205         }
206         return pkg.Path()
207 }
208
209 func (p *iexporter) doDecl(obj types.Object) {
210         w := p.newWriter()
211         w.setPkg(obj.Pkg(), false)
212
213         switch obj := obj.(type) {
214         case *types.Var:
215                 w.tag('V')
216                 w.pos(obj.Pos())
217                 w.typ(obj.Type(), obj.Pkg())
218
219         case *types.Func:
220                 sig, _ := obj.Type().(*types.Signature)
221                 if sig.Recv() != nil {
222                         panic(internalErrorf("unexpected method: %v", sig))
223                 }
224                 w.tag('F')
225                 w.pos(obj.Pos())
226                 w.signature(sig)
227
228         case *types.Const:
229                 w.tag('C')
230                 w.pos(obj.Pos())
231                 w.value(obj.Type(), obj.Val())
232
233         case *types.TypeName:
234                 if obj.IsAlias() {
235                         w.tag('A')
236                         w.pos(obj.Pos())
237                         w.typ(obj.Type(), obj.Pkg())
238                         break
239                 }
240
241                 // Defined type.
242                 w.tag('T')
243                 w.pos(obj.Pos())
244
245                 underlying := obj.Type().Underlying()
246                 w.typ(underlying, obj.Pkg())
247
248                 t := obj.Type()
249                 if types.IsInterface(t) {
250                         break
251                 }
252
253                 named, ok := t.(*types.Named)
254                 if !ok {
255                         panic(internalErrorf("%s is not a defined type", t))
256                 }
257
258                 n := named.NumMethods()
259                 w.uint64(uint64(n))
260                 for i := 0; i < n; i++ {
261                         m := named.Method(i)
262                         w.pos(m.Pos())
263                         w.string(m.Name())
264                         sig, _ := m.Type().(*types.Signature)
265                         w.param(sig.Recv())
266                         w.signature(sig)
267                 }
268
269         default:
270                 panic(internalErrorf("unexpected object: %v", obj))
271         }
272
273         p.declIndex[obj] = w.flush()
274 }
275
276 func (w *exportWriter) tag(tag byte) {
277         w.data.WriteByte(tag)
278 }
279
280 func (w *exportWriter) pos(pos token.Pos) {
281         if w.p.fset == nil {
282                 w.int64(0)
283                 return
284         }
285
286         p := w.p.fset.Position(pos)
287         file := p.Filename
288         line := int64(p.Line)
289
290         // When file is the same as the last position (common case),
291         // we can save a few bytes by delta encoding just the line
292         // number.
293         //
294         // Note: Because data objects may be read out of order (or not
295         // at all), we can only apply delta encoding within a single
296         // object. This is handled implicitly by tracking prevFile and
297         // prevLine as fields of exportWriter.
298
299         if file == w.prevFile {
300                 delta := line - w.prevLine
301                 w.int64(delta)
302                 if delta == deltaNewFile {
303                         w.int64(-1)
304                 }
305         } else {
306                 w.int64(deltaNewFile)
307                 w.int64(line) // line >= 0
308                 w.string(file)
309                 w.prevFile = file
310         }
311         w.prevLine = line
312 }
313
314 func (w *exportWriter) pkg(pkg *types.Package) {
315         // Ensure any referenced packages are declared in the main index.
316         w.p.allPkgs[pkg] = true
317
318         w.string(w.exportPath(pkg))
319 }
320
321 func (w *exportWriter) qualifiedIdent(obj types.Object) {
322         // Ensure any referenced declarations are written out too.
323         w.p.pushDecl(obj)
324
325         w.string(obj.Name())
326         w.pkg(obj.Pkg())
327 }
328
329 func (w *exportWriter) typ(t types.Type, pkg *types.Package) {
330         w.data.uint64(w.p.typOff(t, pkg))
331 }
332
333 func (p *iexporter) newWriter() *exportWriter {
334         return &exportWriter{p: p}
335 }
336
337 func (w *exportWriter) flush() uint64 {
338         off := uint64(w.p.data0.Len())
339         io.Copy(&w.p.data0, &w.data)
340         return off
341 }
342
343 func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 {
344         off, ok := p.typIndex[t]
345         if !ok {
346                 w := p.newWriter()
347                 w.doTyp(t, pkg)
348                 off = predeclReserved + w.flush()
349                 p.typIndex[t] = off
350         }
351         return off
352 }
353
354 func (w *exportWriter) startType(k itag) {
355         w.data.uint64(uint64(k))
356 }
357
358 func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
359         switch t := t.(type) {
360         case *types.Named:
361                 w.startType(definedType)
362                 w.qualifiedIdent(t.Obj())
363
364         case *types.Pointer:
365                 w.startType(pointerType)
366                 w.typ(t.Elem(), pkg)
367
368         case *types.Slice:
369                 w.startType(sliceType)
370                 w.typ(t.Elem(), pkg)
371
372         case *types.Array:
373                 w.startType(arrayType)
374                 w.uint64(uint64(t.Len()))
375                 w.typ(t.Elem(), pkg)
376
377         case *types.Chan:
378                 w.startType(chanType)
379                 // 1 RecvOnly; 2 SendOnly; 3 SendRecv
380                 var dir uint64
381                 switch t.Dir() {
382                 case types.RecvOnly:
383                         dir = 1
384                 case types.SendOnly:
385                         dir = 2
386                 case types.SendRecv:
387                         dir = 3
388                 }
389                 w.uint64(dir)
390                 w.typ(t.Elem(), pkg)
391
392         case *types.Map:
393                 w.startType(mapType)
394                 w.typ(t.Key(), pkg)
395                 w.typ(t.Elem(), pkg)
396
397         case *types.Signature:
398                 w.startType(signatureType)
399                 w.setPkg(pkg, true)
400                 w.signature(t)
401
402         case *types.Struct:
403                 w.startType(structType)
404                 w.setPkg(pkg, true)
405
406                 n := t.NumFields()
407                 w.uint64(uint64(n))
408                 for i := 0; i < n; i++ {
409                         f := t.Field(i)
410                         w.pos(f.Pos())
411                         w.string(f.Name())
412                         w.typ(f.Type(), pkg)
413                         w.bool(f.Anonymous())
414                         w.string(t.Tag(i)) // note (or tag)
415                 }
416
417         case *types.Interface:
418                 w.startType(interfaceType)
419                 w.setPkg(pkg, true)
420
421                 n := t.NumEmbeddeds()
422                 w.uint64(uint64(n))
423                 for i := 0; i < n; i++ {
424                         f := t.Embedded(i)
425                         w.pos(f.Obj().Pos())
426                         w.typ(f.Obj().Type(), f.Obj().Pkg())
427                 }
428
429                 n = t.NumExplicitMethods()
430                 w.uint64(uint64(n))
431                 for i := 0; i < n; i++ {
432                         m := t.ExplicitMethod(i)
433                         w.pos(m.Pos())
434                         w.string(m.Name())
435                         sig, _ := m.Type().(*types.Signature)
436                         w.signature(sig)
437                 }
438
439         default:
440                 panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t)))
441         }
442 }
443
444 func (w *exportWriter) setPkg(pkg *types.Package, write bool) {
445         if write {
446                 w.pkg(pkg)
447         }
448
449         w.currPkg = pkg
450 }
451
452 func (w *exportWriter) signature(sig *types.Signature) {
453         w.paramList(sig.Params())
454         w.paramList(sig.Results())
455         if sig.Params().Len() > 0 {
456                 w.bool(sig.Variadic())
457         }
458 }
459
460 func (w *exportWriter) paramList(tup *types.Tuple) {
461         n := tup.Len()
462         w.uint64(uint64(n))
463         for i := 0; i < n; i++ {
464                 w.param(tup.At(i))
465         }
466 }
467
468 func (w *exportWriter) param(obj types.Object) {
469         w.pos(obj.Pos())
470         w.localIdent(obj)
471         w.typ(obj.Type(), obj.Pkg())
472 }
473
474 func (w *exportWriter) value(typ types.Type, v constant.Value) {
475         w.typ(typ, nil)
476
477         switch v.Kind() {
478         case constant.Bool:
479                 w.bool(constant.BoolVal(v))
480         case constant.Int:
481                 var i big.Int
482                 if i64, exact := constant.Int64Val(v); exact {
483                         i.SetInt64(i64)
484                 } else if ui64, exact := constant.Uint64Val(v); exact {
485                         i.SetUint64(ui64)
486                 } else {
487                         i.SetString(v.ExactString(), 10)
488                 }
489                 w.mpint(&i, typ)
490         case constant.Float:
491                 f := constantToFloat(v)
492                 w.mpfloat(f, typ)
493         case constant.Complex:
494                 w.mpfloat(constantToFloat(constant.Real(v)), typ)
495                 w.mpfloat(constantToFloat(constant.Imag(v)), typ)
496         case constant.String:
497                 w.string(constant.StringVal(v))
498         case constant.Unknown:
499                 // package contains type errors
500         default:
501                 panic(internalErrorf("unexpected value %v (%T)", v, v))
502         }
503 }
504
505 // constantToFloat converts a constant.Value with kind constant.Float to a
506 // big.Float.
507 func constantToFloat(x constant.Value) *big.Float {
508         assert(x.Kind() == constant.Float)
509         // Use the same floating-point precision (512) as cmd/compile
510         // (see Mpprec in cmd/compile/internal/gc/mpfloat.go).
511         const mpprec = 512
512         var f big.Float
513         f.SetPrec(mpprec)
514         if v, exact := constant.Float64Val(x); exact {
515                 // float64
516                 f.SetFloat64(v)
517         } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
518                 // TODO(gri): add big.Rat accessor to constant.Value.
519                 n := valueToRat(num)
520                 d := valueToRat(denom)
521                 f.SetRat(n.Quo(n, d))
522         } else {
523                 // Value too large to represent as a fraction => inaccessible.
524                 // TODO(gri): add big.Float accessor to constant.Value.
525                 _, ok := f.SetString(x.ExactString())
526                 assert(ok)
527         }
528         return &f
529 }
530
531 // mpint exports a multi-precision integer.
532 //
533 // For unsigned types, small values are written out as a single
534 // byte. Larger values are written out as a length-prefixed big-endian
535 // byte string, where the length prefix is encoded as its complement.
536 // For example, bytes 0, 1, and 2 directly represent the integer
537 // values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-,
538 // 2-, and 3-byte big-endian string follow.
539 //
540 // Encoding for signed types use the same general approach as for
541 // unsigned types, except small values use zig-zag encoding and the
542 // bottom bit of length prefix byte for large values is reserved as a
543 // sign bit.
544 //
545 // The exact boundary between small and large encodings varies
546 // according to the maximum number of bytes needed to encode a value
547 // of type typ. As a special case, 8-bit types are always encoded as a
548 // single byte.
549 //
550 // TODO(mdempsky): Is this level of complexity really worthwhile?
551 func (w *exportWriter) mpint(x *big.Int, typ types.Type) {
552         basic, ok := typ.Underlying().(*types.Basic)
553         if !ok {
554                 panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying()))
555         }
556
557         signed, maxBytes := intSize(basic)
558
559         negative := x.Sign() < 0
560         if !signed && negative {
561                 panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x))
562         }
563
564         b := x.Bytes()
565         if len(b) > 0 && b[0] == 0 {
566                 panic(internalErrorf("leading zeros"))
567         }
568         if uint(len(b)) > maxBytes {
569                 panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x))
570         }
571
572         maxSmall := 256 - maxBytes
573         if signed {
574                 maxSmall = 256 - 2*maxBytes
575         }
576         if maxBytes == 1 {
577                 maxSmall = 256
578         }
579
580         // Check if x can use small value encoding.
581         if len(b) <= 1 {
582                 var ux uint
583                 if len(b) == 1 {
584                         ux = uint(b[0])
585                 }
586                 if signed {
587                         ux <<= 1
588                         if negative {
589                                 ux--
590                         }
591                 }
592                 if ux < maxSmall {
593                         w.data.WriteByte(byte(ux))
594                         return
595                 }
596         }
597
598         n := 256 - uint(len(b))
599         if signed {
600                 n = 256 - 2*uint(len(b))
601                 if negative {
602                         n |= 1
603                 }
604         }
605         if n < maxSmall || n >= 256 {
606                 panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n))
607         }
608
609         w.data.WriteByte(byte(n))
610         w.data.Write(b)
611 }
612
613 // mpfloat exports a multi-precision floating point number.
614 //
615 // The number's value is decomposed into mantissa × 2**exponent, where
616 // mantissa is an integer. The value is written out as mantissa (as a
617 // multi-precision integer) and then the exponent, except exponent is
618 // omitted if mantissa is zero.
619 func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) {
620         if f.IsInf() {
621                 panic("infinite constant")
622         }
623
624         // Break into f = mant × 2**exp, with 0.5 <= mant < 1.
625         var mant big.Float
626         exp := int64(f.MantExp(&mant))
627
628         // Scale so that mant is an integer.
629         prec := mant.MinPrec()
630         mant.SetMantExp(&mant, int(prec))
631         exp -= int64(prec)
632
633         manti, acc := mant.Int(nil)
634         if acc != big.Exact {
635                 panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc))
636         }
637         w.mpint(manti, typ)
638         if manti.Sign() != 0 {
639                 w.int64(exp)
640         }
641 }
642
643 func (w *exportWriter) bool(b bool) bool {
644         var x uint64
645         if b {
646                 x = 1
647         }
648         w.uint64(x)
649         return b
650 }
651
652 func (w *exportWriter) int64(x int64)   { w.data.int64(x) }
653 func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
654 func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
655
656 func (w *exportWriter) localIdent(obj types.Object) {
657         // Anonymous parameters.
658         if obj == nil {
659                 w.string("")
660                 return
661         }
662
663         name := obj.Name()
664         if name == "_" {
665                 w.string("_")
666                 return
667         }
668
669         w.string(name)
670 }
671
672 type intWriter struct {
673         bytes.Buffer
674 }
675
676 func (w *intWriter) int64(x int64) {
677         var buf [binary.MaxVarintLen64]byte
678         n := binary.PutVarint(buf[:], x)
679         w.Write(buf[:n])
680 }
681
682 func (w *intWriter) uint64(x uint64) {
683         var buf [binary.MaxVarintLen64]byte
684         n := binary.PutUvarint(buf[:], x)
685         w.Write(buf[:n])
686 }
687
688 func assert(cond bool) {
689         if !cond {
690                 panic("internal error: assertion failed")
691         }
692 }
693
694 // The below is copied from go/src/cmd/compile/internal/gc/syntax.go.
695
696 // objQueue is a FIFO queue of types.Object. The zero value of objQueue is
697 // a ready-to-use empty queue.
698 type objQueue struct {
699         ring       []types.Object
700         head, tail int
701 }
702
703 // empty returns true if q contains no Nodes.
704 func (q *objQueue) empty() bool {
705         return q.head == q.tail
706 }
707
708 // pushTail appends n to the tail of the queue.
709 func (q *objQueue) pushTail(obj types.Object) {
710         if len(q.ring) == 0 {
711                 q.ring = make([]types.Object, 16)
712         } else if q.head+len(q.ring) == q.tail {
713                 // Grow the ring.
714                 nring := make([]types.Object, len(q.ring)*2)
715                 // Copy the old elements.
716                 part := q.ring[q.head%len(q.ring):]
717                 if q.tail-q.head <= len(part) {
718                         part = part[:q.tail-q.head]
719                         copy(nring, part)
720                 } else {
721                         pos := copy(nring, part)
722                         copy(nring[pos:], q.ring[:q.tail%len(q.ring)])
723                 }
724                 q.ring, q.head, q.tail = nring, 0, q.tail-q.head
725         }
726
727         q.ring[q.tail%len(q.ring)] = obj
728         q.tail++
729 }
730
731 // popHead pops a node from the head of the queue. It panics if q is empty.
732 func (q *objQueue) popHead() types.Object {
733         if q.empty() {
734                 panic("dequeue empty")
735         }
736         obj := q.ring[q.head%len(q.ring)]
737         q.head++
738         return obj
739 }