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