github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/go/gcimporter/gcimporter.go (about) 1 // Copyright 2011 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 // Package gcimporter implements Import for gc-generated object files. 6 // Importing this package installs Import as go/types.DefaultImport. 7 package gcimporter // import "golang.org/x/tools/go/gcimporter" 8 9 import ( 10 "bufio" 11 "errors" 12 "fmt" 13 "go/build" 14 "go/token" 15 "io" 16 "os" 17 "path/filepath" 18 "sort" 19 "strconv" 20 "strings" 21 "text/scanner" 22 23 "golang.org/x/tools/go/exact" 24 "golang.org/x/tools/go/types" 25 ) 26 27 // debugging/development support 28 const debug = false 29 30 func init() { 31 types.DefaultImport = Import 32 } 33 34 var pkgExts = [...]string{".a", ".5", ".6", ".7", ".8", ".9"} 35 36 // FindPkg returns the filename and unique package id for an import 37 // path based on package information provided by build.Import (using 38 // the build.Default build.Context). 39 // If no file was found, an empty filename is returned. 40 // 41 func FindPkg(path, srcDir string) (filename, id string) { 42 if len(path) == 0 { 43 return 44 } 45 46 id = path 47 var noext string 48 switch { 49 default: 50 // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" 51 // Don't require the source files to be present. 52 bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary) 53 if bp.PkgObj == "" { 54 return 55 } 56 noext = strings.TrimSuffix(bp.PkgObj, ".a") 57 58 case build.IsLocalImport(path): 59 // "./x" -> "/this/directory/x.ext", "/this/directory/x" 60 noext = filepath.Join(srcDir, path) 61 id = noext 62 63 case filepath.IsAbs(path): 64 // for completeness only - go/build.Import 65 // does not support absolute imports 66 // "/x" -> "/x.ext", "/x" 67 noext = path 68 } 69 70 // try extensions 71 for _, ext := range pkgExts { 72 filename = noext + ext 73 if f, err := os.Stat(filename); err == nil && !f.IsDir() { 74 return 75 } 76 } 77 78 filename = "" // not found 79 return 80 } 81 82 // ImportData imports a package by reading the gc-generated export data, 83 // adds the corresponding package object to the packages map indexed by id, 84 // and returns the object. 85 // 86 // The packages map must contains all packages already imported. The data 87 // reader position must be the beginning of the export data section. The 88 // filename is only used in error messages. 89 // 90 // If packages[id] contains the completely imported package, that package 91 // can be used directly, and there is no need to call this function (but 92 // there is also no harm but for extra time used). 93 // 94 func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) { 95 // support for parser error handling 96 defer func() { 97 switch r := recover().(type) { 98 case nil: 99 // nothing to do 100 case importError: 101 err = r 102 default: 103 panic(r) // internal error 104 } 105 }() 106 107 var p parser 108 p.init(filename, id, data, packages) 109 pkg = p.parseExport() 110 111 return 112 } 113 114 // Import imports a gc-generated package given its import path, adds the 115 // corresponding package object to the packages map, and returns the object. 116 // Local import paths are interpreted relative to the current working directory. 117 // The packages map must contains all packages already imported. 118 // 119 func Import(packages map[string]*types.Package, path string) (pkg *types.Package, err error) { 120 if path == "unsafe" { 121 return types.Unsafe, nil 122 } 123 124 srcDir := "." 125 if build.IsLocalImport(path) { 126 srcDir, err = os.Getwd() 127 if err != nil { 128 return 129 } 130 } 131 132 filename, id := FindPkg(path, srcDir) 133 if filename == "" { 134 err = fmt.Errorf("can't find import: %s", id) 135 return 136 } 137 138 // no need to re-import if the package was imported completely before 139 if pkg = packages[id]; pkg != nil && pkg.Complete() { 140 return 141 } 142 143 // open file 144 f, err := os.Open(filename) 145 if err != nil { 146 return 147 } 148 defer func() { 149 f.Close() 150 if err != nil { 151 // add file name to error 152 err = fmt.Errorf("reading export data: %s: %v", filename, err) 153 } 154 }() 155 156 buf := bufio.NewReader(f) 157 if err = FindExportData(buf); err != nil { 158 return 159 } 160 161 pkg, err = ImportData(packages, filename, id, buf) 162 163 return 164 } 165 166 // ---------------------------------------------------------------------------- 167 // Parser 168 169 // TODO(gri) Imported objects don't have position information. 170 // Ideally use the debug table line info; alternatively 171 // create some fake position (or the position of the 172 // import). That way error messages referring to imported 173 // objects can print meaningful information. 174 175 // parser parses the exports inside a gc compiler-produced 176 // object/archive file and populates its scope with the results. 177 type parser struct { 178 scanner scanner.Scanner 179 tok rune // current token 180 lit string // literal string; only valid for Ident, Int, String tokens 181 id string // package id of imported package 182 sharedPkgs map[string]*types.Package // package id -> package object (across importer) 183 localPkgs map[string]*types.Package // package id -> package object (just this package) 184 } 185 186 func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) { 187 p.scanner.Init(src) 188 p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) } 189 p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments 190 p.scanner.Whitespace = 1<<'\t' | 1<<' ' 191 p.scanner.Filename = filename // for good error messages 192 p.next() 193 p.id = id 194 p.sharedPkgs = packages 195 if debug { 196 // check consistency of packages map 197 for _, pkg := range packages { 198 if pkg.Name() == "" { 199 fmt.Printf("no package name for %s\n", pkg.Path()) 200 } 201 } 202 } 203 } 204 205 func (p *parser) next() { 206 p.tok = p.scanner.Scan() 207 switch p.tok { 208 case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·': 209 p.lit = p.scanner.TokenText() 210 default: 211 p.lit = "" 212 } 213 if debug { 214 fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit) 215 } 216 } 217 218 func declTypeName(pkg *types.Package, name string) *types.TypeName { 219 scope := pkg.Scope() 220 if obj := scope.Lookup(name); obj != nil { 221 return obj.(*types.TypeName) 222 } 223 obj := types.NewTypeName(token.NoPos, pkg, name, nil) 224 // a named type may be referred to before the underlying type 225 // is known - set it up 226 types.NewNamed(obj, nil, nil) 227 scope.Insert(obj) 228 return obj 229 } 230 231 // ---------------------------------------------------------------------------- 232 // Error handling 233 234 // Internal errors are boxed as importErrors. 235 type importError struct { 236 pos scanner.Position 237 err error 238 } 239 240 func (e importError) Error() string { 241 return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err) 242 } 243 244 func (p *parser) error(err interface{}) { 245 if s, ok := err.(string); ok { 246 err = errors.New(s) 247 } 248 // panic with a runtime.Error if err is not an error 249 panic(importError{p.scanner.Pos(), err.(error)}) 250 } 251 252 func (p *parser) errorf(format string, args ...interface{}) { 253 p.error(fmt.Sprintf(format, args...)) 254 } 255 256 func (p *parser) expect(tok rune) string { 257 lit := p.lit 258 if p.tok != tok { 259 p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit) 260 } 261 p.next() 262 return lit 263 } 264 265 func (p *parser) expectSpecial(tok string) { 266 sep := 'x' // not white space 267 i := 0 268 for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' { 269 sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token 270 p.next() 271 i++ 272 } 273 if i < len(tok) { 274 p.errorf("expected %q, got %q", tok, tok[0:i]) 275 } 276 } 277 278 func (p *parser) expectKeyword(keyword string) { 279 lit := p.expect(scanner.Ident) 280 if lit != keyword { 281 p.errorf("expected keyword %s, got %q", keyword, lit) 282 } 283 } 284 285 // ---------------------------------------------------------------------------- 286 // Qualified and unqualified names 287 288 // PackageId = string_lit . 289 // 290 func (p *parser) parsePackageId() string { 291 id, err := strconv.Unquote(p.expect(scanner.String)) 292 if err != nil { 293 p.error(err) 294 } 295 // id == "" stands for the imported package id 296 // (only known at time of package installation) 297 if id == "" { 298 id = p.id 299 } 300 return id 301 } 302 303 // PackageName = ident . 304 // 305 func (p *parser) parsePackageName() string { 306 return p.expect(scanner.Ident) 307 } 308 309 // dotIdentifier = ( ident | '·' ) { ident | int | '·' } . 310 func (p *parser) parseDotIdent() string { 311 ident := "" 312 if p.tok != scanner.Int { 313 sep := 'x' // not white space 314 for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' { 315 ident += p.lit 316 sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token 317 p.next() 318 } 319 } 320 if ident == "" { 321 p.expect(scanner.Ident) // use expect() for error handling 322 } 323 return ident 324 } 325 326 // QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) . 327 // 328 func (p *parser) parseQualifiedName() (id, name string) { 329 p.expect('@') 330 id = p.parsePackageId() 331 p.expect('.') 332 // Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields. 333 if p.tok == '?' { 334 p.next() 335 } else { 336 name = p.parseDotIdent() 337 } 338 return 339 } 340 341 // getPkg returns the package for a given id. If the package is 342 // not found but we have a package name, create the package and 343 // add it to the p.localPkgs and p.sharedPkgs maps. 344 // 345 // id identifies a package, usually by a canonical package path like 346 // "encoding/json" but possibly by a non-canonical import path like 347 // "./json". 348 // 349 func (p *parser) getPkg(id, name string) *types.Package { 350 // package unsafe is not in the packages maps - handle explicitly 351 if id == "unsafe" { 352 return types.Unsafe 353 } 354 355 pkg := p.localPkgs[id] 356 if pkg == nil && name != "" { 357 // first import of id from this package 358 pkg = p.sharedPkgs[id] 359 if pkg == nil { 360 // first import of id by this importer 361 pkg = types.NewPackage(id, name) 362 p.sharedPkgs[id] = pkg 363 } 364 365 if p.localPkgs == nil { 366 p.localPkgs = make(map[string]*types.Package) 367 } 368 p.localPkgs[id] = pkg 369 } 370 return pkg 371 } 372 373 // parseExportedName is like parseQualifiedName, but 374 // the package id is resolved to an imported *types.Package. 375 // 376 func (p *parser) parseExportedName() (pkg *types.Package, name string) { 377 id, name := p.parseQualifiedName() 378 pkg = p.getPkg(id, "") 379 if pkg == nil { 380 p.errorf("%s package not found", id) 381 } 382 return 383 } 384 385 // ---------------------------------------------------------------------------- 386 // Types 387 388 // BasicType = identifier . 389 // 390 func (p *parser) parseBasicType() types.Type { 391 id := p.expect(scanner.Ident) 392 obj := types.Universe.Lookup(id) 393 if obj, ok := obj.(*types.TypeName); ok { 394 return obj.Type() 395 } 396 p.errorf("not a basic type: %s", id) 397 return nil 398 } 399 400 // ArrayType = "[" int_lit "]" Type . 401 // 402 func (p *parser) parseArrayType() types.Type { 403 // "[" already consumed and lookahead known not to be "]" 404 lit := p.expect(scanner.Int) 405 p.expect(']') 406 elem := p.parseType() 407 n, err := strconv.ParseInt(lit, 10, 64) 408 if err != nil { 409 p.error(err) 410 } 411 return types.NewArray(elem, n) 412 } 413 414 // MapType = "map" "[" Type "]" Type . 415 // 416 func (p *parser) parseMapType() types.Type { 417 p.expectKeyword("map") 418 p.expect('[') 419 key := p.parseType() 420 p.expect(']') 421 elem := p.parseType() 422 return types.NewMap(key, elem) 423 } 424 425 // Name = identifier | "?" | QualifiedName . 426 // 427 // If materializePkg is set, the returned package is guaranteed to be set. 428 // For fully qualified names, the returned package may be a fake package 429 // (without name, scope, and not in the p.imports map), created for the 430 // sole purpose of providing a package path. Fake packages are created 431 // when the package id is not found in the p.imports map; in that case 432 // we cannot create a real package because we don't have a package name. 433 // For non-qualified names, the returned package is the imported package. 434 // 435 func (p *parser) parseName(materializePkg bool) (pkg *types.Package, name string) { 436 switch p.tok { 437 case scanner.Ident: 438 pkg = p.sharedPkgs[p.id] 439 name = p.lit 440 p.next() 441 case '?': 442 // anonymous 443 pkg = p.sharedPkgs[p.id] 444 p.next() 445 case '@': 446 // exported name prefixed with package path 447 var id string 448 id, name = p.parseQualifiedName() 449 if materializePkg { 450 // we don't have a package name - if the package 451 // doesn't exist yet, create a fake package instead 452 pkg = p.getPkg(id, "") 453 if pkg == nil { 454 pkg = types.NewPackage(id, "") 455 } 456 } 457 default: 458 p.error("name expected") 459 } 460 return 461 } 462 463 func deref(typ types.Type) types.Type { 464 if p, _ := typ.(*types.Pointer); p != nil { 465 return p.Elem() 466 } 467 return typ 468 } 469 470 // Field = Name Type [ string_lit ] . 471 // 472 func (p *parser) parseField() (*types.Var, string) { 473 pkg, name := p.parseName(true) 474 typ := p.parseType() 475 anonymous := false 476 if name == "" { 477 // anonymous field - typ must be T or *T and T must be a type name 478 switch typ := deref(typ).(type) { 479 case *types.Basic: // basic types are named types 480 pkg = nil 481 name = typ.Name() 482 case *types.Named: 483 name = typ.Obj().Name() 484 default: 485 p.errorf("anonymous field expected") 486 } 487 anonymous = true 488 } 489 tag := "" 490 if p.tok == scanner.String { 491 s := p.expect(scanner.String) 492 var err error 493 tag, err = strconv.Unquote(s) 494 if err != nil { 495 p.errorf("invalid struct tag %s: %s", s, err) 496 } 497 } 498 return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag 499 } 500 501 // StructType = "struct" "{" [ FieldList ] "}" . 502 // FieldList = Field { ";" Field } . 503 // 504 func (p *parser) parseStructType() types.Type { 505 var fields []*types.Var 506 var tags []string 507 508 p.expectKeyword("struct") 509 p.expect('{') 510 for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ { 511 if i > 0 { 512 p.expect(';') 513 } 514 fld, tag := p.parseField() 515 if tag != "" && tags == nil { 516 tags = make([]string, i) 517 } 518 if tags != nil { 519 tags = append(tags, tag) 520 } 521 fields = append(fields, fld) 522 } 523 p.expect('}') 524 525 return types.NewStruct(fields, tags) 526 } 527 528 // Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] . 529 // 530 func (p *parser) parseParameter() (par *types.Var, isVariadic bool) { 531 _, name := p.parseName(false) 532 // remove gc-specific parameter numbering 533 if i := strings.Index(name, "·"); i >= 0 { 534 name = name[:i] 535 } 536 if p.tok == '.' { 537 p.expectSpecial("...") 538 isVariadic = true 539 } 540 typ := p.parseType() 541 if isVariadic { 542 typ = types.NewSlice(typ) 543 } 544 // ignore argument tag (e.g. "noescape") 545 if p.tok == scanner.String { 546 p.next() 547 } 548 // TODO(gri) should we provide a package? 549 par = types.NewVar(token.NoPos, nil, name, typ) 550 return 551 } 552 553 // Parameters = "(" [ ParameterList ] ")" . 554 // ParameterList = { Parameter "," } Parameter . 555 // 556 func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) { 557 p.expect('(') 558 for p.tok != ')' && p.tok != scanner.EOF { 559 if len(list) > 0 { 560 p.expect(',') 561 } 562 par, variadic := p.parseParameter() 563 list = append(list, par) 564 if variadic { 565 if isVariadic { 566 p.error("... not on final argument") 567 } 568 isVariadic = true 569 } 570 } 571 p.expect(')') 572 573 return 574 } 575 576 // Signature = Parameters [ Result ] . 577 // Result = Type | Parameters . 578 // 579 func (p *parser) parseSignature(recv *types.Var) *types.Signature { 580 params, isVariadic := p.parseParameters() 581 582 // optional result type 583 var results []*types.Var 584 if p.tok == '(' { 585 var variadic bool 586 results, variadic = p.parseParameters() 587 if variadic { 588 p.error("... not permitted on result type") 589 } 590 } 591 592 return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic) 593 } 594 595 // InterfaceType = "interface" "{" [ MethodList ] "}" . 596 // MethodList = Method { ";" Method } . 597 // Method = Name Signature . 598 // 599 // The methods of embedded interfaces are always "inlined" 600 // by the compiler and thus embedded interfaces are never 601 // visible in the export data. 602 // 603 func (p *parser) parseInterfaceType() types.Type { 604 var methods []*types.Func 605 606 p.expectKeyword("interface") 607 p.expect('{') 608 for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ { 609 if i > 0 { 610 p.expect(';') 611 } 612 pkg, name := p.parseName(true) 613 sig := p.parseSignature(nil) 614 methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig)) 615 } 616 p.expect('}') 617 618 // Complete requires the type's embedded interfaces to be fully defined, 619 // but we do not define any 620 return types.NewInterface(methods, nil).Complete() 621 } 622 623 // ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type . 624 // 625 func (p *parser) parseChanType() types.Type { 626 dir := types.SendRecv 627 if p.tok == scanner.Ident { 628 p.expectKeyword("chan") 629 if p.tok == '<' { 630 p.expectSpecial("<-") 631 dir = types.SendOnly 632 } 633 } else { 634 p.expectSpecial("<-") 635 p.expectKeyword("chan") 636 dir = types.RecvOnly 637 } 638 elem := p.parseType() 639 return types.NewChan(dir, elem) 640 } 641 642 // Type = 643 // BasicType | TypeName | ArrayType | SliceType | StructType | 644 // PointerType | FuncType | InterfaceType | MapType | ChanType | 645 // "(" Type ")" . 646 // 647 // BasicType = ident . 648 // TypeName = ExportedName . 649 // SliceType = "[" "]" Type . 650 // PointerType = "*" Type . 651 // FuncType = "func" Signature . 652 // 653 func (p *parser) parseType() types.Type { 654 switch p.tok { 655 case scanner.Ident: 656 switch p.lit { 657 default: 658 return p.parseBasicType() 659 case "struct": 660 return p.parseStructType() 661 case "func": 662 // FuncType 663 p.next() 664 return p.parseSignature(nil) 665 case "interface": 666 return p.parseInterfaceType() 667 case "map": 668 return p.parseMapType() 669 case "chan": 670 return p.parseChanType() 671 } 672 case '@': 673 // TypeName 674 pkg, name := p.parseExportedName() 675 return declTypeName(pkg, name).Type() 676 case '[': 677 p.next() // look ahead 678 if p.tok == ']' { 679 // SliceType 680 p.next() 681 return types.NewSlice(p.parseType()) 682 } 683 return p.parseArrayType() 684 case '*': 685 // PointerType 686 p.next() 687 return types.NewPointer(p.parseType()) 688 case '<': 689 return p.parseChanType() 690 case '(': 691 // "(" Type ")" 692 p.next() 693 typ := p.parseType() 694 p.expect(')') 695 return typ 696 } 697 p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit) 698 return nil 699 } 700 701 // ---------------------------------------------------------------------------- 702 // Declarations 703 704 // ImportDecl = "import" PackageName PackageId . 705 // 706 func (p *parser) parseImportDecl() { 707 p.expectKeyword("import") 708 name := p.parsePackageName() 709 p.getPkg(p.parsePackageId(), name) 710 } 711 712 // int_lit = [ "+" | "-" ] { "0" ... "9" } . 713 // 714 func (p *parser) parseInt() string { 715 s := "" 716 switch p.tok { 717 case '-': 718 s = "-" 719 p.next() 720 case '+': 721 p.next() 722 } 723 return s + p.expect(scanner.Int) 724 } 725 726 // number = int_lit [ "p" int_lit ] . 727 // 728 func (p *parser) parseNumber() (typ *types.Basic, val exact.Value) { 729 // mantissa 730 mant := exact.MakeFromLiteral(p.parseInt(), token.INT) 731 if mant == nil { 732 panic("invalid mantissa") 733 } 734 735 if p.lit == "p" { 736 // exponent (base 2) 737 p.next() 738 exp, err := strconv.ParseInt(p.parseInt(), 10, 0) 739 if err != nil { 740 p.error(err) 741 } 742 if exp < 0 { 743 denom := exact.MakeInt64(1) 744 denom = exact.Shift(denom, token.SHL, uint(-exp)) 745 typ = types.Typ[types.UntypedFloat] 746 val = exact.BinaryOp(mant, token.QUO, denom) 747 return 748 } 749 if exp > 0 { 750 mant = exact.Shift(mant, token.SHL, uint(exp)) 751 } 752 typ = types.Typ[types.UntypedFloat] 753 val = mant 754 return 755 } 756 757 typ = types.Typ[types.UntypedInt] 758 val = mant 759 return 760 } 761 762 // ConstDecl = "const" ExportedName [ Type ] "=" Literal . 763 // Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit . 764 // bool_lit = "true" | "false" . 765 // complex_lit = "(" float_lit "+" float_lit "i" ")" . 766 // rune_lit = "(" int_lit "+" int_lit ")" . 767 // string_lit = `"` { unicode_char } `"` . 768 // 769 func (p *parser) parseConstDecl() { 770 p.expectKeyword("const") 771 pkg, name := p.parseExportedName() 772 773 var typ0 types.Type 774 if p.tok != '=' { 775 typ0 = p.parseType() 776 } 777 778 p.expect('=') 779 var typ types.Type 780 var val exact.Value 781 switch p.tok { 782 case scanner.Ident: 783 // bool_lit 784 if p.lit != "true" && p.lit != "false" { 785 p.error("expected true or false") 786 } 787 typ = types.Typ[types.UntypedBool] 788 val = exact.MakeBool(p.lit == "true") 789 p.next() 790 791 case '-', scanner.Int: 792 // int_lit 793 typ, val = p.parseNumber() 794 795 case '(': 796 // complex_lit or rune_lit 797 p.next() 798 if p.tok == scanner.Char { 799 p.next() 800 p.expect('+') 801 typ = types.Typ[types.UntypedRune] 802 _, val = p.parseNumber() 803 p.expect(')') 804 break 805 } 806 _, re := p.parseNumber() 807 p.expect('+') 808 _, im := p.parseNumber() 809 p.expectKeyword("i") 810 p.expect(')') 811 typ = types.Typ[types.UntypedComplex] 812 val = exact.BinaryOp(re, token.ADD, exact.MakeImag(im)) 813 814 case scanner.Char: 815 // rune_lit 816 typ = types.Typ[types.UntypedRune] 817 val = exact.MakeFromLiteral(p.lit, token.CHAR) 818 p.next() 819 820 case scanner.String: 821 // string_lit 822 typ = types.Typ[types.UntypedString] 823 val = exact.MakeFromLiteral(p.lit, token.STRING) 824 p.next() 825 826 default: 827 p.errorf("expected literal got %s", scanner.TokenString(p.tok)) 828 } 829 830 if typ0 == nil { 831 typ0 = typ 832 } 833 834 pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val)) 835 } 836 837 // TypeDecl = "type" ExportedName Type . 838 // 839 func (p *parser) parseTypeDecl() { 840 p.expectKeyword("type") 841 pkg, name := p.parseExportedName() 842 obj := declTypeName(pkg, name) 843 844 // The type object may have been imported before and thus already 845 // have a type associated with it. We still need to parse the type 846 // structure, but throw it away if the object already has a type. 847 // This ensures that all imports refer to the same type object for 848 // a given type declaration. 849 typ := p.parseType() 850 851 if name := obj.Type().(*types.Named); name.Underlying() == nil { 852 name.SetUnderlying(typ) 853 } 854 } 855 856 // VarDecl = "var" ExportedName Type . 857 // 858 func (p *parser) parseVarDecl() { 859 p.expectKeyword("var") 860 pkg, name := p.parseExportedName() 861 typ := p.parseType() 862 pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ)) 863 } 864 865 // Func = Signature [ Body ] . 866 // Body = "{" ... "}" . 867 // 868 func (p *parser) parseFunc(recv *types.Var) *types.Signature { 869 sig := p.parseSignature(recv) 870 if p.tok == '{' { 871 p.next() 872 for i := 1; i > 0; p.next() { 873 switch p.tok { 874 case '{': 875 i++ 876 case '}': 877 i-- 878 } 879 } 880 } 881 return sig 882 } 883 884 // MethodDecl = "func" Receiver Name Func . 885 // Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" . 886 // 887 func (p *parser) parseMethodDecl() { 888 // "func" already consumed 889 p.expect('(') 890 recv, _ := p.parseParameter() // receiver 891 p.expect(')') 892 893 // determine receiver base type object 894 base := deref(recv.Type()).(*types.Named) 895 896 // parse method name, signature, and possibly inlined body 897 _, name := p.parseName(true) 898 sig := p.parseFunc(recv) 899 900 // methods always belong to the same package as the base type object 901 pkg := base.Obj().Pkg() 902 903 // add method to type unless type was imported before 904 // and method exists already 905 // TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small. 906 base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) 907 } 908 909 // FuncDecl = "func" ExportedName Func . 910 // 911 func (p *parser) parseFuncDecl() { 912 // "func" already consumed 913 pkg, name := p.parseExportedName() 914 typ := p.parseFunc(nil) 915 pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ)) 916 } 917 918 // Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" . 919 // 920 func (p *parser) parseDecl() { 921 if p.tok == scanner.Ident { 922 switch p.lit { 923 case "import": 924 p.parseImportDecl() 925 case "const": 926 p.parseConstDecl() 927 case "type": 928 p.parseTypeDecl() 929 case "var": 930 p.parseVarDecl() 931 case "func": 932 p.next() // look ahead 933 if p.tok == '(' { 934 p.parseMethodDecl() 935 } else { 936 p.parseFuncDecl() 937 } 938 } 939 } 940 p.expect('\n') 941 } 942 943 // ---------------------------------------------------------------------------- 944 // Export 945 946 // Export = "PackageClause { Decl } "$$" . 947 // PackageClause = "package" PackageName [ "safe" ] "\n" . 948 // 949 func (p *parser) parseExport() *types.Package { 950 p.expectKeyword("package") 951 name := p.parsePackageName() 952 if p.tok == scanner.Ident && p.lit == "safe" { 953 // package was compiled with -u option - ignore 954 p.next() 955 } 956 p.expect('\n') 957 958 pkg := p.getPkg(p.id, name) 959 960 for p.tok != '$' && p.tok != scanner.EOF { 961 p.parseDecl() 962 } 963 964 if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' { 965 // don't call next()/expect() since reading past the 966 // export data may cause scanner errors (e.g. NUL chars) 967 p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch) 968 } 969 970 if n := p.scanner.ErrorCount; n != 0 { 971 p.errorf("expected no scanner errors, got %d", n) 972 } 973 974 // Record all referenced packages as imports. 975 var imports []*types.Package 976 for id, pkg2 := range p.localPkgs { 977 if id == p.id { 978 continue // avoid self-edge 979 } 980 imports = append(imports, pkg2) 981 } 982 sort.Sort(byPath(imports)) 983 pkg.SetImports(imports) 984 985 // package was imported completely and without errors 986 pkg.MarkComplete() 987 988 return pkg 989 } 990 991 type byPath []*types.Package 992 993 func (a byPath) Len() int { return len(a) } 994 func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 995 func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }