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