blob: 1a33cd5c6cd3dd626e08337f6a87933fc2770c2d [file] [log] [blame]
Rebecca Stambler6e0e2182018-04-26 13:58:52 -04001// 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
10package gcimporter
11
12import (
13 "bytes"
14 "encoding/binary"
Robert Griesemer9a70f1f2018-06-12 22:33:41 -070015 "fmt"
Rebecca Stambler6e0e2182018-04-26 13:58:52 -040016 "go/constant"
17 "go/token"
18 "go/types"
19 "io"
20 "sort"
Robert Findley3883e4a2021-09-30 22:45:40 -040021 "strings"
Robert Findley0cffec92021-09-14 13:07:03 -040022
23 "golang.org/x/tools/internal/typeparams"
Rebecca Stambler6e0e2182018-04-26 13:58:52 -040024)
25
26type intReader struct {
27 *bytes.Reader
28 path string
29}
30
31func (r *intReader) int64() int64 {
32 i, err := binary.ReadVarint(r.Reader)
33 if err != nil {
34 errorf("import %q: read varint error: %v", r.path, err)
35 }
36 return i
37}
38
39func (r *intReader) uint64() uint64 {
40 i, err := binary.ReadUvarint(r.Reader)
41 if err != nil {
42 errorf("import %q: read varint error: %v", r.path, err)
43 }
44 return i
45}
46
Robert Findley0cffec92021-09-14 13:07:03 -040047// Keep this in sync with constants in iexport.go.
48const (
Robert Findley52e95272022-01-10 18:46:59 -050049 iexportVersionGo1_11 = 0
50 iexportVersionPosCol = 1
51 iexportVersionGo1_18 = 2
52 iexportVersionGenerics = 2
Robert Findley0cffec92021-09-14 13:07:03 -040053)
54
55type ident struct {
56 pkg string
57 name string
58}
59
Rebecca Stambler6e0e2182018-04-26 13:58:52 -040060const predeclReserved = 32
61
62type itag uint64
63
64const (
65 // Types
66 definedType itag = iota
67 pointerType
68 sliceType
69 arrayType
70 chanType
71 mapType
72 signatureType
73 structType
74 interfaceType
Robert Findley0cffec92021-09-14 13:07:03 -040075 typeParamType
Robert Findley02e52382021-09-14 20:46:30 -040076 instanceType
Robert Findley0cffec92021-09-14 13:07:03 -040077 unionType
Rebecca Stambler6e0e2182018-04-26 13:58:52 -040078)
79
Robert Griesemer9a70f1f2018-06-12 22:33:41 -070080// IImportData imports a package from the serialized package data
Matthew Dempskya1db63c2021-02-15 22:17:43 -080081// and returns 0 and a reference to the package.
Rebecca Stambler6e0e2182018-04-26 13:58:52 -040082// If the export data version is not recognized or the format is otherwise
83// compromised, an error is returned.
Matthew Dempskya1db63c2021-02-15 22:17:43 -080084func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
85 pkgs, err := iimportCommon(fset, imports, data, false, path)
86 if err != nil {
87 return 0, nil, err
88 }
89 return 0, pkgs[0], nil
90}
91
92// IImportBundle imports a set of packages from the serialized package bundle.
93func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
94 return iimportCommon(fset, imports, data, true, "")
95}
96
97func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string) (pkgs []*types.Package, err error) {
Matthew Dempskydb0687c2019-09-26 17:38:16 -070098 const currentVersion = 1
99 version := int64(-1)
Robert Findley91c880c2021-09-20 10:42:55 -0400100 if !debug {
101 defer func() {
102 if e := recover(); e != nil {
103 if version > currentVersion {
104 err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
105 } else {
106 err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
107 }
Robert Griesemer9a70f1f2018-06-12 22:33:41 -0700108 }
Robert Findley91c880c2021-09-20 10:42:55 -0400109 }()
110 }
Robert Griesemer9a70f1f2018-06-12 22:33:41 -0700111
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400112 r := &intReader{bytes.NewReader(data), path}
113
Matthew Dempskya1db63c2021-02-15 22:17:43 -0800114 if bundle {
115 bundleVersion := r.uint64()
116 switch bundleVersion {
117 case bundleVersion:
118 default:
119 errorf("unknown bundle format version %d", bundleVersion)
120 }
121 }
122
Matthew Dempskydb0687c2019-09-26 17:38:16 -0700123 version = int64(r.uint64())
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400124 switch version {
Robert Findley18096c52021-10-22 11:02:26 -0400125 case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400126 default:
Robert Findley18096c52021-10-22 11:02:26 -0400127 if version > iexportVersionGo1_18 {
Robert Findley0cffec92021-09-14 13:07:03 -0400128 errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
129 } else {
130 errorf("unknown iexport format version %d", version)
131 }
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400132 }
133
134 sLen := int64(r.uint64())
135 dLen := int64(r.uint64())
136
137 whence, _ := r.Seek(0, io.SeekCurrent)
138 stringData := data[whence : whence+sLen]
139 declData := data[whence+sLen : whence+sLen+dLen]
140 r.Seek(sLen+dLen, io.SeekCurrent)
141
142 p := iimporter{
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400143 version: int(version),
144 ipath: path,
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400145
146 stringData: stringData,
147 stringCache: make(map[uint64]string),
148 pkgCache: make(map[uint64]*types.Package),
149
150 declData: declData,
151 pkgIndex: make(map[*types.Package]map[string]uint64),
152 typCache: make(map[uint64]types.Type),
Robert Findley0cffec92021-09-14 13:07:03 -0400153 // Separate map for typeparams, keyed by their package and unique
Robert Findley81f084e2021-10-18 12:23:03 -0400154 // name.
Robert Findley0cffec92021-09-14 13:07:03 -0400155 tparamIndex: make(map[ident]types.Type),
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400156
157 fake: fakeFileSet{
158 fset: fset,
Robert Findleycbf1d012021-10-20 11:02:53 -0400159 files: make(map[string]*fileInfo),
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400160 },
161 }
Robert Findleycbf1d012021-10-20 11:02:53 -0400162 defer p.fake.setLines() // set lines for files in fset
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400163
Rebecca Stambler58ecf642019-01-07 14:50:49 -0500164 for i, pt := range predeclared() {
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400165 p.typCache[uint64(i)] = pt
166 }
167
168 pkgList := make([]*types.Package, r.uint64())
169 for i := range pkgList {
170 pkgPathOff := r.uint64()
171 pkgPath := p.stringAt(pkgPathOff)
172 pkgName := p.stringAt(r.uint64())
173 _ = r.uint64() // package height; unused by go/types
174
175 if pkgPath == "" {
176 pkgPath = path
177 }
178 pkg := imports[pkgPath]
179 if pkg == nil {
180 pkg = types.NewPackage(pkgPath, pkgName)
181 imports[pkgPath] = pkg
182 } else if pkg.Name() != pkgName {
183 errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
184 }
185
186 p.pkgCache[pkgPathOff] = pkg
187
188 nameIndex := make(map[string]uint64)
189 for nSyms := r.uint64(); nSyms > 0; nSyms-- {
190 name := p.stringAt(r.uint64())
191 nameIndex[name] = r.uint64()
192 }
193
194 p.pkgIndex[pkg] = nameIndex
195 pkgList[i] = pkg
196 }
Matthew Dempskya1db63c2021-02-15 22:17:43 -0800197
198 if bundle {
199 pkgs = make([]*types.Package, r.uint64())
200 for i := range pkgs {
201 pkg := p.pkgAt(r.uint64())
202 imps := make([]*types.Package, r.uint64())
203 for j := range imps {
204 imps[j] = p.pkgAt(r.uint64())
205 }
206 pkg.SetImports(imps)
207 pkgs[i] = pkg
208 }
209 } else {
210 if len(pkgList) == 0 {
211 errorf("no packages found for %s", path)
212 panic("unreachable")
213 }
214 pkgs = pkgList[:1]
215
216 // record all referenced packages as imports
217 list := append(([]*types.Package)(nil), pkgList[1:]...)
218 sort.Sort(byPath(list))
219 pkgs[0].SetImports(list)
Rebecca Stambler246a69f2019-10-03 17:28:33 -0400220 }
Matthew Dempskya1db63c2021-02-15 22:17:43 -0800221
222 for _, pkg := range pkgs {
223 if pkg.Complete() {
224 continue
225 }
226
227 names := make([]string, 0, len(p.pkgIndex[pkg]))
228 for name := range p.pkgIndex[pkg] {
229 names = append(names, name)
230 }
231 sort.Strings(names)
232 for _, name := range names {
233 p.doDecl(pkg, name)
234 }
235
236 // package was imported completely and without errors
237 pkg.MarkComplete()
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400238 }
239
240 for _, typ := range p.interfaceList {
241 typ.Complete()
242 }
243
Matthew Dempskya1db63c2021-02-15 22:17:43 -0800244 return pkgs, nil
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400245}
246
247type iimporter struct {
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400248 version int
249 ipath string
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400250
251 stringData []byte
252 stringCache map[uint64]string
253 pkgCache map[uint64]*types.Package
254
Robert Findley0cffec92021-09-14 13:07:03 -0400255 declData []byte
256 pkgIndex map[*types.Package]map[string]uint64
257 typCache map[uint64]types.Type
258 tparamIndex map[ident]types.Type
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400259
260 fake fakeFileSet
261 interfaceList []*types.Interface
Robert Findley81f084e2021-10-18 12:23:03 -0400262
263 indent int // for tracing support
264}
265
266func (p *iimporter) trace(format string, args ...interface{}) {
267 if !trace {
268 // Call sites should also be guarded, but having this check here allows
269 // easily enabling/disabling debug trace statements.
270 return
271 }
272 fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400273}
274
275func (p *iimporter) doDecl(pkg *types.Package, name string) {
Robert Findley81f084e2021-10-18 12:23:03 -0400276 if debug {
277 p.trace("import decl %s", name)
278 p.indent++
279 defer func() {
280 p.indent--
281 p.trace("=> %s", name)
282 }()
283 }
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400284 // See if we've already imported this declaration.
285 if obj := pkg.Scope().Lookup(name); obj != nil {
286 return
287 }
288
289 off, ok := p.pkgIndex[pkg][name]
290 if !ok {
291 errorf("%v.%v not in index", pkg, name)
292 }
293
294 r := &importReader{p: p, currPkg: pkg}
295 r.declReader.Reset(p.declData[off:])
296
297 r.obj(name)
298}
299
300func (p *iimporter) stringAt(off uint64) string {
301 if s, ok := p.stringCache[off]; ok {
302 return s
303 }
304
305 slen, n := binary.Uvarint(p.stringData[off:])
306 if n <= 0 {
307 errorf("varint failed")
308 }
309 spos := off + uint64(n)
310 s := string(p.stringData[spos : spos+slen])
311 p.stringCache[off] = s
312 return s
313}
314
315func (p *iimporter) pkgAt(off uint64) *types.Package {
316 if pkg, ok := p.pkgCache[off]; ok {
317 return pkg
318 }
319 path := p.stringAt(off)
320 errorf("missing package %q in %q", path, p.ipath)
321 return nil
322}
323
324func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
Robert Findleydf480292021-12-01 13:55:45 -0500325 if t, ok := p.typCache[off]; ok && canReuse(base, t) {
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400326 return t
327 }
328
329 if off < predeclReserved {
330 errorf("predeclared type missing from cache: %v", off)
331 }
332
333 r := &importReader{p: p}
334 r.declReader.Reset(p.declData[off-predeclReserved:])
335 t := r.doType(base)
336
Robert Findleydf480292021-12-01 13:55:45 -0500337 if canReuse(base, t) {
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400338 p.typCache[off] = t
339 }
340 return t
341}
342
Robert Findleydf480292021-12-01 13:55:45 -0500343// canReuse reports whether the type rhs on the RHS of the declaration for def
344// may be re-used.
345//
346// Specifically, if def is non-nil and rhs is an interface type with methods, it
347// may not be re-used because we have a convention of setting the receiver type
348// for interface methods to def.
349func canReuse(def *types.Named, rhs types.Type) bool {
350 if def == nil {
351 return true
352 }
353 iface, _ := rhs.(*types.Interface)
354 if iface == nil {
355 return true
356 }
357 // Don't use iface.Empty() here as iface may not be complete.
358 return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
359}
360
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400361type importReader struct {
362 p *iimporter
363 declReader bytes.Reader
364 currPkg *types.Package
365 prevFile string
366 prevLine int64
Matthew Dempskydb0687c2019-09-26 17:38:16 -0700367 prevColumn int64
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400368}
369
370func (r *importReader) obj(name string) {
371 tag := r.byte()
372 pos := r.pos()
373
374 switch tag {
375 case 'A':
376 typ := r.typ()
377
378 r.declare(types.NewTypeName(pos, r.currPkg, name, typ))
379
380 case 'C':
381 typ, val := r.value()
382
383 r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
384
Robert Findley0cffec92021-09-14 13:07:03 -0400385 case 'F', 'G':
386 var tparams []*typeparams.TypeParam
387 if tag == 'G' {
388 tparams = r.tparamList()
389 }
Robert Findley21896842021-09-28 15:04:48 -0400390 sig := r.signature(nil, nil, tparams)
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400391 r.declare(types.NewFunc(pos, r.currPkg, name, sig))
392
Robert Findley0cffec92021-09-14 13:07:03 -0400393 case 'T', 'U':
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400394 // Types can be recursive. We need to setup a stub
395 // declaration before recursing.
396 obj := types.NewTypeName(pos, r.currPkg, name, nil)
397 named := types.NewNamed(obj, nil, nil)
Robert Findley0cffec92021-09-14 13:07:03 -0400398 // Declare obj before calling r.tparamList, so the new type name is recognized
399 // if used in the constraint of one of its own typeparams (see #48280).
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400400 r.declare(obj)
Robert Findley0cffec92021-09-14 13:07:03 -0400401 if tag == 'U' {
402 tparams := r.tparamList()
403 typeparams.SetForNamed(named, tparams)
404 }
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400405
406 underlying := r.p.typAt(r.uint64(), named).Underlying()
407 named.SetUnderlying(underlying)
408
409 if !isInterface(underlying) {
410 for n := r.uint64(); n > 0; n-- {
411 mpos := r.pos()
412 mname := r.ident()
413 recv := r.param()
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400414
Robert Findley0cffec92021-09-14 13:07:03 -0400415 // If the receiver has any targs, set those as the
416 // rparams of the method (since those are the
417 // typeparams being used in the method sig/body).
Robert Findley81f084e2021-10-18 12:23:03 -0400418 base := baseType(recv.Type())
419 assert(base != nil)
420 targs := typeparams.NamedTypeArgs(base)
Robert Findley21896842021-09-28 15:04:48 -0400421 var rparams []*typeparams.TypeParam
Robert Findley91c880c2021-09-20 10:42:55 -0400422 if targs.Len() > 0 {
Robert Findley81f084e2021-10-18 12:23:03 -0400423 rparams = make([]*typeparams.TypeParam, targs.Len())
Robert Findley0cffec92021-09-14 13:07:03 -0400424 for i := range rparams {
Robert Findley91c880c2021-09-20 10:42:55 -0400425 rparams[i] = targs.At(i).(*typeparams.TypeParam)
Robert Findley0cffec92021-09-14 13:07:03 -0400426 }
Robert Findley0cffec92021-09-14 13:07:03 -0400427 }
Robert Findley21896842021-09-28 15:04:48 -0400428 msig := r.signature(recv, rparams, nil)
Robert Findley0cffec92021-09-14 13:07:03 -0400429
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400430 named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
431 }
432 }
433
Robert Findley0cffec92021-09-14 13:07:03 -0400434 case 'P':
435 // We need to "declare" a typeparam in order to have a name that
436 // can be referenced recursively (if needed) in the type param's
437 // bound.
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400438 if r.p.version < iexportVersionGenerics {
Robert Findley0cffec92021-09-14 13:07:03 -0400439 errorf("unexpected type param type")
440 }
Robert Findley80963bc2022-01-20 11:16:42 -0500441 name0 := tparamName(name)
Robert Findley0cffec92021-09-14 13:07:03 -0400442 tn := types.NewTypeName(pos, r.currPkg, name0, nil)
443 t := typeparams.NewTypeParam(tn, nil)
Robert Findley3883e4a2021-09-30 22:45:40 -0400444
Robert Findley0cffec92021-09-14 13:07:03 -0400445 // To handle recursive references to the typeparam within its
446 // bound, save the partial type in tparamIndex before reading the bounds.
447 id := ident{r.currPkg.Name(), name}
448 r.p.tparamIndex[id] = t
Robert Findley18096c52021-10-22 11:02:26 -0400449 var implicit bool
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400450 if r.p.version >= iexportVersionGo1_18 {
Robert Findley18096c52021-10-22 11:02:26 -0400451 implicit = r.bool()
452 }
453 constraint := r.typ()
454 if implicit {
455 iface, _ := constraint.(*types.Interface)
456 if iface == nil {
457 errorf("non-interface constraint marked implicit")
458 }
459 typeparams.MarkImplicit(iface)
460 }
461 typeparams.SetTypeParamConstraint(t, constraint)
Robert Findley0cffec92021-09-14 13:07:03 -0400462
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400463 case 'V':
464 typ := r.typ()
465
466 r.declare(types.NewVar(pos, r.currPkg, name, typ))
467
468 default:
469 errorf("unexpected tag: %v", tag)
470 }
471}
472
473func (r *importReader) declare(obj types.Object) {
474 obj.Pkg().Scope().Insert(obj)
475}
476
477func (r *importReader) value() (typ types.Type, val constant.Value) {
478 typ = r.typ()
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400479 if r.p.version >= iexportVersionGo1_18 {
480 // TODO: add support for using the kind.
481 _ = constant.Kind(r.int64())
482 }
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400483
484 switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
485 case types.IsBoolean:
486 val = constant.MakeBool(r.bool())
487
488 case types.IsString:
489 val = constant.MakeString(r.string())
490
491 case types.IsInteger:
492 val = r.mpint(b)
493
494 case types.IsFloat:
495 val = r.mpfloat(b)
496
497 case types.IsComplex:
498 re := r.mpfloat(b)
499 im := r.mpfloat(b)
500 val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
501
502 default:
Rebecca Stambler58ecf642019-01-07 14:50:49 -0500503 if b.Kind() == types.Invalid {
504 val = constant.MakeUnknown()
505 return
506 }
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400507 errorf("unexpected type %v", typ) // panics
508 panic("unreachable")
509 }
510
511 return
512}
513
514func intSize(b *types.Basic) (signed bool, maxBytes uint) {
515 if (b.Info() & types.IsUntyped) != 0 {
516 return true, 64
517 }
518
519 switch b.Kind() {
520 case types.Float32, types.Complex64:
521 return true, 3
522 case types.Float64, types.Complex128:
523 return true, 7
524 }
525
526 signed = (b.Info() & types.IsUnsigned) == 0
527 switch b.Kind() {
528 case types.Int8, types.Uint8:
529 maxBytes = 1
530 case types.Int16, types.Uint16:
531 maxBytes = 2
532 case types.Int32, types.Uint32:
533 maxBytes = 4
534 default:
535 maxBytes = 8
536 }
537
538 return
539}
540
541func (r *importReader) mpint(b *types.Basic) constant.Value {
542 signed, maxBytes := intSize(b)
543
544 maxSmall := 256 - maxBytes
545 if signed {
546 maxSmall = 256 - 2*maxBytes
547 }
548 if maxBytes == 1 {
549 maxSmall = 256
550 }
551
552 n, _ := r.declReader.ReadByte()
553 if uint(n) < maxSmall {
554 v := int64(n)
555 if signed {
556 v >>= 1
557 if n&1 != 0 {
558 v = ^v
559 }
560 }
561 return constant.MakeInt64(v)
562 }
563
564 v := -n
565 if signed {
566 v = -(n &^ 1) >> 1
567 }
568 if v < 1 || uint(v) > maxBytes {
569 errorf("weird decoding: %v, %v => %v", n, signed, v)
570 }
571
572 buf := make([]byte, v)
573 io.ReadFull(&r.declReader, buf)
574
575 // convert to little endian
576 // TODO(gri) go/constant should have a more direct conversion function
577 // (e.g., once it supports a big.Float based implementation)
578 for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
579 buf[i], buf[j] = buf[j], buf[i]
580 }
581
582 x := constant.MakeFromBytes(buf)
583 if signed && n&1 != 0 {
584 x = constant.UnaryOp(token.SUB, x, 0)
585 }
586 return x
587}
588
589func (r *importReader) mpfloat(b *types.Basic) constant.Value {
590 x := r.mpint(b)
591 if constant.Sign(x) == 0 {
592 return x
593 }
594
595 exp := r.int64()
596 switch {
597 case exp > 0:
598 x = constant.Shift(x, token.SHL, uint(exp))
Rob Findley35a91592021-04-05 23:21:25 -0400599 // Ensure that the imported Kind is Float, else this constant may run into
600 // bitsize limits on overlarge integers. Eventually we can instead adopt
601 // the approach of CL 288632, but that CL relies on go/constant APIs that
602 // were introduced in go1.13.
603 //
604 // TODO(rFindley): sync the logic here with tip Go once we no longer
605 // support go1.12.
606 x = constant.ToFloat(x)
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400607 case exp < 0:
608 d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
609 x = constant.BinaryOp(x, token.QUO, d)
610 }
611 return x
612}
613
614func (r *importReader) ident() string {
615 return r.string()
616}
617
618func (r *importReader) qualifiedIdent() (*types.Package, string) {
619 name := r.string()
620 pkg := r.pkg()
621 return pkg, name
622}
623
624func (r *importReader) pos() token.Pos {
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400625 if r.p.version >= iexportVersionPosCol {
Matthew Dempskydb0687c2019-09-26 17:38:16 -0700626 r.posv1()
627 } else {
628 r.posv0()
629 }
630
631 if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
632 return token.NoPos
633 }
634 return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
635}
636
637func (r *importReader) posv0() {
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400638 delta := r.int64()
639 if delta != deltaNewFile {
640 r.prevLine += delta
641 } else if l := r.int64(); l == -1 {
642 r.prevLine += deltaNewFile
643 } else {
644 r.prevFile = r.string()
645 r.prevLine = l
646 }
Matthew Dempskydb0687c2019-09-26 17:38:16 -0700647}
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400648
Matthew Dempskydb0687c2019-09-26 17:38:16 -0700649func (r *importReader) posv1() {
650 delta := r.int64()
651 r.prevColumn += delta >> 1
652 if delta&1 != 0 {
653 delta = r.int64()
654 r.prevLine += delta >> 1
655 if delta&1 != 0 {
656 r.prevFile = r.string()
657 }
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400658 }
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400659}
660
661func (r *importReader) typ() types.Type {
662 return r.p.typAt(r.uint64(), nil)
663}
664
665func isInterface(t types.Type) bool {
666 _, ok := t.(*types.Interface)
667 return ok
668}
669
670func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
671func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
672
Robert Findley81f084e2021-10-18 12:23:03 -0400673func (r *importReader) doType(base *types.Named) (res types.Type) {
674 k := r.kind()
675 if debug {
676 r.p.trace("importing type %d (base: %s)", k, base)
677 r.p.indent++
678 defer func() {
679 r.p.indent--
680 r.p.trace("=> %s", res)
681 }()
682 }
683 switch k {
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400684 default:
685 errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
686 return nil
687
688 case definedType:
689 pkg, name := r.qualifiedIdent()
690 r.p.doDecl(pkg, name)
691 return pkg.Scope().Lookup(name).(*types.TypeName).Type()
692 case pointerType:
693 return types.NewPointer(r.typ())
694 case sliceType:
695 return types.NewSlice(r.typ())
696 case arrayType:
697 n := r.uint64()
698 return types.NewArray(r.typ(), int64(n))
699 case chanType:
700 dir := chanDir(int(r.uint64()))
701 return types.NewChan(dir, r.typ())
702 case mapType:
703 return types.NewMap(r.typ(), r.typ())
704 case signatureType:
705 r.currPkg = r.pkg()
Robert Findley21896842021-09-28 15:04:48 -0400706 return r.signature(nil, nil, nil)
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400707
708 case structType:
709 r.currPkg = r.pkg()
710
711 fields := make([]*types.Var, r.uint64())
712 tags := make([]string, len(fields))
713 for i := range fields {
714 fpos := r.pos()
715 fname := r.ident()
716 ftyp := r.typ()
717 emb := r.bool()
718 tag := r.string()
719
720 fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
721 tags[i] = tag
722 }
723 return types.NewStruct(fields, tags)
724
725 case interfaceType:
726 r.currPkg = r.pkg()
727
Robert Griesemer9a70f1f2018-06-12 22:33:41 -0700728 embeddeds := make([]types.Type, r.uint64())
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400729 for i := range embeddeds {
730 _ = r.pos()
Robert Griesemer9a70f1f2018-06-12 22:33:41 -0700731 embeddeds[i] = r.typ()
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400732 }
733
734 methods := make([]*types.Func, r.uint64())
735 for i := range methods {
736 mpos := r.pos()
737 mname := r.ident()
738
739 // TODO(mdempsky): Matches bimport.go, but I
740 // don't agree with this.
741 var recv *types.Var
742 if base != nil {
743 recv = types.NewVar(token.NoPos, r.currPkg, "", base)
744 }
745
Robert Findley21896842021-09-28 15:04:48 -0400746 msig := r.signature(recv, nil, nil)
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400747 methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
748 }
749
Robert Griesemer9d855102018-06-13 10:56:57 -0700750 typ := newInterface(methods, embeddeds)
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400751 r.p.interfaceList = append(r.p.interfaceList, typ)
752 return typ
Robert Findley0cffec92021-09-14 13:07:03 -0400753
754 case typeParamType:
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400755 if r.p.version < iexportVersionGenerics {
Robert Findley0cffec92021-09-14 13:07:03 -0400756 errorf("unexpected type param type")
757 }
758 pkg, name := r.qualifiedIdent()
759 id := ident{pkg.Name(), name}
760 if t, ok := r.p.tparamIndex[id]; ok {
761 // We're already in the process of importing this typeparam.
762 return t
763 }
764 // Otherwise, import the definition of the typeparam now.
765 r.p.doDecl(pkg, name)
766 return r.p.tparamIndex[id]
767
Robert Findley02e52382021-09-14 20:46:30 -0400768 case instanceType:
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400769 if r.p.version < iexportVersionGenerics {
Robert Findley0cffec92021-09-14 13:07:03 -0400770 errorf("unexpected instantiation type")
771 }
772 // pos does not matter for instances: they are positioned on the original
773 // type.
774 _ = r.pos()
775 len := r.uint64()
776 targs := make([]types.Type, len)
777 for i := range targs {
778 targs[i] = r.typ()
779 }
780 baseType := r.typ()
781 // The imported instantiated type doesn't include any methods, so
782 // we must always use the methods of the base (orig) type.
783 // TODO provide a non-nil *Environment
784 t, _ := typeparams.Instantiate(nil, baseType, targs, false)
785 return t
786
787 case unionType:
Robert Findleyfc8b4ca2021-10-22 11:32:16 -0400788 if r.p.version < iexportVersionGenerics {
Robert Findley0cffec92021-09-14 13:07:03 -0400789 errorf("unexpected instantiation type")
790 }
791 terms := make([]*typeparams.Term, r.uint64())
792 for i := range terms {
793 terms[i] = typeparams.NewTerm(r.bool(), r.typ())
794 }
795 return typeparams.NewUnion(terms)
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400796 }
797}
798
799func (r *importReader) kind() itag {
800 return itag(r.uint64())
801}
802
Robert Findley21896842021-09-28 15:04:48 -0400803func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400804 params := r.paramList()
805 results := r.paramList()
806 variadic := params.Len() > 0 && r.bool()
Robert Findley21896842021-09-28 15:04:48 -0400807 return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic)
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400808}
809
Robert Findley0cffec92021-09-14 13:07:03 -0400810func (r *importReader) tparamList() []*typeparams.TypeParam {
811 n := r.uint64()
812 if n == 0 {
813 return nil
814 }
815 xs := make([]*typeparams.TypeParam, n)
816 for i := range xs {
817 // Note: the standard library importer is tolerant of nil types here,
818 // though would panic in SetTypeParams.
819 xs[i] = r.typ().(*typeparams.TypeParam)
820 }
821 return xs
822}
823
Rebecca Stambler6e0e2182018-04-26 13:58:52 -0400824func (r *importReader) paramList() *types.Tuple {
825 xs := make([]*types.Var, r.uint64())
826 for i := range xs {
827 xs[i] = r.param()
828 }
829 return types.NewTuple(xs...)
830}
831
832func (r *importReader) param() *types.Var {
833 pos := r.pos()
834 name := r.ident()
835 typ := r.typ()
836 return types.NewParam(pos, r.currPkg, name, typ)
837}
838
839func (r *importReader) bool() bool {
840 return r.uint64() != 0
841}
842
843func (r *importReader) int64() int64 {
844 n, err := binary.ReadVarint(&r.declReader)
845 if err != nil {
846 errorf("readVarint: %v", err)
847 }
848 return n
849}
850
851func (r *importReader) uint64() uint64 {
852 n, err := binary.ReadUvarint(&r.declReader)
853 if err != nil {
854 errorf("readUvarint: %v", err)
855 }
856 return n
857}
858
859func (r *importReader) byte() byte {
860 x, err := r.declReader.ReadByte()
861 if err != nil {
862 errorf("declReader.ReadByte: %v", err)
863 }
864 return x
865}
Robert Findley0cffec92021-09-14 13:07:03 -0400866
867func baseType(typ types.Type) *types.Named {
868 // pointer receivers are never types.Named types
869 if p, _ := typ.(*types.Pointer); p != nil {
870 typ = p.Elem()
871 }
872 // receiver base types are always (possibly generic) types.Named types
873 n, _ := typ.(*types.Named)
874 return n
875}