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