github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/go/gcimporter/gcimporter.go (about)

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