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