github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/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). A relative srcDir is interpreted 35 // relative to the current working directory. 36 // If no file was found, an empty filename is returned. 37 // 38 func FindPkg(path, srcDir string) (filename, id string) { 39 if path == "" { 40 return 41 } 42 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 if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 49 srcDir = abs 50 } 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 id = bp.ImportPath 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 id = path 69 } 70 71 if false { // for debugging 72 if path != id { 73 fmt.Printf("%s -> %s\n", path, id) 74 } 75 } 76 77 // try extensions 78 for _, ext := range pkgExts { 79 filename = noext + ext 80 if f, err := os.Stat(filename); err == nil && !f.IsDir() { 81 return 82 } 83 } 84 85 filename = "" // not found 86 return 87 } 88 89 // ImportData imports a package by reading the gc-generated export data, 90 // adds the corresponding package object to the packages map indexed by id, 91 // and returns the object. 92 // 93 // The packages map must contains all packages already imported. The data 94 // reader position must be the beginning of the export data section. The 95 // filename is only used in error messages. 96 // 97 // If packages[id] contains the completely imported package, that package 98 // can be used directly, and there is no need to call this function (but 99 // there is also no harm but for extra time used). 100 // 101 func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) { 102 // support for parser error handling 103 defer func() { 104 switch r := recover().(type) { 105 case nil: 106 // nothing to do 107 case importError: 108 err = r 109 default: 110 panic(r) // internal error 111 } 112 }() 113 114 var p parser 115 p.init(filename, id, data, packages) 116 pkg = p.parseExport() 117 118 return 119 } 120 121 // Import imports a gc-generated package given its import path and srcDir, adds 122 // the corresponding package object to the packages map, and returns the object. 123 // The packages map must contain all packages already imported. 124 // 125 func Import(packages map[string]*types.Package, path, srcDir string) (pkg *types.Package, err error) { 126 filename, id := FindPkg(path, srcDir) 127 if filename == "" { 128 if path == "unsafe" { 129 return types.Unsafe, nil 130 } 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, id) 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, create the package and add it to the p.localPkgs 353 // and p.sharedPkgs maps. name is the (expected) name of the 354 // package. If name == "", the package name is expected to be 355 // set later via an import clause in the export data. 356 // 357 // id identifies a package, usually by a canonical package path like 358 // "encoding/json" but possibly by a non-canonical import path like 359 // "./json". 360 // 361 func (p *parser) getPkg(id, name string) *types.Package { 362 // package unsafe is not in the packages maps - handle explicitly 363 if id == "unsafe" { 364 return types.Unsafe 365 } 366 367 pkg := p.localPkgs[id] 368 if pkg == nil { 369 // first import of id from this package 370 pkg = p.sharedPkgs[id] 371 if pkg == nil { 372 // first import of id by this importer; 373 // add (possibly unnamed) pkg to shared packages 374 pkg = types.NewPackage(id, name) 375 p.sharedPkgs[id] = pkg 376 } 377 // add (possibly unnamed) pkg to local packages 378 if p.localPkgs == nil { 379 p.localPkgs = make(map[string]*types.Package) 380 } 381 p.localPkgs[id] = pkg 382 } else if name != "" { 383 // package exists already and we have an expected package name; 384 // make sure names match or set package name if necessary 385 if pname := pkg.Name(); pname == "" { 386 pkg.SetName(name) 387 } else if pname != name { 388 p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name) 389 } 390 } 391 return pkg 392 } 393 394 // parseExportedName is like parseQualifiedName, but 395 // the package id is resolved to an imported *types.Package. 396 // 397 func (p *parser) parseExportedName() (pkg *types.Package, name string) { 398 id, name := p.parseQualifiedName() 399 pkg = p.getPkg(id, "") 400 return 401 } 402 403 // ---------------------------------------------------------------------------- 404 // Types 405 406 // BasicType = identifier . 407 // 408 func (p *parser) parseBasicType() types.Type { 409 id := p.expect(scanner.Ident) 410 obj := types.Universe.Lookup(id) 411 if obj, ok := obj.(*types.TypeName); ok { 412 return obj.Type() 413 } 414 p.errorf("not a basic type: %s", id) 415 return nil 416 } 417 418 // ArrayType = "[" int_lit "]" Type . 419 // 420 func (p *parser) parseArrayType(parent *types.Package) types.Type { 421 // "[" already consumed and lookahead known not to be "]" 422 lit := p.expect(scanner.Int) 423 p.expect(']') 424 elem := p.parseType(parent) 425 n, err := strconv.ParseInt(lit, 10, 64) 426 if err != nil { 427 p.error(err) 428 } 429 return types.NewArray(elem, n) 430 } 431 432 // MapType = "map" "[" Type "]" Type . 433 // 434 func (p *parser) parseMapType(parent *types.Package) types.Type { 435 p.expectKeyword("map") 436 p.expect('[') 437 key := p.parseType(parent) 438 p.expect(']') 439 elem := p.parseType(parent) 440 return types.NewMap(key, elem) 441 } 442 443 // Name = identifier | "?" | QualifiedName . 444 // 445 // For unqualified and anonymous names, the returned package is the parent 446 // package unless parent == nil, in which case the returned package is the 447 // package being imported. (The parent package is not nil if the the name 448 // is an unqualified struct field or interface method name belonging to a 449 // type declared in another package.) 450 // 451 // For qualified names, the returned package is nil (and not created if 452 // it doesn't exist yet) unless materializePkg is set (which creates an 453 // unnamed package with valid package path). In the latter case, a 454 // subsequent import clause is expected to provide a name for the package. 455 // 456 func (p *parser) parseName(parent *types.Package, materializePkg bool) (pkg *types.Package, name string) { 457 pkg = parent 458 if pkg == nil { 459 pkg = p.sharedPkgs[p.id] 460 } 461 switch p.tok { 462 case scanner.Ident: 463 name = p.lit 464 p.next() 465 case '?': 466 // anonymous 467 p.next() 468 case '@': 469 // exported name prefixed with package path 470 pkg = nil 471 var id string 472 id, name = p.parseQualifiedName() 473 if materializePkg { 474 pkg = p.getPkg(id, "") 475 } 476 default: 477 p.error("name expected") 478 } 479 return 480 } 481 482 func deref(typ types.Type) types.Type { 483 if p, _ := typ.(*types.Pointer); p != nil { 484 return p.Elem() 485 } 486 return typ 487 } 488 489 // Field = Name Type [ string_lit ] . 490 // 491 func (p *parser) parseField(parent *types.Package) (*types.Var, string) { 492 pkg, name := p.parseName(parent, true) 493 typ := p.parseType(parent) 494 anonymous := false 495 if name == "" { 496 // anonymous field - typ must be T or *T and T must be a type name 497 switch typ := deref(typ).(type) { 498 case *types.Basic: // basic types are named types 499 pkg = nil // objects defined in Universe scope have no package 500 name = typ.Name() 501 case *types.Named: 502 name = typ.Obj().Name() 503 default: 504 p.errorf("anonymous field expected") 505 } 506 anonymous = true 507 } 508 tag := "" 509 if p.tok == scanner.String { 510 s := p.expect(scanner.String) 511 var err error 512 tag, err = strconv.Unquote(s) 513 if err != nil { 514 p.errorf("invalid struct tag %s: %s", s, err) 515 } 516 } 517 return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag 518 } 519 520 // StructType = "struct" "{" [ FieldList ] "}" . 521 // FieldList = Field { ";" Field } . 522 // 523 func (p *parser) parseStructType(parent *types.Package) types.Type { 524 var fields []*types.Var 525 var tags []string 526 527 p.expectKeyword("struct") 528 p.expect('{') 529 for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ { 530 if i > 0 { 531 p.expect(';') 532 } 533 fld, tag := p.parseField(parent) 534 if tag != "" && tags == nil { 535 tags = make([]string, i) 536 } 537 if tags != nil { 538 tags = append(tags, tag) 539 } 540 fields = append(fields, fld) 541 } 542 p.expect('}') 543 544 return types.NewStruct(fields, tags) 545 } 546 547 // Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] . 548 // 549 func (p *parser) parseParameter() (par *types.Var, isVariadic bool) { 550 _, name := p.parseName(nil, false) 551 // remove gc-specific parameter numbering 552 if i := strings.Index(name, "·"); i >= 0 { 553 name = name[:i] 554 } 555 if p.tok == '.' { 556 p.expectSpecial("...") 557 isVariadic = true 558 } 559 typ := p.parseType(nil) 560 if isVariadic { 561 typ = types.NewSlice(typ) 562 } 563 // ignore argument tag (e.g. "noescape") 564 if p.tok == scanner.String { 565 p.next() 566 } 567 // TODO(gri) should we provide a package? 568 par = types.NewVar(token.NoPos, nil, name, typ) 569 return 570 } 571 572 // Parameters = "(" [ ParameterList ] ")" . 573 // ParameterList = { Parameter "," } Parameter . 574 // 575 func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) { 576 p.expect('(') 577 for p.tok != ')' && p.tok != scanner.EOF { 578 if len(list) > 0 { 579 p.expect(',') 580 } 581 par, variadic := p.parseParameter() 582 list = append(list, par) 583 if variadic { 584 if isVariadic { 585 p.error("... not on final argument") 586 } 587 isVariadic = true 588 } 589 } 590 p.expect(')') 591 592 return 593 } 594 595 // Signature = Parameters [ Result ] . 596 // Result = Type | Parameters . 597 // 598 func (p *parser) parseSignature(recv *types.Var) *types.Signature { 599 params, isVariadic := p.parseParameters() 600 601 // optional result type 602 var results []*types.Var 603 if p.tok == '(' { 604 var variadic bool 605 results, variadic = p.parseParameters() 606 if variadic { 607 p.error("... not permitted on result type") 608 } 609 } 610 611 return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic) 612 } 613 614 // InterfaceType = "interface" "{" [ MethodList ] "}" . 615 // MethodList = Method { ";" Method } . 616 // Method = Name Signature . 617 // 618 // The methods of embedded interfaces are always "inlined" 619 // by the compiler and thus embedded interfaces are never 620 // visible in the export data. 621 // 622 func (p *parser) parseInterfaceType(parent *types.Package) types.Type { 623 var methods []*types.Func 624 625 p.expectKeyword("interface") 626 p.expect('{') 627 for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ { 628 if i > 0 { 629 p.expect(';') 630 } 631 pkg, name := p.parseName(parent, true) 632 sig := p.parseSignature(nil) 633 methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig)) 634 } 635 p.expect('}') 636 637 // Complete requires the type's embedded interfaces to be fully defined, 638 // but we do not define any 639 return types.NewInterface(methods, nil).Complete() 640 } 641 642 // ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type . 643 // 644 func (p *parser) parseChanType(parent *types.Package) types.Type { 645 dir := types.SendRecv 646 if p.tok == scanner.Ident { 647 p.expectKeyword("chan") 648 if p.tok == '<' { 649 p.expectSpecial("<-") 650 dir = types.SendOnly 651 } 652 } else { 653 p.expectSpecial("<-") 654 p.expectKeyword("chan") 655 dir = types.RecvOnly 656 } 657 elem := p.parseType(parent) 658 return types.NewChan(dir, elem) 659 } 660 661 // Type = 662 // BasicType | TypeName | ArrayType | SliceType | StructType | 663 // PointerType | FuncType | InterfaceType | MapType | ChanType | 664 // "(" Type ")" . 665 // 666 // BasicType = ident . 667 // TypeName = ExportedName . 668 // SliceType = "[" "]" Type . 669 // PointerType = "*" Type . 670 // FuncType = "func" Signature . 671 // 672 func (p *parser) parseType(parent *types.Package) types.Type { 673 switch p.tok { 674 case scanner.Ident: 675 switch p.lit { 676 default: 677 return p.parseBasicType() 678 case "struct": 679 return p.parseStructType(parent) 680 case "func": 681 // FuncType 682 p.next() 683 return p.parseSignature(nil) 684 case "interface": 685 return p.parseInterfaceType(parent) 686 case "map": 687 return p.parseMapType(parent) 688 case "chan": 689 return p.parseChanType(parent) 690 } 691 case '@': 692 // TypeName 693 pkg, name := p.parseExportedName() 694 return declTypeName(pkg, name).Type() 695 case '[': 696 p.next() // look ahead 697 if p.tok == ']' { 698 // SliceType 699 p.next() 700 return types.NewSlice(p.parseType(parent)) 701 } 702 return p.parseArrayType(parent) 703 case '*': 704 // PointerType 705 p.next() 706 return types.NewPointer(p.parseType(parent)) 707 case '<': 708 return p.parseChanType(parent) 709 case '(': 710 // "(" Type ")" 711 p.next() 712 typ := p.parseType(parent) 713 p.expect(')') 714 return typ 715 } 716 p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit) 717 return nil 718 } 719 720 // ---------------------------------------------------------------------------- 721 // Declarations 722 723 // ImportDecl = "import" PackageName PackageId . 724 // 725 func (p *parser) parseImportDecl() { 726 p.expectKeyword("import") 727 name := p.parsePackageName() 728 p.getPkg(p.parsePackageId(), name) 729 } 730 731 // int_lit = [ "+" | "-" ] { "0" ... "9" } . 732 // 733 func (p *parser) parseInt() string { 734 s := "" 735 switch p.tok { 736 case '-': 737 s = "-" 738 p.next() 739 case '+': 740 p.next() 741 } 742 return s + p.expect(scanner.Int) 743 } 744 745 // number = int_lit [ "p" int_lit ] . 746 // 747 func (p *parser) parseNumber() (typ *types.Basic, val exact.Value) { 748 // mantissa 749 mant := exact.MakeFromLiteral(p.parseInt(), token.INT, 0) 750 if mant == nil { 751 panic("invalid mantissa") 752 } 753 754 if p.lit == "p" { 755 // exponent (base 2) 756 p.next() 757 exp, err := strconv.ParseInt(p.parseInt(), 10, 0) 758 if err != nil { 759 p.error(err) 760 } 761 if exp < 0 { 762 denom := exact.MakeInt64(1) 763 denom = exact.Shift(denom, token.SHL, uint(-exp)) 764 typ = types.Typ[types.UntypedFloat] 765 val = exact.BinaryOp(mant, token.QUO, denom) 766 return 767 } 768 if exp > 0 { 769 mant = exact.Shift(mant, token.SHL, uint(exp)) 770 } 771 typ = types.Typ[types.UntypedFloat] 772 val = mant 773 return 774 } 775 776 typ = types.Typ[types.UntypedInt] 777 val = mant 778 return 779 } 780 781 // ConstDecl = "const" ExportedName [ Type ] "=" Literal . 782 // Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit . 783 // bool_lit = "true" | "false" . 784 // complex_lit = "(" float_lit "+" float_lit "i" ")" . 785 // rune_lit = "(" int_lit "+" int_lit ")" . 786 // string_lit = `"` { unicode_char } `"` . 787 // 788 func (p *parser) parseConstDecl() { 789 p.expectKeyword("const") 790 pkg, name := p.parseExportedName() 791 792 var typ0 types.Type 793 if p.tok != '=' { 794 // constant types are never structured - no need for parent type 795 typ0 = p.parseType(nil) 796 } 797 798 p.expect('=') 799 var typ types.Type 800 var val exact.Value 801 switch p.tok { 802 case scanner.Ident: 803 // bool_lit 804 if p.lit != "true" && p.lit != "false" { 805 p.error("expected true or false") 806 } 807 typ = types.Typ[types.UntypedBool] 808 val = exact.MakeBool(p.lit == "true") 809 p.next() 810 811 case '-', scanner.Int: 812 // int_lit 813 typ, val = p.parseNumber() 814 815 case '(': 816 // complex_lit or rune_lit 817 p.next() 818 if p.tok == scanner.Char { 819 p.next() 820 p.expect('+') 821 typ = types.Typ[types.UntypedRune] 822 _, val = p.parseNumber() 823 p.expect(')') 824 break 825 } 826 _, re := p.parseNumber() 827 p.expect('+') 828 _, im := p.parseNumber() 829 p.expectKeyword("i") 830 p.expect(')') 831 typ = types.Typ[types.UntypedComplex] 832 val = exact.BinaryOp(re, token.ADD, exact.MakeImag(im)) 833 834 case scanner.Char: 835 // rune_lit 836 typ = types.Typ[types.UntypedRune] 837 val = exact.MakeFromLiteral(p.lit, token.CHAR, 0) 838 p.next() 839 840 case scanner.String: 841 // string_lit 842 typ = types.Typ[types.UntypedString] 843 val = exact.MakeFromLiteral(p.lit, token.STRING, 0) 844 p.next() 845 846 default: 847 p.errorf("expected literal got %s", scanner.TokenString(p.tok)) 848 } 849 850 if typ0 == nil { 851 typ0 = typ 852 } 853 854 pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val)) 855 } 856 857 // TypeDecl = "type" ExportedName Type . 858 // 859 func (p *parser) parseTypeDecl() { 860 p.expectKeyword("type") 861 pkg, name := p.parseExportedName() 862 obj := declTypeName(pkg, name) 863 864 // The type object may have been imported before and thus already 865 // have a type associated with it. We still need to parse the type 866 // structure, but throw it away if the object already has a type. 867 // This ensures that all imports refer to the same type object for 868 // a given type declaration. 869 typ := p.parseType(pkg) 870 871 if name := obj.Type().(*types.Named); name.Underlying() == nil { 872 name.SetUnderlying(typ) 873 } 874 } 875 876 // VarDecl = "var" ExportedName Type . 877 // 878 func (p *parser) parseVarDecl() { 879 p.expectKeyword("var") 880 pkg, name := p.parseExportedName() 881 typ := p.parseType(pkg) 882 pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ)) 883 } 884 885 // Func = Signature [ Body ] . 886 // Body = "{" ... "}" . 887 // 888 func (p *parser) parseFunc(recv *types.Var) *types.Signature { 889 sig := p.parseSignature(recv) 890 if p.tok == '{' { 891 p.next() 892 for i := 1; i > 0; p.next() { 893 switch p.tok { 894 case '{': 895 i++ 896 case '}': 897 i-- 898 } 899 } 900 } 901 return sig 902 } 903 904 // MethodDecl = "func" Receiver Name Func . 905 // Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" . 906 // 907 func (p *parser) parseMethodDecl() { 908 // "func" already consumed 909 p.expect('(') 910 recv, _ := p.parseParameter() // receiver 911 p.expect(')') 912 913 // determine receiver base type object 914 base := deref(recv.Type()).(*types.Named) 915 916 // parse method name, signature, and possibly inlined body 917 _, name := p.parseName(nil, false) 918 sig := p.parseFunc(recv) 919 920 // methods always belong to the same package as the base type object 921 pkg := base.Obj().Pkg() 922 923 // add method to type unless type was imported before 924 // and method exists already 925 // TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small. 926 base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) 927 } 928 929 // FuncDecl = "func" ExportedName Func . 930 // 931 func (p *parser) parseFuncDecl() { 932 // "func" already consumed 933 pkg, name := p.parseExportedName() 934 typ := p.parseFunc(nil) 935 pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ)) 936 } 937 938 // Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" . 939 // 940 func (p *parser) parseDecl() { 941 if p.tok == scanner.Ident { 942 switch p.lit { 943 case "import": 944 p.parseImportDecl() 945 case "const": 946 p.parseConstDecl() 947 case "type": 948 p.parseTypeDecl() 949 case "var": 950 p.parseVarDecl() 951 case "func": 952 p.next() // look ahead 953 if p.tok == '(' { 954 p.parseMethodDecl() 955 } else { 956 p.parseFuncDecl() 957 } 958 } 959 } 960 p.expect('\n') 961 } 962 963 // ---------------------------------------------------------------------------- 964 // Export 965 966 // Export = "PackageClause { Decl } "$$" . 967 // PackageClause = "package" PackageName [ "safe" ] "\n" . 968 // 969 func (p *parser) parseExport() *types.Package { 970 p.expectKeyword("package") 971 name := p.parsePackageName() 972 if p.tok == scanner.Ident && p.lit == "safe" { 973 // package was compiled with -u option - ignore 974 p.next() 975 } 976 p.expect('\n') 977 978 pkg := p.getPkg(p.id, name) 979 980 for p.tok != '$' && p.tok != scanner.EOF { 981 p.parseDecl() 982 } 983 984 if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' { 985 // don't call next()/expect() since reading past the 986 // export data may cause scanner errors (e.g. NUL chars) 987 p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch) 988 } 989 990 if n := p.scanner.ErrorCount; n != 0 { 991 p.errorf("expected no scanner errors, got %d", n) 992 } 993 994 // Record all locally referenced packages as imports. 995 var imports []*types.Package 996 for id, pkg2 := range p.localPkgs { 997 if pkg2.Name() == "" { 998 p.errorf("%s package has no name", id) 999 } 1000 if id == p.id { 1001 continue // avoid self-edge 1002 } 1003 imports = append(imports, pkg2) 1004 } 1005 sort.Sort(byPath(imports)) 1006 pkg.SetImports(imports) 1007 1008 // package was imported completely and without errors 1009 pkg.MarkComplete() 1010 1011 return pkg 1012 } 1013 1014 type byPath []*types.Package 1015 1016 func (a byPath) Len() int { return len(a) } 1017 func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 1018 func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }