github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/internal/gcimporter/iimport.go (about) 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 "strings" 22 23 "github.com/powerman/golang-tools/internal/typeparams" 24 ) 25 26 type intReader struct { 27 *bytes.Reader 28 path string 29 } 30 31 func (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 39 func (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 47 // Keep this in sync with constants in iexport.go. 48 const ( 49 iexportVersionGo1_11 = 0 50 iexportVersionPosCol = 1 51 iexportVersionGo1_18 = 2 52 iexportVersionGenerics = 2 53 ) 54 55 type ident struct { 56 pkg string 57 name string 58 } 59 60 const predeclReserved = 32 61 62 type itag uint64 63 64 const ( 65 // Types 66 definedType itag = iota 67 pointerType 68 sliceType 69 arrayType 70 chanType 71 mapType 72 signatureType 73 structType 74 interfaceType 75 typeParamType 76 instanceType 77 unionType 78 ) 79 80 // IImportData imports a package from the serialized package data 81 // and returns 0 and a reference to the package. 82 // If the export data version is not recognized or the format is otherwise 83 // compromised, an error is returned. 84 func 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. 93 func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) { 94 return iimportCommon(fset, imports, data, true, "") 95 } 96 97 func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string) (pkgs []*types.Package, err error) { 98 const currentVersion = 1 99 version := int64(-1) 100 if !debug { 101 defer func() { 102 if e := recover(); e != nil { 103 if bundle { 104 err = fmt.Errorf("%v", e) 105 } else if version > currentVersion { 106 err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) 107 } else { 108 err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e) 109 } 110 } 111 }() 112 } 113 114 r := &intReader{bytes.NewReader(data), path} 115 116 if bundle { 117 bundleVersion := r.uint64() 118 switch bundleVersion { 119 case bundleVersion: 120 default: 121 errorf("unknown bundle format version %d", bundleVersion) 122 } 123 } 124 125 version = int64(r.uint64()) 126 switch version { 127 case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: 128 default: 129 if version > iexportVersionGo1_18 { 130 errorf("unstable iexport format version %d, just rebuild compiler and std library", version) 131 } else { 132 errorf("unknown iexport format version %d", version) 133 } 134 } 135 136 sLen := int64(r.uint64()) 137 dLen := int64(r.uint64()) 138 139 whence, _ := r.Seek(0, io.SeekCurrent) 140 stringData := data[whence : whence+sLen] 141 declData := data[whence+sLen : whence+sLen+dLen] 142 r.Seek(sLen+dLen, io.SeekCurrent) 143 144 p := iimporter{ 145 version: int(version), 146 ipath: path, 147 148 stringData: stringData, 149 stringCache: make(map[uint64]string), 150 pkgCache: make(map[uint64]*types.Package), 151 152 declData: declData, 153 pkgIndex: make(map[*types.Package]map[string]uint64), 154 typCache: make(map[uint64]types.Type), 155 // Separate map for typeparams, keyed by their package and unique 156 // name. 157 tparamIndex: make(map[ident]types.Type), 158 159 fake: fakeFileSet{ 160 fset: fset, 161 files: make(map[string]*fileInfo), 162 }, 163 } 164 defer p.fake.setLines() // set lines for files in fset 165 166 for i, pt := range predeclared() { 167 p.typCache[uint64(i)] = pt 168 } 169 170 pkgList := make([]*types.Package, r.uint64()) 171 for i := range pkgList { 172 pkgPathOff := r.uint64() 173 pkgPath := p.stringAt(pkgPathOff) 174 pkgName := p.stringAt(r.uint64()) 175 _ = r.uint64() // package height; unused by go/types 176 177 if pkgPath == "" { 178 pkgPath = path 179 } 180 pkg := imports[pkgPath] 181 if pkg == nil { 182 pkg = types.NewPackage(pkgPath, pkgName) 183 imports[pkgPath] = pkg 184 } else if pkg.Name() != pkgName { 185 errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path) 186 } 187 188 p.pkgCache[pkgPathOff] = pkg 189 190 nameIndex := make(map[string]uint64) 191 for nSyms := r.uint64(); nSyms > 0; nSyms-- { 192 name := p.stringAt(r.uint64()) 193 nameIndex[name] = r.uint64() 194 } 195 196 p.pkgIndex[pkg] = nameIndex 197 pkgList[i] = pkg 198 } 199 200 if bundle { 201 pkgs = make([]*types.Package, r.uint64()) 202 for i := range pkgs { 203 pkg := p.pkgAt(r.uint64()) 204 imps := make([]*types.Package, r.uint64()) 205 for j := range imps { 206 imps[j] = p.pkgAt(r.uint64()) 207 } 208 pkg.SetImports(imps) 209 pkgs[i] = pkg 210 } 211 } else { 212 if len(pkgList) == 0 { 213 errorf("no packages found for %s", path) 214 panic("unreachable") 215 } 216 pkgs = pkgList[:1] 217 218 // record all referenced packages as imports 219 list := append(([]*types.Package)(nil), pkgList[1:]...) 220 sort.Sort(byPath(list)) 221 pkgs[0].SetImports(list) 222 } 223 224 for _, pkg := range pkgs { 225 if pkg.Complete() { 226 continue 227 } 228 229 names := make([]string, 0, len(p.pkgIndex[pkg])) 230 for name := range p.pkgIndex[pkg] { 231 names = append(names, name) 232 } 233 sort.Strings(names) 234 for _, name := range names { 235 p.doDecl(pkg, name) 236 } 237 238 // package was imported completely and without errors 239 pkg.MarkComplete() 240 } 241 242 // SetConstraint can't be called if the constraint type is not yet complete. 243 // When type params are created in the 'P' case of (*importReader).obj(), 244 // the associated constraint type may not be complete due to recursion. 245 // Therefore, we defer calling SetConstraint there, and call it here instead 246 // after all types are complete. 247 for _, d := range p.later { 248 typeparams.SetTypeParamConstraint(d.t, d.constraint) 249 } 250 251 for _, typ := range p.interfaceList { 252 typ.Complete() 253 } 254 255 return pkgs, nil 256 } 257 258 type setConstraintArgs struct { 259 t *typeparams.TypeParam 260 constraint types.Type 261 } 262 263 type iimporter struct { 264 version int 265 ipath string 266 267 stringData []byte 268 stringCache map[uint64]string 269 pkgCache map[uint64]*types.Package 270 271 declData []byte 272 pkgIndex map[*types.Package]map[string]uint64 273 typCache map[uint64]types.Type 274 tparamIndex map[ident]types.Type 275 276 fake fakeFileSet 277 interfaceList []*types.Interface 278 279 // Arguments for calls to SetConstraint that are deferred due to recursive types 280 later []setConstraintArgs 281 282 indent int // for tracing support 283 } 284 285 func (p *iimporter) trace(format string, args ...interface{}) { 286 if !trace { 287 // Call sites should also be guarded, but having this check here allows 288 // easily enabling/disabling debug trace statements. 289 return 290 } 291 fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) 292 } 293 294 func (p *iimporter) doDecl(pkg *types.Package, name string) { 295 if debug { 296 p.trace("import decl %s", name) 297 p.indent++ 298 defer func() { 299 p.indent-- 300 p.trace("=> %s", name) 301 }() 302 } 303 // See if we've already imported this declaration. 304 if obj := pkg.Scope().Lookup(name); obj != nil { 305 return 306 } 307 308 off, ok := p.pkgIndex[pkg][name] 309 if !ok { 310 errorf("%v.%v not in index", pkg, name) 311 } 312 313 r := &importReader{p: p, currPkg: pkg} 314 r.declReader.Reset(p.declData[off:]) 315 316 r.obj(name) 317 } 318 319 func (p *iimporter) stringAt(off uint64) string { 320 if s, ok := p.stringCache[off]; ok { 321 return s 322 } 323 324 slen, n := binary.Uvarint(p.stringData[off:]) 325 if n <= 0 { 326 errorf("varint failed") 327 } 328 spos := off + uint64(n) 329 s := string(p.stringData[spos : spos+slen]) 330 p.stringCache[off] = s 331 return s 332 } 333 334 func (p *iimporter) pkgAt(off uint64) *types.Package { 335 if pkg, ok := p.pkgCache[off]; ok { 336 return pkg 337 } 338 path := p.stringAt(off) 339 errorf("missing package %q in %q", path, p.ipath) 340 return nil 341 } 342 343 func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { 344 if t, ok := p.typCache[off]; ok && canReuse(base, t) { 345 return t 346 } 347 348 if off < predeclReserved { 349 errorf("predeclared type missing from cache: %v", off) 350 } 351 352 r := &importReader{p: p} 353 r.declReader.Reset(p.declData[off-predeclReserved:]) 354 t := r.doType(base) 355 356 if canReuse(base, t) { 357 p.typCache[off] = t 358 } 359 return t 360 } 361 362 // canReuse reports whether the type rhs on the RHS of the declaration for def 363 // may be re-used. 364 // 365 // Specifically, if def is non-nil and rhs is an interface type with methods, it 366 // may not be re-used because we have a convention of setting the receiver type 367 // for interface methods to def. 368 func canReuse(def *types.Named, rhs types.Type) bool { 369 if def == nil { 370 return true 371 } 372 iface, _ := rhs.(*types.Interface) 373 if iface == nil { 374 return true 375 } 376 // Don't use iface.Empty() here as iface may not be complete. 377 return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 378 } 379 380 type importReader struct { 381 p *iimporter 382 declReader bytes.Reader 383 currPkg *types.Package 384 prevFile string 385 prevLine int64 386 prevColumn int64 387 } 388 389 func (r *importReader) obj(name string) { 390 tag := r.byte() 391 pos := r.pos() 392 393 switch tag { 394 case 'A': 395 typ := r.typ() 396 397 r.declare(types.NewTypeName(pos, r.currPkg, name, typ)) 398 399 case 'C': 400 typ, val := r.value() 401 402 r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) 403 404 case 'F', 'G': 405 var tparams []*typeparams.TypeParam 406 if tag == 'G' { 407 tparams = r.tparamList() 408 } 409 sig := r.signature(nil, nil, tparams) 410 r.declare(types.NewFunc(pos, r.currPkg, name, sig)) 411 412 case 'T', 'U': 413 // Types can be recursive. We need to setup a stub 414 // declaration before recursing. 415 obj := types.NewTypeName(pos, r.currPkg, name, nil) 416 named := types.NewNamed(obj, nil, nil) 417 // Declare obj before calling r.tparamList, so the new type name is recognized 418 // if used in the constraint of one of its own typeparams (see #48280). 419 r.declare(obj) 420 if tag == 'U' { 421 tparams := r.tparamList() 422 typeparams.SetForNamed(named, tparams) 423 } 424 425 underlying := r.p.typAt(r.uint64(), named).Underlying() 426 named.SetUnderlying(underlying) 427 428 if !isInterface(underlying) { 429 for n := r.uint64(); n > 0; n-- { 430 mpos := r.pos() 431 mname := r.ident() 432 recv := r.param() 433 434 // If the receiver has any targs, set those as the 435 // rparams of the method (since those are the 436 // typeparams being used in the method sig/body). 437 base := baseType(recv.Type()) 438 assert(base != nil) 439 targs := typeparams.NamedTypeArgs(base) 440 var rparams []*typeparams.TypeParam 441 if targs.Len() > 0 { 442 rparams = make([]*typeparams.TypeParam, targs.Len()) 443 for i := range rparams { 444 rparams[i] = targs.At(i).(*typeparams.TypeParam) 445 } 446 } 447 msig := r.signature(recv, rparams, nil) 448 449 named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) 450 } 451 } 452 453 case 'P': 454 // We need to "declare" a typeparam in order to have a name that 455 // can be referenced recursively (if needed) in the type param's 456 // bound. 457 if r.p.version < iexportVersionGenerics { 458 errorf("unexpected type param type") 459 } 460 name0 := tparamName(name) 461 tn := types.NewTypeName(pos, r.currPkg, name0, nil) 462 t := typeparams.NewTypeParam(tn, nil) 463 464 // To handle recursive references to the typeparam within its 465 // bound, save the partial type in tparamIndex before reading the bounds. 466 id := ident{r.currPkg.Name(), name} 467 r.p.tparamIndex[id] = t 468 var implicit bool 469 if r.p.version >= iexportVersionGo1_18 { 470 implicit = r.bool() 471 } 472 constraint := r.typ() 473 if implicit { 474 iface, _ := constraint.(*types.Interface) 475 if iface == nil { 476 errorf("non-interface constraint marked implicit") 477 } 478 typeparams.MarkImplicit(iface) 479 } 480 // The constraint type may not be complete, if we 481 // are in the middle of a type recursion involving type 482 // constraints. So, we defer SetConstraint until we have 483 // completely set up all types in ImportData. 484 r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) 485 486 case 'V': 487 typ := r.typ() 488 489 r.declare(types.NewVar(pos, r.currPkg, name, typ)) 490 491 default: 492 errorf("unexpected tag: %v", tag) 493 } 494 } 495 496 func (r *importReader) declare(obj types.Object) { 497 obj.Pkg().Scope().Insert(obj) 498 } 499 500 func (r *importReader) value() (typ types.Type, val constant.Value) { 501 typ = r.typ() 502 if r.p.version >= iexportVersionGo1_18 { 503 // TODO: add support for using the kind. 504 _ = constant.Kind(r.int64()) 505 } 506 507 switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { 508 case types.IsBoolean: 509 val = constant.MakeBool(r.bool()) 510 511 case types.IsString: 512 val = constant.MakeString(r.string()) 513 514 case types.IsInteger: 515 val = r.mpint(b) 516 517 case types.IsFloat: 518 val = r.mpfloat(b) 519 520 case types.IsComplex: 521 re := r.mpfloat(b) 522 im := r.mpfloat(b) 523 val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) 524 525 default: 526 if b.Kind() == types.Invalid { 527 val = constant.MakeUnknown() 528 return 529 } 530 errorf("unexpected type %v", typ) // panics 531 panic("unreachable") 532 } 533 534 return 535 } 536 537 func intSize(b *types.Basic) (signed bool, maxBytes uint) { 538 if (b.Info() & types.IsUntyped) != 0 { 539 return true, 64 540 } 541 542 switch b.Kind() { 543 case types.Float32, types.Complex64: 544 return true, 3 545 case types.Float64, types.Complex128: 546 return true, 7 547 } 548 549 signed = (b.Info() & types.IsUnsigned) == 0 550 switch b.Kind() { 551 case types.Int8, types.Uint8: 552 maxBytes = 1 553 case types.Int16, types.Uint16: 554 maxBytes = 2 555 case types.Int32, types.Uint32: 556 maxBytes = 4 557 default: 558 maxBytes = 8 559 } 560 561 return 562 } 563 564 func (r *importReader) mpint(b *types.Basic) constant.Value { 565 signed, maxBytes := intSize(b) 566 567 maxSmall := 256 - maxBytes 568 if signed { 569 maxSmall = 256 - 2*maxBytes 570 } 571 if maxBytes == 1 { 572 maxSmall = 256 573 } 574 575 n, _ := r.declReader.ReadByte() 576 if uint(n) < maxSmall { 577 v := int64(n) 578 if signed { 579 v >>= 1 580 if n&1 != 0 { 581 v = ^v 582 } 583 } 584 return constant.MakeInt64(v) 585 } 586 587 v := -n 588 if signed { 589 v = -(n &^ 1) >> 1 590 } 591 if v < 1 || uint(v) > maxBytes { 592 errorf("weird decoding: %v, %v => %v", n, signed, v) 593 } 594 595 buf := make([]byte, v) 596 io.ReadFull(&r.declReader, buf) 597 598 // convert to little endian 599 // TODO(gri) go/constant should have a more direct conversion function 600 // (e.g., once it supports a big.Float based implementation) 601 for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 { 602 buf[i], buf[j] = buf[j], buf[i] 603 } 604 605 x := constant.MakeFromBytes(buf) 606 if signed && n&1 != 0 { 607 x = constant.UnaryOp(token.SUB, x, 0) 608 } 609 return x 610 } 611 612 func (r *importReader) mpfloat(b *types.Basic) constant.Value { 613 x := r.mpint(b) 614 if constant.Sign(x) == 0 { 615 return x 616 } 617 618 exp := r.int64() 619 switch { 620 case exp > 0: 621 x = constant.Shift(x, token.SHL, uint(exp)) 622 // Ensure that the imported Kind is Float, else this constant may run into 623 // bitsize limits on overlarge integers. Eventually we can instead adopt 624 // the approach of CL 288632, but that CL relies on go/constant APIs that 625 // were introduced in go1.13. 626 // 627 // TODO(rFindley): sync the logic here with tip Go once we no longer 628 // support go1.12. 629 x = constant.ToFloat(x) 630 case exp < 0: 631 d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) 632 x = constant.BinaryOp(x, token.QUO, d) 633 } 634 return x 635 } 636 637 func (r *importReader) ident() string { 638 return r.string() 639 } 640 641 func (r *importReader) qualifiedIdent() (*types.Package, string) { 642 name := r.string() 643 pkg := r.pkg() 644 return pkg, name 645 } 646 647 func (r *importReader) pos() token.Pos { 648 if r.p.version >= iexportVersionPosCol { 649 r.posv1() 650 } else { 651 r.posv0() 652 } 653 654 if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { 655 return token.NoPos 656 } 657 return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) 658 } 659 660 func (r *importReader) posv0() { 661 delta := r.int64() 662 if delta != deltaNewFile { 663 r.prevLine += delta 664 } else if l := r.int64(); l == -1 { 665 r.prevLine += deltaNewFile 666 } else { 667 r.prevFile = r.string() 668 r.prevLine = l 669 } 670 } 671 672 func (r *importReader) posv1() { 673 delta := r.int64() 674 r.prevColumn += delta >> 1 675 if delta&1 != 0 { 676 delta = r.int64() 677 r.prevLine += delta >> 1 678 if delta&1 != 0 { 679 r.prevFile = r.string() 680 } 681 } 682 } 683 684 func (r *importReader) typ() types.Type { 685 return r.p.typAt(r.uint64(), nil) 686 } 687 688 func isInterface(t types.Type) bool { 689 _, ok := t.(*types.Interface) 690 return ok 691 } 692 693 func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } 694 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } 695 696 func (r *importReader) doType(base *types.Named) (res types.Type) { 697 k := r.kind() 698 if debug { 699 r.p.trace("importing type %d (base: %s)", k, base) 700 r.p.indent++ 701 defer func() { 702 r.p.indent-- 703 r.p.trace("=> %s", res) 704 }() 705 } 706 switch k { 707 default: 708 errorf("unexpected kind tag in %q: %v", r.p.ipath, k) 709 return nil 710 711 case definedType: 712 pkg, name := r.qualifiedIdent() 713 r.p.doDecl(pkg, name) 714 return pkg.Scope().Lookup(name).(*types.TypeName).Type() 715 case pointerType: 716 return types.NewPointer(r.typ()) 717 case sliceType: 718 return types.NewSlice(r.typ()) 719 case arrayType: 720 n := r.uint64() 721 return types.NewArray(r.typ(), int64(n)) 722 case chanType: 723 dir := chanDir(int(r.uint64())) 724 return types.NewChan(dir, r.typ()) 725 case mapType: 726 return types.NewMap(r.typ(), r.typ()) 727 case signatureType: 728 r.currPkg = r.pkg() 729 return r.signature(nil, nil, nil) 730 731 case structType: 732 r.currPkg = r.pkg() 733 734 fields := make([]*types.Var, r.uint64()) 735 tags := make([]string, len(fields)) 736 for i := range fields { 737 fpos := r.pos() 738 fname := r.ident() 739 ftyp := r.typ() 740 emb := r.bool() 741 tag := r.string() 742 743 fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb) 744 tags[i] = tag 745 } 746 return types.NewStruct(fields, tags) 747 748 case interfaceType: 749 r.currPkg = r.pkg() 750 751 embeddeds := make([]types.Type, r.uint64()) 752 for i := range embeddeds { 753 _ = r.pos() 754 embeddeds[i] = r.typ() 755 } 756 757 methods := make([]*types.Func, r.uint64()) 758 for i := range methods { 759 mpos := r.pos() 760 mname := r.ident() 761 762 // TODO(mdempsky): Matches bimport.go, but I 763 // don't agree with this. 764 var recv *types.Var 765 if base != nil { 766 recv = types.NewVar(token.NoPos, r.currPkg, "", base) 767 } 768 769 msig := r.signature(recv, nil, nil) 770 methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig) 771 } 772 773 typ := newInterface(methods, embeddeds) 774 r.p.interfaceList = append(r.p.interfaceList, typ) 775 return typ 776 777 case typeParamType: 778 if r.p.version < iexportVersionGenerics { 779 errorf("unexpected type param type") 780 } 781 pkg, name := r.qualifiedIdent() 782 id := ident{pkg.Name(), name} 783 if t, ok := r.p.tparamIndex[id]; ok { 784 // We're already in the process of importing this typeparam. 785 return t 786 } 787 // Otherwise, import the definition of the typeparam now. 788 r.p.doDecl(pkg, name) 789 return r.p.tparamIndex[id] 790 791 case instanceType: 792 if r.p.version < iexportVersionGenerics { 793 errorf("unexpected instantiation type") 794 } 795 // pos does not matter for instances: they are positioned on the original 796 // type. 797 _ = r.pos() 798 len := r.uint64() 799 targs := make([]types.Type, len) 800 for i := range targs { 801 targs[i] = r.typ() 802 } 803 baseType := r.typ() 804 // The imported instantiated type doesn't include any methods, so 805 // we must always use the methods of the base (orig) type. 806 // TODO provide a non-nil *Environment 807 t, _ := typeparams.Instantiate(nil, baseType, targs, false) 808 return t 809 810 case unionType: 811 if r.p.version < iexportVersionGenerics { 812 errorf("unexpected instantiation type") 813 } 814 terms := make([]*typeparams.Term, r.uint64()) 815 for i := range terms { 816 terms[i] = typeparams.NewTerm(r.bool(), r.typ()) 817 } 818 return typeparams.NewUnion(terms) 819 } 820 } 821 822 func (r *importReader) kind() itag { 823 return itag(r.uint64()) 824 } 825 826 func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature { 827 params := r.paramList() 828 results := r.paramList() 829 variadic := params.Len() > 0 && r.bool() 830 return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic) 831 } 832 833 func (r *importReader) tparamList() []*typeparams.TypeParam { 834 n := r.uint64() 835 if n == 0 { 836 return nil 837 } 838 xs := make([]*typeparams.TypeParam, n) 839 for i := range xs { 840 // Note: the standard library importer is tolerant of nil types here, 841 // though would panic in SetTypeParams. 842 xs[i] = r.typ().(*typeparams.TypeParam) 843 } 844 return xs 845 } 846 847 func (r *importReader) paramList() *types.Tuple { 848 xs := make([]*types.Var, r.uint64()) 849 for i := range xs { 850 xs[i] = r.param() 851 } 852 return types.NewTuple(xs...) 853 } 854 855 func (r *importReader) param() *types.Var { 856 pos := r.pos() 857 name := r.ident() 858 typ := r.typ() 859 return types.NewParam(pos, r.currPkg, name, typ) 860 } 861 862 func (r *importReader) bool() bool { 863 return r.uint64() != 0 864 } 865 866 func (r *importReader) int64() int64 { 867 n, err := binary.ReadVarint(&r.declReader) 868 if err != nil { 869 errorf("readVarint: %v", err) 870 } 871 return n 872 } 873 874 func (r *importReader) uint64() uint64 { 875 n, err := binary.ReadUvarint(&r.declReader) 876 if err != nil { 877 errorf("readUvarint: %v", err) 878 } 879 return n 880 } 881 882 func (r *importReader) byte() byte { 883 x, err := r.declReader.ReadByte() 884 if err != nil { 885 errorf("declReader.ReadByte: %v", err) 886 } 887 return x 888 } 889 890 func baseType(typ types.Type) *types.Named { 891 // pointer receivers are never types.Named types 892 if p, _ := typ.(*types.Pointer); p != nil { 893 typ = p.Elem() 894 } 895 // receiver base types are always (possibly generic) types.Named types 896 n, _ := typ.(*types.Named) 897 return n 898 }