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