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