github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/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/jhump/golang-x-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 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 } 108 } 109 }() 110 } 111 112 r := &intReader{bytes.NewReader(data), path} 113 114 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 123 version = int64(r.uint64()) 124 switch version { 125 case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: 126 default: 127 if version > iexportVersionGo1_18 { 128 errorf("unstable iexport format version %d, just rebuild compiler and std library", version) 129 } else { 130 errorf("unknown iexport format version %d", version) 131 } 132 } 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{ 143 version: int(version), 144 ipath: path, 145 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), 153 // Separate map for typeparams, keyed by their package and unique 154 // name. 155 tparamIndex: make(map[ident]types.Type), 156 157 fake: fakeFileSet{ 158 fset: fset, 159 files: make(map[string]*fileInfo), 160 }, 161 } 162 defer p.fake.setLines() // set lines for files in fset 163 164 for i, pt := range predeclared() { 165 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 } 197 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) 220 } 221 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() 238 } 239 240 for _, typ := range p.interfaceList { 241 typ.Complete() 242 } 243 244 return pkgs, nil 245 } 246 247 type iimporter struct { 248 version int 249 ipath string 250 251 stringData []byte 252 stringCache map[uint64]string 253 pkgCache map[uint64]*types.Package 254 255 declData []byte 256 pkgIndex map[*types.Package]map[string]uint64 257 typCache map[uint64]types.Type 258 tparamIndex map[ident]types.Type 259 260 fake fakeFileSet 261 interfaceList []*types.Interface 262 263 indent int // for tracing support 264 } 265 266 func (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...) 273 } 274 275 func (p *iimporter) doDecl(pkg *types.Package, name string) { 276 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 } 284 // 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 300 func (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 315 func (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 324 func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { 325 if t, ok := p.typCache[off]; ok && canReuse(base, t) { 326 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 337 if canReuse(base, t) { 338 p.typCache[off] = t 339 } 340 return t 341 } 342 343 // 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. 349 func 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 361 type importReader struct { 362 p *iimporter 363 declReader bytes.Reader 364 currPkg *types.Package 365 prevFile string 366 prevLine int64 367 prevColumn int64 368 } 369 370 func (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 385 case 'F', 'G': 386 var tparams []*typeparams.TypeParam 387 if tag == 'G' { 388 tparams = r.tparamList() 389 } 390 sig := r.signature(nil, nil, tparams) 391 r.declare(types.NewFunc(pos, r.currPkg, name, sig)) 392 393 case 'T', 'U': 394 // 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) 398 // 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). 400 r.declare(obj) 401 if tag == 'U' { 402 tparams := r.tparamList() 403 typeparams.SetForNamed(named, tparams) 404 } 405 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() 414 415 // 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). 418 base := baseType(recv.Type()) 419 assert(base != nil) 420 targs := typeparams.NamedTypeArgs(base) 421 var rparams []*typeparams.TypeParam 422 if targs.Len() > 0 { 423 rparams = make([]*typeparams.TypeParam, targs.Len()) 424 for i := range rparams { 425 rparams[i] = targs.At(i).(*typeparams.TypeParam) 426 } 427 } 428 msig := r.signature(recv, rparams, nil) 429 430 named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) 431 } 432 } 433 434 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. 438 if r.p.version < iexportVersionGenerics { 439 errorf("unexpected type param type") 440 } 441 name0 := tparamName(name) 442 tn := types.NewTypeName(pos, r.currPkg, name0, nil) 443 t := typeparams.NewTypeParam(tn, nil) 444 445 // 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 449 var implicit bool 450 if r.p.version >= iexportVersionGo1_18 { 451 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) 462 463 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 473 func (r *importReader) declare(obj types.Object) { 474 obj.Pkg().Scope().Insert(obj) 475 } 476 477 func (r *importReader) value() (typ types.Type, val constant.Value) { 478 typ = r.typ() 479 if r.p.version >= iexportVersionGo1_18 { 480 // TODO: add support for using the kind. 481 _ = constant.Kind(r.int64()) 482 } 483 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: 503 if b.Kind() == types.Invalid { 504 val = constant.MakeUnknown() 505 return 506 } 507 errorf("unexpected type %v", typ) // panics 508 panic("unreachable") 509 } 510 511 return 512 } 513 514 func 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 541 func (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 589 func (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)) 599 // 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) 607 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 614 func (r *importReader) ident() string { 615 return r.string() 616 } 617 618 func (r *importReader) qualifiedIdent() (*types.Package, string) { 619 name := r.string() 620 pkg := r.pkg() 621 return pkg, name 622 } 623 624 func (r *importReader) pos() token.Pos { 625 if r.p.version >= iexportVersionPosCol { 626 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 637 func (r *importReader) posv0() { 638 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 } 647 } 648 649 func (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 } 658 } 659 } 660 661 func (r *importReader) typ() types.Type { 662 return r.p.typAt(r.uint64(), nil) 663 } 664 665 func isInterface(t types.Type) bool { 666 _, ok := t.(*types.Interface) 667 return ok 668 } 669 670 func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } 671 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } 672 673 func (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 { 684 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() 706 return r.signature(nil, nil, nil) 707 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 728 embeddeds := make([]types.Type, r.uint64()) 729 for i := range embeddeds { 730 _ = r.pos() 731 embeddeds[i] = r.typ() 732 } 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 746 msig := r.signature(recv, nil, nil) 747 methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig) 748 } 749 750 typ := newInterface(methods, embeddeds) 751 r.p.interfaceList = append(r.p.interfaceList, typ) 752 return typ 753 754 case typeParamType: 755 if r.p.version < iexportVersionGenerics { 756 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 768 case instanceType: 769 if r.p.version < iexportVersionGenerics { 770 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: 788 if r.p.version < iexportVersionGenerics { 789 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) 796 } 797 } 798 799 func (r *importReader) kind() itag { 800 return itag(r.uint64()) 801 } 802 803 func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature { 804 params := r.paramList() 805 results := r.paramList() 806 variadic := params.Len() > 0 && r.bool() 807 return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic) 808 } 809 810 func (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 824 func (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 832 func (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 839 func (r *importReader) bool() bool { 840 return r.uint64() != 0 841 } 842 843 func (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 851 func (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 859 func (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 } 866 867 func 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 }