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