gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/golang.org/x/tools/go/gcimporter15/bimport.go (about) 1 // Copyright 2015 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 // This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go. 6 7 package gcimporter 8 9 import ( 10 "encoding/binary" 11 "fmt" 12 "go/constant" 13 "go/token" 14 "go/types" 15 "sort" 16 "strconv" 17 "strings" 18 "sync" 19 "unicode" 20 "unicode/utf8" 21 ) 22 23 type importer struct { 24 imports map[string]*types.Package 25 data []byte 26 importpath string 27 buf []byte // for reading strings 28 version int // export format version 29 30 // object lists 31 strList []string // in order of appearance 32 pathList []string // in order of appearance 33 pkgList []*types.Package // in order of appearance 34 typList []types.Type // in order of appearance 35 interfaceList []*types.Interface // for delayed completion only 36 trackAllTypes bool 37 38 // position encoding 39 posInfoFormat bool 40 prevFile string 41 prevLine int 42 fset *token.FileSet 43 files map[string]*token.File 44 45 // debugging support 46 debugFormat bool 47 read int // bytes read 48 } 49 50 // BImportData imports a package from the serialized package data 51 // and returns the number of bytes consumed and a reference to the package. 52 // If the export data version is not recognized or the format is otherwise 53 // compromised, an error is returned. 54 func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { 55 // catch panics and return them as errors 56 defer func() { 57 if e := recover(); e != nil { 58 // The package (filename) causing the problem is added to this 59 // error by a wrapper in the caller (Import in gcimporter.go). 60 // Return a (possibly nil or incomplete) package unchanged (see #16088). 61 err = fmt.Errorf("cannot import, possibly version skew (%v) - reinstall package", e) 62 } 63 }() 64 65 p := importer{ 66 imports: imports, 67 data: data, 68 importpath: path, 69 version: -1, // unknown version 70 strList: []string{""}, // empty string is mapped to 0 71 pathList: []string{""}, // empty string is mapped to 0 72 fset: fset, 73 files: make(map[string]*token.File), 74 } 75 76 // read version info 77 var versionstr string 78 if b := p.rawByte(); b == 'c' || b == 'd' { 79 // Go1.7 encoding; first byte encodes low-level 80 // encoding format (compact vs debug). 81 // For backward-compatibility only (avoid problems with 82 // old installed packages). Newly compiled packages use 83 // the extensible format string. 84 // TODO(gri) Remove this support eventually; after Go1.8. 85 if b == 'd' { 86 p.debugFormat = true 87 } 88 p.trackAllTypes = p.rawByte() == 'a' 89 p.posInfoFormat = p.int() != 0 90 versionstr = p.string() 91 if versionstr == "v1" { 92 p.version = 0 93 } 94 } else { 95 // Go1.8 extensible encoding 96 // read version string and extract version number (ignore anything after the version number) 97 versionstr = p.rawStringln(b) 98 if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" { 99 if v, err := strconv.Atoi(s[1]); err == nil && v > 0 { 100 p.version = v 101 } 102 } 103 } 104 105 // read version specific flags - extend as necessary 106 switch p.version { 107 // case 6: 108 // ... 109 // fallthrough 110 case 5, 4, 3, 2, 1: 111 p.debugFormat = p.rawStringln(p.rawByte()) == "debug" 112 p.trackAllTypes = p.int() != 0 113 p.posInfoFormat = p.int() != 0 114 case 0: 115 // Go1.7 encoding format - nothing to do here 116 default: 117 errorf("unknown export format version %d (%q)", p.version, versionstr) 118 } 119 120 // --- generic export data --- 121 122 // populate typList with predeclared "known" types 123 p.typList = append(p.typList, predeclared...) 124 125 // read package data 126 pkg = p.pkg() 127 128 // read objects of phase 1 only (see cmd/compiler/internal/gc/bexport.go) 129 objcount := 0 130 for { 131 tag := p.tagOrIndex() 132 if tag == endTag { 133 break 134 } 135 p.obj(tag) 136 objcount++ 137 } 138 139 // self-verification 140 if count := p.int(); count != objcount { 141 errorf("got %d objects; want %d", objcount, count) 142 } 143 144 // ignore compiler-specific import data 145 146 // complete interfaces 147 // TODO(gri) re-investigate if we still need to do this in a delayed fashion 148 for _, typ := range p.interfaceList { 149 typ.Complete() 150 } 151 152 // record all referenced packages as imports 153 list := append(([]*types.Package)(nil), p.pkgList[1:]...) 154 sort.Sort(byPath(list)) 155 pkg.SetImports(list) 156 157 // package was imported completely and without errors 158 pkg.MarkComplete() 159 160 return p.read, pkg, nil 161 } 162 163 func errorf(format string, args ...interface{}) { 164 panic(fmt.Sprintf(format, args...)) 165 } 166 167 func (p *importer) pkg() *types.Package { 168 // if the package was seen before, i is its index (>= 0) 169 i := p.tagOrIndex() 170 if i >= 0 { 171 return p.pkgList[i] 172 } 173 174 // otherwise, i is the package tag (< 0) 175 if i != packageTag { 176 errorf("unexpected package tag %d version %d", i, p.version) 177 } 178 179 // read package data 180 name := p.string() 181 var path string 182 if p.version >= 5 { 183 path = p.path() 184 } else { 185 path = p.string() 186 } 187 188 // we should never see an empty package name 189 if name == "" { 190 errorf("empty package name in import") 191 } 192 193 // an empty path denotes the package we are currently importing; 194 // it must be the first package we see 195 if (path == "") != (len(p.pkgList) == 0) { 196 errorf("package path %q for pkg index %d", path, len(p.pkgList)) 197 } 198 199 // if the package was imported before, use that one; otherwise create a new one 200 if path == "" { 201 path = p.importpath 202 } 203 pkg := p.imports[path] 204 if pkg == nil { 205 pkg = types.NewPackage(path, name) 206 p.imports[path] = pkg 207 } else if pkg.Name() != name { 208 errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path) 209 } 210 p.pkgList = append(p.pkgList, pkg) 211 212 return pkg 213 } 214 215 // objTag returns the tag value for each object kind. 216 func objTag(obj types.Object) int { 217 switch obj.(type) { 218 case *types.Const: 219 return constTag 220 case *types.TypeName: 221 return typeTag 222 case *types.Var: 223 return varTag 224 case *types.Func: 225 return funcTag 226 default: 227 errorf("unexpected object: %v (%T)", obj, obj) // panics 228 panic("unreachable") 229 } 230 } 231 232 func sameObj(a, b types.Object) bool { 233 // Because unnamed types are not canonicalized, we cannot simply compare types for 234 // (pointer) identity. 235 // Ideally we'd check equality of constant values as well, but this is good enough. 236 return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type()) 237 } 238 239 func (p *importer) declare(obj types.Object) { 240 pkg := obj.Pkg() 241 if alt := pkg.Scope().Insert(obj); alt != nil { 242 // This can only trigger if we import a (non-type) object a second time. 243 // Excluding type aliases, this cannot happen because 1) we only import a package 244 // once; and b) we ignore compiler-specific export data which may contain 245 // functions whose inlined function bodies refer to other functions that 246 // were already imported. 247 // However, type aliases require reexporting the original type, so we need 248 // to allow it (see also the comment in cmd/compile/internal/gc/bimport.go, 249 // method importer.obj, switch case importing functions). 250 // TODO(gri) review/update this comment once the gc compiler handles type aliases. 251 if !sameObj(obj, alt) { 252 errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt) 253 } 254 } 255 } 256 257 func (p *importer) obj(tag int) { 258 switch tag { 259 case constTag: 260 pos := p.pos() 261 pkg, name := p.qualifiedName() 262 typ := p.typ(nil) 263 val := p.value() 264 p.declare(types.NewConst(pos, pkg, name, typ, val)) 265 266 case aliasTag: 267 // TODO(gri) verify type alias hookup is correct 268 pos := p.pos() 269 pkg, name := p.qualifiedName() 270 typ := p.typ(nil) 271 p.declare(types.NewTypeName(pos, pkg, name, typ)) 272 273 case typeTag: 274 p.typ(nil) 275 276 case varTag: 277 pos := p.pos() 278 pkg, name := p.qualifiedName() 279 typ := p.typ(nil) 280 p.declare(types.NewVar(pos, pkg, name, typ)) 281 282 case funcTag: 283 pos := p.pos() 284 pkg, name := p.qualifiedName() 285 params, isddd := p.paramList() 286 result, _ := p.paramList() 287 sig := types.NewSignature(nil, params, result, isddd) 288 p.declare(types.NewFunc(pos, pkg, name, sig)) 289 290 default: 291 errorf("unexpected object tag %d", tag) 292 } 293 } 294 295 const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go 296 297 func (p *importer) pos() token.Pos { 298 if !p.posInfoFormat { 299 return token.NoPos 300 } 301 302 file := p.prevFile 303 line := p.prevLine 304 delta := p.int() 305 line += delta 306 if p.version >= 5 { 307 if delta == deltaNewFile { 308 if n := p.int(); n >= 0 { 309 // file changed 310 file = p.path() 311 line = n 312 } 313 } 314 } else { 315 if delta == 0 { 316 if n := p.int(); n >= 0 { 317 // file changed 318 file = p.prevFile[:n] + p.string() 319 line = p.int() 320 } 321 } 322 } 323 p.prevFile = file 324 p.prevLine = line 325 326 // Synthesize a token.Pos 327 328 // Since we don't know the set of needed file positions, we 329 // reserve maxlines positions per file. 330 const maxlines = 64 * 1024 331 f := p.files[file] 332 if f == nil { 333 f = p.fset.AddFile(file, -1, maxlines) 334 p.files[file] = f 335 // Allocate the fake linebreak indices on first use. 336 // TODO(adonovan): opt: save ~512KB using a more complex scheme? 337 fakeLinesOnce.Do(func() { 338 fakeLines = make([]int, maxlines) 339 for i := range fakeLines { 340 fakeLines[i] = i 341 } 342 }) 343 f.SetLines(fakeLines) 344 } 345 346 if line > maxlines { 347 line = 1 348 } 349 350 // Treat the file as if it contained only newlines 351 // and column=1: use the line number as the offset. 352 return f.Pos(line - 1) 353 } 354 355 var ( 356 fakeLines []int 357 fakeLinesOnce sync.Once 358 ) 359 360 func (p *importer) qualifiedName() (pkg *types.Package, name string) { 361 name = p.string() 362 pkg = p.pkg() 363 return 364 } 365 366 func (p *importer) record(t types.Type) { 367 p.typList = append(p.typList, t) 368 } 369 370 // A dddSlice is a types.Type representing ...T parameters. 371 // It only appears for parameter types and does not escape 372 // the importer. 373 type dddSlice struct { 374 elem types.Type 375 } 376 377 func (t *dddSlice) Underlying() types.Type { return t } 378 func (t *dddSlice) String() string { return "..." + t.elem.String() } 379 380 // parent is the package which declared the type; parent == nil means 381 // the package currently imported. The parent package is needed for 382 // exported struct fields and interface methods which don't contain 383 // explicit package information in the export data. 384 func (p *importer) typ(parent *types.Package) types.Type { 385 // if the type was seen before, i is its index (>= 0) 386 i := p.tagOrIndex() 387 if i >= 0 { 388 return p.typList[i] 389 } 390 391 // otherwise, i is the type tag (< 0) 392 switch i { 393 case namedTag: 394 // read type object 395 pos := p.pos() 396 parent, name := p.qualifiedName() 397 scope := parent.Scope() 398 obj := scope.Lookup(name) 399 400 // if the object doesn't exist yet, create and insert it 401 if obj == nil { 402 obj = types.NewTypeName(pos, parent, name, nil) 403 scope.Insert(obj) 404 } 405 406 if _, ok := obj.(*types.TypeName); !ok { 407 errorf("pkg = %s, name = %s => %s", parent, name, obj) 408 } 409 410 // associate new named type with obj if it doesn't exist yet 411 t0 := types.NewNamed(obj.(*types.TypeName), nil, nil) 412 413 // but record the existing type, if any 414 t := obj.Type().(*types.Named) 415 p.record(t) 416 417 // read underlying type 418 t0.SetUnderlying(p.typ(parent)) 419 420 // interfaces don't have associated methods 421 if types.IsInterface(t0) { 422 return t 423 } 424 425 // read associated methods 426 for i := p.int(); i > 0; i-- { 427 // TODO(gri) replace this with something closer to fieldName 428 pos := p.pos() 429 name := p.string() 430 if !exported(name) { 431 p.pkg() 432 } 433 434 recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver? 435 params, isddd := p.paramList() 436 result, _ := p.paramList() 437 p.int() // go:nointerface pragma - discarded 438 439 sig := types.NewSignature(recv.At(0), params, result, isddd) 440 t0.AddMethod(types.NewFunc(pos, parent, name, sig)) 441 } 442 443 return t 444 445 case arrayTag: 446 t := new(types.Array) 447 if p.trackAllTypes { 448 p.record(t) 449 } 450 451 n := p.int64() 452 *t = *types.NewArray(p.typ(parent), n) 453 return t 454 455 case sliceTag: 456 t := new(types.Slice) 457 if p.trackAllTypes { 458 p.record(t) 459 } 460 461 *t = *types.NewSlice(p.typ(parent)) 462 return t 463 464 case dddTag: 465 t := new(dddSlice) 466 if p.trackAllTypes { 467 p.record(t) 468 } 469 470 t.elem = p.typ(parent) 471 return t 472 473 case structTag: 474 t := new(types.Struct) 475 if p.trackAllTypes { 476 p.record(t) 477 } 478 479 *t = *types.NewStruct(p.fieldList(parent)) 480 return t 481 482 case pointerTag: 483 t := new(types.Pointer) 484 if p.trackAllTypes { 485 p.record(t) 486 } 487 488 *t = *types.NewPointer(p.typ(parent)) 489 return t 490 491 case signatureTag: 492 t := new(types.Signature) 493 if p.trackAllTypes { 494 p.record(t) 495 } 496 497 params, isddd := p.paramList() 498 result, _ := p.paramList() 499 *t = *types.NewSignature(nil, params, result, isddd) 500 return t 501 502 case interfaceTag: 503 // Create a dummy entry in the type list. This is safe because we 504 // cannot expect the interface type to appear in a cycle, as any 505 // such cycle must contain a named type which would have been 506 // first defined earlier. 507 n := len(p.typList) 508 if p.trackAllTypes { 509 p.record(nil) 510 } 511 512 var embeddeds []*types.Named 513 for n := p.int(); n > 0; n-- { 514 p.pos() 515 embeddeds = append(embeddeds, p.typ(parent).(*types.Named)) 516 } 517 518 t := types.NewInterface(p.methodList(parent), embeddeds) 519 p.interfaceList = append(p.interfaceList, t) 520 if p.trackAllTypes { 521 p.typList[n] = t 522 } 523 return t 524 525 case mapTag: 526 t := new(types.Map) 527 if p.trackAllTypes { 528 p.record(t) 529 } 530 531 key := p.typ(parent) 532 val := p.typ(parent) 533 *t = *types.NewMap(key, val) 534 return t 535 536 case chanTag: 537 t := new(types.Chan) 538 if p.trackAllTypes { 539 p.record(t) 540 } 541 542 var dir types.ChanDir 543 // tag values must match the constants in cmd/compile/internal/gc/go.go 544 switch d := p.int(); d { 545 case 1 /* Crecv */ : 546 dir = types.RecvOnly 547 case 2 /* Csend */ : 548 dir = types.SendOnly 549 case 3 /* Cboth */ : 550 dir = types.SendRecv 551 default: 552 errorf("unexpected channel dir %d", d) 553 } 554 val := p.typ(parent) 555 *t = *types.NewChan(dir, val) 556 return t 557 558 default: 559 errorf("unexpected type tag %d", i) // panics 560 panic("unreachable") 561 } 562 } 563 564 func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) { 565 if n := p.int(); n > 0 { 566 fields = make([]*types.Var, n) 567 tags = make([]string, n) 568 for i := range fields { 569 fields[i], tags[i] = p.field(parent) 570 } 571 } 572 return 573 } 574 575 func (p *importer) field(parent *types.Package) (*types.Var, string) { 576 pos := p.pos() 577 pkg, name, alias := p.fieldName(parent) 578 typ := p.typ(parent) 579 tag := p.string() 580 581 anonymous := false 582 if name == "" { 583 // anonymous field - typ must be T or *T and T must be a type name 584 switch typ := deref(typ).(type) { 585 case *types.Basic: // basic types are named types 586 pkg = nil // // objects defined in Universe scope have no package 587 name = typ.Name() 588 case *types.Named: 589 name = typ.Obj().Name() 590 default: 591 errorf("named base type expected") 592 } 593 anonymous = true 594 } else if alias { 595 // anonymous field: we have an explicit name because it's an alias 596 anonymous = true 597 } 598 599 return types.NewField(pos, pkg, name, typ, anonymous), tag 600 } 601 602 func (p *importer) methodList(parent *types.Package) (methods []*types.Func) { 603 if n := p.int(); n > 0 { 604 methods = make([]*types.Func, n) 605 for i := range methods { 606 methods[i] = p.method(parent) 607 } 608 } 609 return 610 } 611 612 func (p *importer) method(parent *types.Package) *types.Func { 613 pos := p.pos() 614 pkg, name, _ := p.fieldName(parent) 615 params, isddd := p.paramList() 616 result, _ := p.paramList() 617 sig := types.NewSignature(nil, params, result, isddd) 618 return types.NewFunc(pos, pkg, name, sig) 619 } 620 621 func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) { 622 name = p.string() 623 pkg = parent 624 if pkg == nil { 625 // use the imported package instead 626 pkg = p.pkgList[0] 627 } 628 if p.version == 0 && name == "_" { 629 // version 0 didn't export a package for _ fields 630 return 631 } 632 switch name { 633 case "": 634 // 1) field name matches base type name and is exported: nothing to do 635 case "?": 636 // 2) field name matches base type name and is not exported: need package 637 name = "" 638 pkg = p.pkg() 639 case "@": 640 // 3) field name doesn't match type name (alias) 641 name = p.string() 642 alias = true 643 fallthrough 644 default: 645 if !exported(name) { 646 pkg = p.pkg() 647 } 648 } 649 return 650 } 651 652 func (p *importer) paramList() (*types.Tuple, bool) { 653 n := p.int() 654 if n == 0 { 655 return nil, false 656 } 657 // negative length indicates unnamed parameters 658 named := true 659 if n < 0 { 660 n = -n 661 named = false 662 } 663 // n > 0 664 params := make([]*types.Var, n) 665 isddd := false 666 for i := range params { 667 params[i], isddd = p.param(named) 668 } 669 return types.NewTuple(params...), isddd 670 } 671 672 func (p *importer) param(named bool) (*types.Var, bool) { 673 t := p.typ(nil) 674 td, isddd := t.(*dddSlice) 675 if isddd { 676 t = types.NewSlice(td.elem) 677 } 678 679 var pkg *types.Package 680 var name string 681 if named { 682 name = p.string() 683 if name == "" { 684 errorf("expected named parameter") 685 } 686 if name != "_" { 687 pkg = p.pkg() 688 } 689 if i := strings.Index(name, "ยท"); i > 0 { 690 name = name[:i] // cut off gc-specific parameter numbering 691 } 692 } 693 694 // read and discard compiler-specific info 695 p.string() 696 697 return types.NewVar(token.NoPos, pkg, name, t), isddd 698 } 699 700 func exported(name string) bool { 701 ch, _ := utf8.DecodeRuneInString(name) 702 return unicode.IsUpper(ch) 703 } 704 705 func (p *importer) value() constant.Value { 706 switch tag := p.tagOrIndex(); tag { 707 case falseTag: 708 return constant.MakeBool(false) 709 case trueTag: 710 return constant.MakeBool(true) 711 case int64Tag: 712 return constant.MakeInt64(p.int64()) 713 case floatTag: 714 return p.float() 715 case complexTag: 716 re := p.float() 717 im := p.float() 718 return constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) 719 case stringTag: 720 return constant.MakeString(p.string()) 721 case unknownTag: 722 return constant.MakeUnknown() 723 default: 724 errorf("unexpected value tag %d", tag) // panics 725 panic("unreachable") 726 } 727 } 728 729 func (p *importer) float() constant.Value { 730 sign := p.int() 731 if sign == 0 { 732 return constant.MakeInt64(0) 733 } 734 735 exp := p.int() 736 mant := []byte(p.string()) // big endian 737 738 // remove leading 0's if any 739 for len(mant) > 0 && mant[0] == 0 { 740 mant = mant[1:] 741 } 742 743 // convert to little endian 744 // TODO(gri) go/constant should have a more direct conversion function 745 // (e.g., once it supports a big.Float based implementation) 746 for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 { 747 mant[i], mant[j] = mant[j], mant[i] 748 } 749 750 // adjust exponent (constant.MakeFromBytes creates an integer value, 751 // but mant represents the mantissa bits such that 0.5 <= mant < 1.0) 752 exp -= len(mant) << 3 753 if len(mant) > 0 { 754 for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 { 755 exp++ 756 } 757 } 758 759 x := constant.MakeFromBytes(mant) 760 switch { 761 case exp < 0: 762 d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) 763 x = constant.BinaryOp(x, token.QUO, d) 764 case exp > 0: 765 x = constant.Shift(x, token.SHL, uint(exp)) 766 } 767 768 if sign < 0 { 769 x = constant.UnaryOp(token.SUB, x, 0) 770 } 771 return x 772 } 773 774 // ---------------------------------------------------------------------------- 775 // Low-level decoders 776 777 func (p *importer) tagOrIndex() int { 778 if p.debugFormat { 779 p.marker('t') 780 } 781 782 return int(p.rawInt64()) 783 } 784 785 func (p *importer) int() int { 786 x := p.int64() 787 if int64(int(x)) != x { 788 errorf("exported integer too large") 789 } 790 return int(x) 791 } 792 793 func (p *importer) int64() int64 { 794 if p.debugFormat { 795 p.marker('i') 796 } 797 798 return p.rawInt64() 799 } 800 801 func (p *importer) path() string { 802 if p.debugFormat { 803 p.marker('p') 804 } 805 // if the path was seen before, i is its index (>= 0) 806 // (the empty string is at index 0) 807 i := p.rawInt64() 808 if i >= 0 { 809 return p.pathList[i] 810 } 811 // otherwise, i is the negative path length (< 0) 812 a := make([]string, -i) 813 for n := range a { 814 a[n] = p.string() 815 } 816 s := strings.Join(a, "/") 817 p.pathList = append(p.pathList, s) 818 return s 819 } 820 821 func (p *importer) string() string { 822 if p.debugFormat { 823 p.marker('s') 824 } 825 // if the string was seen before, i is its index (>= 0) 826 // (the empty string is at index 0) 827 i := p.rawInt64() 828 if i >= 0 { 829 return p.strList[i] 830 } 831 // otherwise, i is the negative string length (< 0) 832 if n := int(-i); n <= cap(p.buf) { 833 p.buf = p.buf[:n] 834 } else { 835 p.buf = make([]byte, n) 836 } 837 for i := range p.buf { 838 p.buf[i] = p.rawByte() 839 } 840 s := string(p.buf) 841 p.strList = append(p.strList, s) 842 return s 843 } 844 845 func (p *importer) marker(want byte) { 846 if got := p.rawByte(); got != want { 847 errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read) 848 } 849 850 pos := p.read 851 if n := int(p.rawInt64()); n != pos { 852 errorf("incorrect position: got %d; want %d", n, pos) 853 } 854 } 855 856 // rawInt64 should only be used by low-level decoders. 857 func (p *importer) rawInt64() int64 { 858 i, err := binary.ReadVarint(p) 859 if err != nil { 860 errorf("read error: %v", err) 861 } 862 return i 863 } 864 865 // rawStringln should only be used to read the initial version string. 866 func (p *importer) rawStringln(b byte) string { 867 p.buf = p.buf[:0] 868 for b != '\n' { 869 p.buf = append(p.buf, b) 870 b = p.rawByte() 871 } 872 return string(p.buf) 873 } 874 875 // needed for binary.ReadVarint in rawInt64 876 func (p *importer) ReadByte() (byte, error) { 877 return p.rawByte(), nil 878 } 879 880 // byte is the bottleneck interface for reading p.data. 881 // It unescapes '|' 'S' to '$' and '|' '|' to '|'. 882 // rawByte should only be used by low-level decoders. 883 func (p *importer) rawByte() byte { 884 b := p.data[0] 885 r := 1 886 if b == '|' { 887 b = p.data[1] 888 r = 2 889 switch b { 890 case 'S': 891 b = '$' 892 case '|': 893 // nothing to do 894 default: 895 errorf("unexpected escape sequence in export data") 896 } 897 } 898 p.data = p.data[r:] 899 p.read += r 900 return b 901 902 } 903 904 // ---------------------------------------------------------------------------- 905 // Export format 906 907 // Tags. Must be < 0. 908 const ( 909 // Objects 910 packageTag = -(iota + 1) 911 constTag 912 typeTag 913 varTag 914 funcTag 915 endTag 916 917 // Types 918 namedTag 919 arrayTag 920 sliceTag 921 dddTag 922 structTag 923 pointerTag 924 signatureTag 925 interfaceTag 926 mapTag 927 chanTag 928 929 // Values 930 falseTag 931 trueTag 932 int64Tag 933 floatTag 934 fractionTag // not used by gc 935 complexTag 936 stringTag 937 nilTag // only used by gc (appears in exported inlined function bodies) 938 unknownTag // not used by gc (only appears in packages with errors) 939 940 // Type aliases 941 aliasTag 942 ) 943 944 var predeclared = []types.Type{ 945 // basic types 946 types.Typ[types.Bool], 947 types.Typ[types.Int], 948 types.Typ[types.Int8], 949 types.Typ[types.Int16], 950 types.Typ[types.Int32], 951 types.Typ[types.Int64], 952 types.Typ[types.Uint], 953 types.Typ[types.Uint8], 954 types.Typ[types.Uint16], 955 types.Typ[types.Uint32], 956 types.Typ[types.Uint64], 957 types.Typ[types.Uintptr], 958 types.Typ[types.Float32], 959 types.Typ[types.Float64], 960 types.Typ[types.Complex64], 961 types.Typ[types.Complex128], 962 types.Typ[types.String], 963 964 // basic type aliases 965 types.Universe.Lookup("byte").Type(), 966 types.Universe.Lookup("rune").Type(), 967 968 // error 969 types.Universe.Lookup("error").Type(), 970 971 // untyped types 972 types.Typ[types.UntypedBool], 973 types.Typ[types.UntypedInt], 974 types.Typ[types.UntypedRune], 975 types.Typ[types.UntypedFloat], 976 types.Typ[types.UntypedComplex], 977 types.Typ[types.UntypedString], 978 types.Typ[types.UntypedNil], 979 980 // package unsafe 981 types.Typ[types.UnsafePointer], 982 983 // invalid type 984 types.Typ[types.Invalid], // only appears in packages with errors 985 986 // used internally by gc; never used by this package or in .a files 987 anyType{}, 988 } 989 990 type anyType struct{} 991 992 func (t anyType) Underlying() types.Type { return t } 993 func (t anyType) String() string { return "any" }