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() }