cuelang.org/go@v0.10.1/internal/golangorgx/tools/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 "math/big" 21 "sort" 22 "strings" 23 24 "golang.org/x/tools/go/types/objectpath" 25 ) 26 27 type intReader struct { 28 *bytes.Reader 29 path string 30 } 31 32 func (r *intReader) int64() int64 { 33 i, err := binary.ReadVarint(r.Reader) 34 if err != nil { 35 errorf("import %q: read varint error: %v", r.path, err) 36 } 37 return i 38 } 39 40 func (r *intReader) uint64() uint64 { 41 i, err := binary.ReadUvarint(r.Reader) 42 if err != nil { 43 errorf("import %q: read varint error: %v", r.path, err) 44 } 45 return i 46 } 47 48 // Keep this in sync with constants in iexport.go. 49 const ( 50 iexportVersionGo1_11 = 0 51 iexportVersionPosCol = 1 52 iexportVersionGo1_18 = 2 53 iexportVersionGenerics = 2 54 55 iexportVersionCurrent = 2 56 ) 57 58 type ident struct { 59 pkg *types.Package 60 name string 61 } 62 63 const predeclReserved = 32 64 65 type itag uint64 66 67 const ( 68 // Types 69 definedType itag = iota 70 pointerType 71 sliceType 72 arrayType 73 chanType 74 mapType 75 signatureType 76 structType 77 interfaceType 78 typeParamType 79 instanceType 80 unionType 81 ) 82 83 // IImportData imports a package from the serialized package data 84 // and returns 0 and a reference to the package. 85 // If the export data version is not recognized or the format is otherwise 86 // compromised, an error is returned. 87 func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) { 88 pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, false, path, false, nil) 89 if err != nil { 90 return 0, nil, err 91 } 92 return 0, pkgs[0], nil 93 } 94 95 // IImportBundle imports a set of packages from the serialized package bundle. 96 func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) { 97 return iimportCommon(fset, GetPackagesFromMap(imports), data, true, "", false, nil) 98 } 99 100 // A GetPackagesFunc function obtains the non-nil symbols for a set of 101 // packages, creating and recursively importing them as needed. An 102 // implementation should store each package symbol is in the Pkg 103 // field of the items array. 104 // 105 // Any error causes importing to fail. This can be used to quickly read 106 // the import manifest of an export data file without fully decoding it. 107 type GetPackagesFunc = func(items []GetPackagesItem) error 108 109 // A GetPackagesItem is a request from the importer for the package 110 // symbol of the specified name and path. 111 type GetPackagesItem struct { 112 Name, Path string 113 Pkg *types.Package // to be filled in by GetPackagesFunc call 114 115 // private importer state 116 pathOffset uint64 117 nameIndex map[string]uint64 118 } 119 120 // GetPackagesFromMap returns a GetPackagesFunc that retrieves 121 // packages from the given map of package path to package. 122 // 123 // The returned function may mutate m: each requested package that is not 124 // found is created with types.NewPackage and inserted into m. 125 func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc { 126 return func(items []GetPackagesItem) error { 127 for i, item := range items { 128 pkg, ok := m[item.Path] 129 if !ok { 130 pkg = types.NewPackage(item.Path, item.Name) 131 m[item.Path] = pkg 132 } 133 items[i].Pkg = pkg 134 } 135 return nil 136 } 137 } 138 139 func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, bundle bool, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) { 140 const currentVersion = iexportVersionCurrent 141 version := int64(-1) 142 if !debug { 143 defer func() { 144 if e := recover(); e != nil { 145 if bundle { 146 err = fmt.Errorf("%v", e) 147 } else if version > currentVersion { 148 err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) 149 } else { 150 err = fmt.Errorf("internal error while importing %q (%v); please report an issue", path, e) 151 } 152 } 153 }() 154 } 155 156 r := &intReader{bytes.NewReader(data), path} 157 158 if bundle { 159 if v := r.uint64(); v != bundleVersion { 160 errorf("unknown bundle format version %d", v) 161 } 162 } 163 164 version = int64(r.uint64()) 165 switch version { 166 case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: 167 default: 168 if version > iexportVersionGo1_18 { 169 errorf("unstable iexport format version %d, just rebuild compiler and std library", version) 170 } else { 171 errorf("unknown iexport format version %d", version) 172 } 173 } 174 175 sLen := int64(r.uint64()) 176 var fLen int64 177 var fileOffset []uint64 178 if shallow { 179 // Shallow mode uses a different position encoding. 180 fLen = int64(r.uint64()) 181 fileOffset = make([]uint64, r.uint64()) 182 for i := range fileOffset { 183 fileOffset[i] = r.uint64() 184 } 185 } 186 dLen := int64(r.uint64()) 187 188 whence, _ := r.Seek(0, io.SeekCurrent) 189 stringData := data[whence : whence+sLen] 190 fileData := data[whence+sLen : whence+sLen+fLen] 191 declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen] 192 r.Seek(sLen+fLen+dLen, io.SeekCurrent) 193 194 p := iimporter{ 195 version: int(version), 196 ipath: path, 197 shallow: shallow, 198 reportf: reportf, 199 200 stringData: stringData, 201 stringCache: make(map[uint64]string), 202 fileOffset: fileOffset, 203 fileData: fileData, 204 fileCache: make([]*token.File, len(fileOffset)), 205 pkgCache: make(map[uint64]*types.Package), 206 207 declData: declData, 208 pkgIndex: make(map[*types.Package]map[string]uint64), 209 typCache: make(map[uint64]types.Type), 210 // Separate map for typeparams, keyed by their package and unique 211 // name. 212 tparamIndex: make(map[ident]types.Type), 213 214 fake: fakeFileSet{ 215 fset: fset, 216 files: make(map[string]*fileInfo), 217 }, 218 } 219 defer p.fake.setLines() // set lines for files in fset 220 221 for i, pt := range predeclared() { 222 p.typCache[uint64(i)] = pt 223 } 224 225 // Gather the relevant packages from the manifest. 226 items := make([]GetPackagesItem, r.uint64()) 227 uniquePkgPaths := make(map[string]bool) 228 for i := range items { 229 pkgPathOff := r.uint64() 230 pkgPath := p.stringAt(pkgPathOff) 231 pkgName := p.stringAt(r.uint64()) 232 _ = r.uint64() // package height; unused by go/types 233 234 if pkgPath == "" { 235 pkgPath = path 236 } 237 items[i].Name = pkgName 238 items[i].Path = pkgPath 239 items[i].pathOffset = pkgPathOff 240 241 // Read index for package. 242 nameIndex := make(map[string]uint64) 243 nSyms := r.uint64() 244 // In shallow mode, only the current package (i=0) has an index. 245 assert(!(shallow && i > 0 && nSyms != 0)) 246 for ; nSyms > 0; nSyms-- { 247 name := p.stringAt(r.uint64()) 248 nameIndex[name] = r.uint64() 249 } 250 251 items[i].nameIndex = nameIndex 252 253 uniquePkgPaths[pkgPath] = true 254 } 255 // Debugging #63822; hypothesis: there are duplicate PkgPaths. 256 if len(uniquePkgPaths) != len(items) { 257 reportf("found duplicate PkgPaths while reading export data manifest: %v", items) 258 } 259 260 // Request packages all at once from the client, 261 // enabling a parallel implementation. 262 if err := getPackages(items); err != nil { 263 return nil, err // don't wrap this error 264 } 265 266 // Check the results and complete the index. 267 pkgList := make([]*types.Package, len(items)) 268 for i, item := range items { 269 pkg := item.Pkg 270 if pkg == nil { 271 errorf("internal error: getPackages returned nil package for %q", item.Path) 272 } else if pkg.Path() != item.Path { 273 errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path) 274 } else if pkg.Name() != item.Name { 275 errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name) 276 } 277 p.pkgCache[item.pathOffset] = pkg 278 p.pkgIndex[pkg] = item.nameIndex 279 pkgList[i] = pkg 280 } 281 282 if bundle { 283 pkgs = make([]*types.Package, r.uint64()) 284 for i := range pkgs { 285 pkg := p.pkgAt(r.uint64()) 286 imps := make([]*types.Package, r.uint64()) 287 for j := range imps { 288 imps[j] = p.pkgAt(r.uint64()) 289 } 290 pkg.SetImports(imps) 291 pkgs[i] = pkg 292 } 293 } else { 294 if len(pkgList) == 0 { 295 errorf("no packages found for %s", path) 296 panic("unreachable") 297 } 298 pkgs = pkgList[:1] 299 300 // record all referenced packages as imports 301 list := append(([]*types.Package)(nil), pkgList[1:]...) 302 sort.Sort(byPath(list)) 303 pkgs[0].SetImports(list) 304 } 305 306 for _, pkg := range pkgs { 307 if pkg.Complete() { 308 continue 309 } 310 311 names := make([]string, 0, len(p.pkgIndex[pkg])) 312 for name := range p.pkgIndex[pkg] { 313 names = append(names, name) 314 } 315 sort.Strings(names) 316 for _, name := range names { 317 p.doDecl(pkg, name) 318 } 319 320 // package was imported completely and without errors 321 pkg.MarkComplete() 322 } 323 324 // SetConstraint can't be called if the constraint type is not yet complete. 325 // When type params are created in the 'P' case of (*importReader).obj(), 326 // the associated constraint type may not be complete due to recursion. 327 // Therefore, we defer calling SetConstraint there, and call it here instead 328 // after all types are complete. 329 for _, d := range p.later { 330 d.t.SetConstraint(d.constraint) 331 } 332 333 for _, typ := range p.interfaceList { 334 typ.Complete() 335 } 336 337 // Workaround for golang/go#61561. See the doc for instanceList for details. 338 for _, typ := range p.instanceList { 339 if iface, _ := typ.Underlying().(*types.Interface); iface != nil { 340 iface.Complete() 341 } 342 } 343 344 return pkgs, nil 345 } 346 347 type setConstraintArgs struct { 348 t *types.TypeParam 349 constraint types.Type 350 } 351 352 type iimporter struct { 353 version int 354 ipath string 355 356 shallow bool 357 reportf ReportFunc // if non-nil, used to report bugs 358 359 stringData []byte 360 stringCache map[uint64]string 361 fileOffset []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i 362 fileData []byte 363 fileCache []*token.File // memoized decoding of file encoded as i 364 pkgCache map[uint64]*types.Package 365 366 declData []byte 367 pkgIndex map[*types.Package]map[string]uint64 368 typCache map[uint64]types.Type 369 tparamIndex map[ident]types.Type 370 371 fake fakeFileSet 372 interfaceList []*types.Interface 373 374 // Workaround for the go/types bug golang/go#61561: instances produced during 375 // instantiation may contain incomplete interfaces. Here we only complete the 376 // underlying type of the instance, which is the most common case but doesn't 377 // handle parameterized interface literals defined deeper in the type. 378 instanceList []types.Type // instances for later completion (see golang/go#61561) 379 380 // Arguments for calls to SetConstraint that are deferred due to recursive types 381 later []setConstraintArgs 382 383 indent int // for tracing support 384 } 385 386 func (p *iimporter) trace(format string, args ...interface{}) { 387 if !trace { 388 // Call sites should also be guarded, but having this check here allows 389 // easily enabling/disabling debug trace statements. 390 return 391 } 392 fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) 393 } 394 395 func (p *iimporter) doDecl(pkg *types.Package, name string) { 396 if debug { 397 p.trace("import decl %s", name) 398 p.indent++ 399 defer func() { 400 p.indent-- 401 p.trace("=> %s", name) 402 }() 403 } 404 // See if we've already imported this declaration. 405 if obj := pkg.Scope().Lookup(name); obj != nil { 406 return 407 } 408 409 off, ok := p.pkgIndex[pkg][name] 410 if !ok { 411 // In deep mode, the index should be complete. In shallow 412 // mode, we should have already recursively loaded necessary 413 // dependencies so the above Lookup succeeds. 414 errorf("%v.%v not in index", pkg, name) 415 } 416 417 r := &importReader{p: p, currPkg: pkg} 418 r.declReader.Reset(p.declData[off:]) 419 420 r.obj(name) 421 } 422 423 func (p *iimporter) stringAt(off uint64) string { 424 if s, ok := p.stringCache[off]; ok { 425 return s 426 } 427 428 slen, n := binary.Uvarint(p.stringData[off:]) 429 if n <= 0 { 430 errorf("varint failed") 431 } 432 spos := off + uint64(n) 433 s := string(p.stringData[spos : spos+slen]) 434 p.stringCache[off] = s 435 return s 436 } 437 438 func (p *iimporter) fileAt(index uint64) *token.File { 439 file := p.fileCache[index] 440 if file == nil { 441 off := p.fileOffset[index] 442 file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath}) 443 p.fileCache[index] = file 444 } 445 return file 446 } 447 448 func (p *iimporter) decodeFile(rd intReader) *token.File { 449 filename := p.stringAt(rd.uint64()) 450 size := int(rd.uint64()) 451 file := p.fake.fset.AddFile(filename, -1, size) 452 453 // SetLines requires a nondecreasing sequence. 454 // Because it is common for clients to derive the interval 455 // [start, start+len(name)] from a start position, and we 456 // want to ensure that the end offset is on the same line, 457 // we fill in the gaps of the sparse encoding with values 458 // that strictly increase by the largest possible amount. 459 // This allows us to avoid having to record the actual end 460 // offset of each needed line. 461 462 lines := make([]int, int(rd.uint64())) 463 var index, offset int 464 for i, n := 0, int(rd.uint64()); i < n; i++ { 465 index += int(rd.uint64()) 466 offset += int(rd.uint64()) 467 lines[index] = offset 468 469 // Ensure monotonicity between points. 470 for j := index - 1; j > 0 && lines[j] == 0; j-- { 471 lines[j] = lines[j+1] - 1 472 } 473 } 474 475 // Ensure monotonicity after last point. 476 for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- { 477 size-- 478 lines[j] = size 479 } 480 481 if !file.SetLines(lines) { 482 errorf("SetLines failed: %d", lines) // can't happen 483 } 484 return file 485 } 486 487 func (p *iimporter) pkgAt(off uint64) *types.Package { 488 if pkg, ok := p.pkgCache[off]; ok { 489 return pkg 490 } 491 path := p.stringAt(off) 492 errorf("missing package %q in %q", path, p.ipath) 493 return nil 494 } 495 496 func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { 497 if t, ok := p.typCache[off]; ok && canReuse(base, t) { 498 return t 499 } 500 501 if off < predeclReserved { 502 errorf("predeclared type missing from cache: %v", off) 503 } 504 505 r := &importReader{p: p} 506 r.declReader.Reset(p.declData[off-predeclReserved:]) 507 t := r.doType(base) 508 509 if canReuse(base, t) { 510 p.typCache[off] = t 511 } 512 return t 513 } 514 515 // canReuse reports whether the type rhs on the RHS of the declaration for def 516 // may be re-used. 517 // 518 // Specifically, if def is non-nil and rhs is an interface type with methods, it 519 // may not be re-used because we have a convention of setting the receiver type 520 // for interface methods to def. 521 func canReuse(def *types.Named, rhs types.Type) bool { 522 if def == nil { 523 return true 524 } 525 iface, _ := rhs.(*types.Interface) 526 if iface == nil { 527 return true 528 } 529 // Don't use iface.Empty() here as iface may not be complete. 530 return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 531 } 532 533 type importReader struct { 534 p *iimporter 535 declReader bytes.Reader 536 currPkg *types.Package 537 prevFile string 538 prevLine int64 539 prevColumn int64 540 } 541 542 func (r *importReader) obj(name string) { 543 tag := r.byte() 544 pos := r.pos() 545 546 switch tag { 547 case 'A': 548 typ := r.typ() 549 550 r.declare(types.NewTypeName(pos, r.currPkg, name, typ)) 551 552 case 'C': 553 typ, val := r.value() 554 555 r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) 556 557 case 'F', 'G': 558 var tparams []*types.TypeParam 559 if tag == 'G' { 560 tparams = r.tparamList() 561 } 562 sig := r.signature(nil, nil, tparams) 563 r.declare(types.NewFunc(pos, r.currPkg, name, sig)) 564 565 case 'T', 'U': 566 // Types can be recursive. We need to setup a stub 567 // declaration before recursing. 568 obj := types.NewTypeName(pos, r.currPkg, name, nil) 569 named := types.NewNamed(obj, nil, nil) 570 // Declare obj before calling r.tparamList, so the new type name is recognized 571 // if used in the constraint of one of its own typeparams (see #48280). 572 r.declare(obj) 573 if tag == 'U' { 574 tparams := r.tparamList() 575 named.SetTypeParams(tparams) 576 } 577 578 underlying := r.p.typAt(r.uint64(), named).Underlying() 579 named.SetUnderlying(underlying) 580 581 if !isInterface(underlying) { 582 for n := r.uint64(); n > 0; n-- { 583 mpos := r.pos() 584 mname := r.ident() 585 recv := r.param() 586 587 // If the receiver has any targs, set those as the 588 // rparams of the method (since those are the 589 // typeparams being used in the method sig/body). 590 base := baseType(recv.Type()) 591 assert(base != nil) 592 targs := base.TypeArgs() 593 var rparams []*types.TypeParam 594 if targs.Len() > 0 { 595 rparams = make([]*types.TypeParam, targs.Len()) 596 for i := range rparams { 597 rparams[i] = targs.At(i).(*types.TypeParam) 598 } 599 } 600 msig := r.signature(recv, rparams, nil) 601 602 named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) 603 } 604 } 605 606 case 'P': 607 // We need to "declare" a typeparam in order to have a name that 608 // can be referenced recursively (if needed) in the type param's 609 // bound. 610 if r.p.version < iexportVersionGenerics { 611 errorf("unexpected type param type") 612 } 613 name0 := tparamName(name) 614 tn := types.NewTypeName(pos, r.currPkg, name0, nil) 615 t := types.NewTypeParam(tn, nil) 616 617 // To handle recursive references to the typeparam within its 618 // bound, save the partial type in tparamIndex before reading the bounds. 619 id := ident{r.currPkg, name} 620 r.p.tparamIndex[id] = t 621 var implicit bool 622 if r.p.version >= iexportVersionGo1_18 { 623 implicit = r.bool() 624 } 625 constraint := r.typ() 626 if implicit { 627 iface, _ := constraint.(*types.Interface) 628 if iface == nil { 629 errorf("non-interface constraint marked implicit") 630 } 631 iface.MarkImplicit() 632 } 633 // The constraint type may not be complete, if we 634 // are in the middle of a type recursion involving type 635 // constraints. So, we defer SetConstraint until we have 636 // completely set up all types in ImportData. 637 r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) 638 639 case 'V': 640 typ := r.typ() 641 642 r.declare(types.NewVar(pos, r.currPkg, name, typ)) 643 644 default: 645 errorf("unexpected tag: %v", tag) 646 } 647 } 648 649 func (r *importReader) declare(obj types.Object) { 650 obj.Pkg().Scope().Insert(obj) 651 } 652 653 func (r *importReader) value() (typ types.Type, val constant.Value) { 654 typ = r.typ() 655 if r.p.version >= iexportVersionGo1_18 { 656 // TODO: add support for using the kind. 657 _ = constant.Kind(r.int64()) 658 } 659 660 switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { 661 case types.IsBoolean: 662 val = constant.MakeBool(r.bool()) 663 664 case types.IsString: 665 val = constant.MakeString(r.string()) 666 667 case types.IsInteger: 668 var x big.Int 669 r.mpint(&x, b) 670 val = constant.Make(&x) 671 672 case types.IsFloat: 673 val = r.mpfloat(b) 674 675 case types.IsComplex: 676 re := r.mpfloat(b) 677 im := r.mpfloat(b) 678 val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) 679 680 default: 681 if b.Kind() == types.Invalid { 682 val = constant.MakeUnknown() 683 return 684 } 685 errorf("unexpected type %v", typ) // panics 686 panic("unreachable") 687 } 688 689 return 690 } 691 692 func intSize(b *types.Basic) (signed bool, maxBytes uint) { 693 if (b.Info() & types.IsUntyped) != 0 { 694 return true, 64 695 } 696 697 switch b.Kind() { 698 case types.Float32, types.Complex64: 699 return true, 3 700 case types.Float64, types.Complex128: 701 return true, 7 702 } 703 704 signed = (b.Info() & types.IsUnsigned) == 0 705 switch b.Kind() { 706 case types.Int8, types.Uint8: 707 maxBytes = 1 708 case types.Int16, types.Uint16: 709 maxBytes = 2 710 case types.Int32, types.Uint32: 711 maxBytes = 4 712 default: 713 maxBytes = 8 714 } 715 716 return 717 } 718 719 func (r *importReader) mpint(x *big.Int, typ *types.Basic) { 720 signed, maxBytes := intSize(typ) 721 722 maxSmall := 256 - maxBytes 723 if signed { 724 maxSmall = 256 - 2*maxBytes 725 } 726 if maxBytes == 1 { 727 maxSmall = 256 728 } 729 730 n, _ := r.declReader.ReadByte() 731 if uint(n) < maxSmall { 732 v := int64(n) 733 if signed { 734 v >>= 1 735 if n&1 != 0 { 736 v = ^v 737 } 738 } 739 x.SetInt64(v) 740 return 741 } 742 743 v := -n 744 if signed { 745 v = -(n &^ 1) >> 1 746 } 747 if v < 1 || uint(v) > maxBytes { 748 errorf("weird decoding: %v, %v => %v", n, signed, v) 749 } 750 b := make([]byte, v) 751 io.ReadFull(&r.declReader, b) 752 x.SetBytes(b) 753 if signed && n&1 != 0 { 754 x.Neg(x) 755 } 756 } 757 758 func (r *importReader) mpfloat(typ *types.Basic) constant.Value { 759 var mant big.Int 760 r.mpint(&mant, typ) 761 var f big.Float 762 f.SetInt(&mant) 763 if f.Sign() != 0 { 764 f.SetMantExp(&f, int(r.int64())) 765 } 766 return constant.Make(&f) 767 } 768 769 func (r *importReader) ident() string { 770 return r.string() 771 } 772 773 func (r *importReader) qualifiedIdent() (*types.Package, string) { 774 name := r.string() 775 pkg := r.pkg() 776 return pkg, name 777 } 778 779 func (r *importReader) pos() token.Pos { 780 if r.p.shallow { 781 // precise offsets are encoded only in shallow mode 782 return r.posv2() 783 } 784 if r.p.version >= iexportVersionPosCol { 785 r.posv1() 786 } else { 787 r.posv0() 788 } 789 790 if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { 791 return token.NoPos 792 } 793 return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) 794 } 795 796 func (r *importReader) posv0() { 797 delta := r.int64() 798 if delta != deltaNewFile { 799 r.prevLine += delta 800 } else if l := r.int64(); l == -1 { 801 r.prevLine += deltaNewFile 802 } else { 803 r.prevFile = r.string() 804 r.prevLine = l 805 } 806 } 807 808 func (r *importReader) posv1() { 809 delta := r.int64() 810 r.prevColumn += delta >> 1 811 if delta&1 != 0 { 812 delta = r.int64() 813 r.prevLine += delta >> 1 814 if delta&1 != 0 { 815 r.prevFile = r.string() 816 } 817 } 818 } 819 820 func (r *importReader) posv2() token.Pos { 821 file := r.uint64() 822 if file == 0 { 823 return token.NoPos 824 } 825 tf := r.p.fileAt(file - 1) 826 return tf.Pos(int(r.uint64())) 827 } 828 829 func (r *importReader) typ() types.Type { 830 return r.p.typAt(r.uint64(), nil) 831 } 832 833 func isInterface(t types.Type) bool { 834 _, ok := t.(*types.Interface) 835 return ok 836 } 837 838 func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } 839 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } 840 841 func (r *importReader) doType(base *types.Named) (res types.Type) { 842 k := r.kind() 843 if debug { 844 r.p.trace("importing type %d (base: %s)", k, base) 845 r.p.indent++ 846 defer func() { 847 r.p.indent-- 848 r.p.trace("=> %s", res) 849 }() 850 } 851 switch k { 852 default: 853 errorf("unexpected kind tag in %q: %v", r.p.ipath, k) 854 return nil 855 856 case definedType: 857 pkg, name := r.qualifiedIdent() 858 r.p.doDecl(pkg, name) 859 return pkg.Scope().Lookup(name).(*types.TypeName).Type() 860 case pointerType: 861 return types.NewPointer(r.typ()) 862 case sliceType: 863 return types.NewSlice(r.typ()) 864 case arrayType: 865 n := r.uint64() 866 return types.NewArray(r.typ(), int64(n)) 867 case chanType: 868 dir := chanDir(int(r.uint64())) 869 return types.NewChan(dir, r.typ()) 870 case mapType: 871 return types.NewMap(r.typ(), r.typ()) 872 case signatureType: 873 r.currPkg = r.pkg() 874 return r.signature(nil, nil, nil) 875 876 case structType: 877 r.currPkg = r.pkg() 878 879 fields := make([]*types.Var, r.uint64()) 880 tags := make([]string, len(fields)) 881 for i := range fields { 882 var field *types.Var 883 if r.p.shallow { 884 field, _ = r.objectPathObject().(*types.Var) 885 } 886 887 fpos := r.pos() 888 fname := r.ident() 889 ftyp := r.typ() 890 emb := r.bool() 891 tag := r.string() 892 893 // Either this is not a shallow import, the field is local, or the 894 // encoded objectPath failed to produce an object (a bug). 895 // 896 // Even in this last, buggy case, fall back on creating a new field. As 897 // discussed in iexport.go, this is not correct, but mostly works and is 898 // preferable to failing (for now at least). 899 if field == nil { 900 field = types.NewField(fpos, r.currPkg, fname, ftyp, emb) 901 } 902 903 fields[i] = field 904 tags[i] = tag 905 } 906 return types.NewStruct(fields, tags) 907 908 case interfaceType: 909 r.currPkg = r.pkg() 910 911 embeddeds := make([]types.Type, r.uint64()) 912 for i := range embeddeds { 913 _ = r.pos() 914 embeddeds[i] = r.typ() 915 } 916 917 methods := make([]*types.Func, r.uint64()) 918 for i := range methods { 919 var method *types.Func 920 if r.p.shallow { 921 method, _ = r.objectPathObject().(*types.Func) 922 } 923 924 mpos := r.pos() 925 mname := r.ident() 926 927 // TODO(mdempsky): Matches bimport.go, but I 928 // don't agree with this. 929 var recv *types.Var 930 if base != nil { 931 recv = types.NewVar(token.NoPos, r.currPkg, "", base) 932 } 933 msig := r.signature(recv, nil, nil) 934 935 if method == nil { 936 method = types.NewFunc(mpos, r.currPkg, mname, msig) 937 } 938 methods[i] = method 939 } 940 941 typ := newInterface(methods, embeddeds) 942 r.p.interfaceList = append(r.p.interfaceList, typ) 943 return typ 944 945 case typeParamType: 946 if r.p.version < iexportVersionGenerics { 947 errorf("unexpected type param type") 948 } 949 pkg, name := r.qualifiedIdent() 950 id := ident{pkg, name} 951 if t, ok := r.p.tparamIndex[id]; ok { 952 // We're already in the process of importing this typeparam. 953 return t 954 } 955 // Otherwise, import the definition of the typeparam now. 956 r.p.doDecl(pkg, name) 957 return r.p.tparamIndex[id] 958 959 case instanceType: 960 if r.p.version < iexportVersionGenerics { 961 errorf("unexpected instantiation type") 962 } 963 // pos does not matter for instances: they are positioned on the original 964 // type. 965 _ = r.pos() 966 len := r.uint64() 967 targs := make([]types.Type, len) 968 for i := range targs { 969 targs[i] = r.typ() 970 } 971 baseType := r.typ() 972 // The imported instantiated type doesn't include any methods, so 973 // we must always use the methods of the base (orig) type. 974 // TODO provide a non-nil *Environment 975 t, _ := types.Instantiate(nil, baseType, targs, false) 976 977 // Workaround for golang/go#61561. See the doc for instanceList for details. 978 r.p.instanceList = append(r.p.instanceList, t) 979 return t 980 981 case unionType: 982 if r.p.version < iexportVersionGenerics { 983 errorf("unexpected instantiation type") 984 } 985 terms := make([]*types.Term, r.uint64()) 986 for i := range terms { 987 terms[i] = types.NewTerm(r.bool(), r.typ()) 988 } 989 return types.NewUnion(terms) 990 } 991 } 992 993 func (r *importReader) kind() itag { 994 return itag(r.uint64()) 995 } 996 997 // objectPathObject is the inverse of exportWriter.objectPath. 998 // 999 // In shallow mode, certain fields and methods may need to be looked up in an 1000 // imported package. See the doc for exportWriter.objectPath for a full 1001 // explanation. 1002 func (r *importReader) objectPathObject() types.Object { 1003 objPath := objectpath.Path(r.string()) 1004 if objPath == "" { 1005 return nil 1006 } 1007 pkg := r.pkg() 1008 obj, err := objectpath.Object(pkg, objPath) 1009 if err != nil { 1010 if r.p.reportf != nil { 1011 r.p.reportf("failed to find object for objectPath %q: %v", objPath, err) 1012 } 1013 } 1014 return obj 1015 } 1016 1017 func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature { 1018 params := r.paramList() 1019 results := r.paramList() 1020 variadic := params.Len() > 0 && r.bool() 1021 return types.NewSignatureType(recv, rparams, tparams, params, results, variadic) 1022 } 1023 1024 func (r *importReader) tparamList() []*types.TypeParam { 1025 n := r.uint64() 1026 if n == 0 { 1027 return nil 1028 } 1029 xs := make([]*types.TypeParam, n) 1030 for i := range xs { 1031 // Note: the standard library importer is tolerant of nil types here, 1032 // though would panic in SetTypeParams. 1033 xs[i] = r.typ().(*types.TypeParam) 1034 } 1035 return xs 1036 } 1037 1038 func (r *importReader) paramList() *types.Tuple { 1039 xs := make([]*types.Var, r.uint64()) 1040 for i := range xs { 1041 xs[i] = r.param() 1042 } 1043 return types.NewTuple(xs...) 1044 } 1045 1046 func (r *importReader) param() *types.Var { 1047 pos := r.pos() 1048 name := r.ident() 1049 typ := r.typ() 1050 return types.NewParam(pos, r.currPkg, name, typ) 1051 } 1052 1053 func (r *importReader) bool() bool { 1054 return r.uint64() != 0 1055 } 1056 1057 func (r *importReader) int64() int64 { 1058 n, err := binary.ReadVarint(&r.declReader) 1059 if err != nil { 1060 errorf("readVarint: %v", err) 1061 } 1062 return n 1063 } 1064 1065 func (r *importReader) uint64() uint64 { 1066 n, err := binary.ReadUvarint(&r.declReader) 1067 if err != nil { 1068 errorf("readUvarint: %v", err) 1069 } 1070 return n 1071 } 1072 1073 func (r *importReader) byte() byte { 1074 x, err := r.declReader.ReadByte() 1075 if err != nil { 1076 errorf("declReader.ReadByte: %v", err) 1077 } 1078 return x 1079 } 1080 1081 func baseType(typ types.Type) *types.Named { 1082 // pointer receivers are never types.Named types 1083 if p, _ := typ.(*types.Pointer); p != nil { 1084 typ = p.Elem() 1085 } 1086 // receiver base types are always (possibly generic) types.Named types 1087 n, _ := typ.(*types.Named) 1088 return n 1089 }