github.com/d4l3k/go@v0.0.0-20151015000803-65fc379daeda/src/go/internal/gcimporter/gcimporter.go (about)

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