...

Source file src/golang.org/x/tools/go/internal/gccgoimporter/parser.go

Documentation: golang.org/x/tools/go/internal/gccgoimporter

     1  // Copyright 2013 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  // Except for this comment, this file is a verbatim copy of the file
     6  // with the same name in $GOROOT/src/go/internal/gccgoimporter, with
     7  // a small modification in parseInterface to support older Go versions.
     8  
     9  package gccgoimporter
    10  
    11  import (
    12  	"bytes"
    13  	"errors"
    14  	"fmt"
    15  	"go/constant"
    16  	"go/token"
    17  	"go/types"
    18  	"io"
    19  	"strconv"
    20  	"strings"
    21  	"text/scanner"
    22  	"unicode/utf8"
    23  
    24  	"golang.org/x/tools/internal/aliases"
    25  	"golang.org/x/tools/internal/typesinternal"
    26  )
    27  
    28  type parser struct {
    29  	scanner  *scanner.Scanner
    30  	version  string                    // format version
    31  	tok      rune                      // current token
    32  	lit      string                    // literal string; only valid for Ident, Int, String tokens
    33  	pkgpath  string                    // package path of imported package
    34  	pkgname  string                    // name of imported package
    35  	pkg      *types.Package            // reference to imported package
    36  	imports  map[string]*types.Package // package path -> package object
    37  	typeList []types.Type              // type number -> type
    38  	typeData []string                  // unparsed type data (v3 and later)
    39  	fixups   []fixupRecord             // fixups to apply at end of parsing
    40  	initdata InitData                  // package init priority data
    41  	aliases  map[int]string            // maps saved type number to alias name
    42  }
    43  
    44  // When reading export data it's possible to encounter a defined type
    45  // N1 with an underlying defined type N2 while we are still reading in
    46  // that defined type N2; see issues #29006 and #29198 for instances
    47  // of this. Example:
    48  //
    49  //   type N1 N2
    50  //   type N2 struct {
    51  //      ...
    52  //      p *N1
    53  //   }
    54  //
    55  // To handle such cases, the parser generates a fixup record (below) and
    56  // delays setting of N1's underlying type until parsing is complete, at
    57  // which point fixups are applied.
    58  
    59  type fixupRecord struct {
    60  	toUpdate *types.Named // type to modify when fixup is processed
    61  	target   types.Type   // type that was incomplete when fixup was created
    62  }
    63  
    64  func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
    65  	p.scanner = new(scanner.Scanner)
    66  	p.initScanner(filename, src)
    67  	p.imports = imports
    68  	p.aliases = make(map[int]string)
    69  	p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
    70  }
    71  
    72  func (p *parser) initScanner(filename string, src io.Reader) {
    73  	p.scanner.Init(src)
    74  	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
    75  	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings
    76  	p.scanner.Whitespace = 1<<'\t' | 1<<' '
    77  	p.scanner.Filename = filename // for good error messages
    78  	p.next()
    79  }
    80  
    81  type importError struct {
    82  	pos scanner.Position
    83  	err error
    84  }
    85  
    86  func (e importError) Error() string {
    87  	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
    88  }
    89  
    90  func (p *parser) error(err interface{}) {
    91  	if s, ok := err.(string); ok {
    92  		err = errors.New(s)
    93  	}
    94  	// panic with a runtime.Error if err is not an error
    95  	panic(importError{p.scanner.Pos(), err.(error)})
    96  }
    97  
    98  func (p *parser) errorf(format string, args ...interface{}) {
    99  	p.error(fmt.Errorf(format, args...))
   100  }
   101  
   102  func (p *parser) expect(tok rune) string {
   103  	lit := p.lit
   104  	if p.tok != tok {
   105  		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
   106  	}
   107  	p.next()
   108  	return lit
   109  }
   110  
   111  func (p *parser) expectEOL() {
   112  	if p.version == "v1" || p.version == "v2" {
   113  		p.expect(';')
   114  	}
   115  	p.expect('\n')
   116  }
   117  
   118  func (p *parser) expectKeyword(keyword string) {
   119  	lit := p.expect(scanner.Ident)
   120  	if lit != keyword {
   121  		p.errorf("expected keyword %s, got %q", keyword, lit)
   122  	}
   123  }
   124  
   125  func (p *parser) parseString() string {
   126  	str, err := strconv.Unquote(p.expect(scanner.String))
   127  	if err != nil {
   128  		p.error(err)
   129  	}
   130  	return str
   131  }
   132  
   133  // parseUnquotedString parses an UnquotedString:
   134  //
   135  //	unquotedString     = { unquotedStringChar } .
   136  //	unquotedStringChar = <neither a whitespace nor a ';' char> .
   137  func (p *parser) parseUnquotedString() string {
   138  	if p.tok == scanner.EOF {
   139  		p.error("unexpected EOF")
   140  	}
   141  	var buf bytes.Buffer
   142  	buf.WriteString(p.scanner.TokenText())
   143  	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
   144  	// we need to let it be consumed by p.next().
   145  	for ch := p.scanner.Peek(); ch != '\n' && ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
   146  		buf.WriteRune(ch)
   147  		p.scanner.Next()
   148  	}
   149  	p.next()
   150  	return buf.String()
   151  }
   152  
   153  func (p *parser) next() {
   154  	p.tok = p.scanner.Scan()
   155  	switch p.tok {
   156  	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, 'ยท':
   157  		p.lit = p.scanner.TokenText()
   158  	default:
   159  		p.lit = ""
   160  	}
   161  }
   162  
   163  func (p *parser) parseQualifiedName() (path, name string) {
   164  	return p.parseQualifiedNameStr(p.parseString())
   165  }
   166  
   167  func (p *parser) parseUnquotedQualifiedName() (path, name string) {
   168  	return p.parseQualifiedNameStr(p.parseUnquotedString())
   169  }
   170  
   171  // parseQualifiedNameStr is given the leading name (unquoted by the caller if necessary)
   172  // and then parses the remainder of a qualified name:
   173  //
   174  //	qualifiedName = [ ["."] unquotedString "." ] unquotedString .
   175  //
   176  // The above production uses greedy matching.
   177  func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
   178  	parts := strings.Split(unquotedName, ".")
   179  	if parts[0] == "" {
   180  		parts = parts[1:]
   181  	}
   182  
   183  	switch len(parts) {
   184  	case 0:
   185  		p.errorf("malformed qualified name: %q", unquotedName)
   186  	case 1:
   187  		// unqualified name
   188  		pkgpath = p.pkgpath
   189  		name = parts[0]
   190  	default:
   191  		// qualified name, which may contain periods
   192  		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
   193  		name = parts[len(parts)-1]
   194  	}
   195  
   196  	return
   197  }
   198  
   199  // getPkg returns the package for a given path. If the package is
   200  // not found but we have a package name, create the package and
   201  // add it to the p.imports map.
   202  func (p *parser) getPkg(pkgpath, name string) *types.Package {
   203  	// package unsafe is not in the imports map - handle explicitly
   204  	if pkgpath == "unsafe" {
   205  		return types.Unsafe
   206  	}
   207  	pkg := p.imports[pkgpath]
   208  	if pkg == nil && name != "" {
   209  		pkg = types.NewPackage(pkgpath, name)
   210  		p.imports[pkgpath] = pkg
   211  	}
   212  	return pkg
   213  }
   214  
   215  // parseExportedName is like parseQualifiedName, but
   216  // the package path is resolved to an imported *types.Package.
   217  //
   218  //	ExportedName = string [string] .
   219  func (p *parser) parseExportedName() (pkg *types.Package, name string) {
   220  	path, name := p.parseQualifiedName()
   221  	var pkgname string
   222  	if p.tok == scanner.String {
   223  		pkgname = p.parseString()
   224  	}
   225  	pkg = p.getPkg(path, pkgname)
   226  	if pkg == nil {
   227  		p.errorf("package %s (path = %q) not found", name, path)
   228  	}
   229  	return
   230  }
   231  
   232  // parseName parses a Name:
   233  //
   234  //	Name = QualifiedName | "?" .
   235  func (p *parser) parseName() string {
   236  	if p.tok == '?' {
   237  		// Anonymous.
   238  		p.next()
   239  		return ""
   240  	}
   241  	// The package path is redundant for us. Don't try to parse it.
   242  	_, name := p.parseUnquotedQualifiedName()
   243  	return name
   244  }
   245  
   246  // parseField parses a Field:
   247  //
   248  //	Field = Name Type [string] .
   249  func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
   250  	name := p.parseName()
   251  	typ, n := p.parseTypeExtended(pkg)
   252  	anon := false
   253  	if name == "" {
   254  		anon = true
   255  		// Alias?
   256  		if aname, ok := p.aliases[n]; ok {
   257  			name = aname
   258  		} else {
   259  			switch typ := aliases.Unalias(typesinternal.Unpointer(typ)).(type) {
   260  			case *types.Basic:
   261  				name = typ.Name()
   262  			case *types.Named:
   263  				name = typ.Obj().Name()
   264  			default:
   265  				p.error("embedded field expected")
   266  			}
   267  		}
   268  	}
   269  	field = types.NewField(token.NoPos, pkg, name, typ, anon)
   270  	if p.tok == scanner.String {
   271  		tag = p.parseString()
   272  	}
   273  	return
   274  }
   275  
   276  // parseParam parses a Param:
   277  //
   278  //	Param = Name ["..."] Type .
   279  func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
   280  	name := p.parseName()
   281  	// Ignore names invented for inlinable functions.
   282  	if strings.HasPrefix(name, "p.") || strings.HasPrefix(name, "r.") || strings.HasPrefix(name, "$ret") {
   283  		name = ""
   284  	}
   285  	if p.tok == '<' && p.scanner.Peek() == 'e' {
   286  		// EscInfo = "<esc:" int ">" . (optional and ignored)
   287  		p.next()
   288  		p.expectKeyword("esc")
   289  		p.expect(':')
   290  		p.expect(scanner.Int)
   291  		p.expect('>')
   292  	}
   293  	if p.tok == '.' {
   294  		p.next()
   295  		p.expect('.')
   296  		p.expect('.')
   297  		isVariadic = true
   298  	}
   299  	typ := p.parseType(pkg)
   300  	if isVariadic {
   301  		typ = types.NewSlice(typ)
   302  	}
   303  	param = types.NewParam(token.NoPos, pkg, name, typ)
   304  	return
   305  }
   306  
   307  // parseVar parses a Var:
   308  //
   309  //	Var = Name Type .
   310  func (p *parser) parseVar(pkg *types.Package) *types.Var {
   311  	name := p.parseName()
   312  	v := types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
   313  	if name[0] == '.' || name[0] == '<' {
   314  		// This is an unexported variable,
   315  		// or a variable defined in a different package.
   316  		// We only want to record exported variables.
   317  		return nil
   318  	}
   319  	return v
   320  }
   321  
   322  // parseConversion parses a Conversion:
   323  //
   324  //	Conversion = "convert" "(" Type "," ConstValue ")" .
   325  func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
   326  	p.expectKeyword("convert")
   327  	p.expect('(')
   328  	typ = p.parseType(pkg)
   329  	p.expect(',')
   330  	val, _ = p.parseConstValue(pkg)
   331  	p.expect(')')
   332  	return
   333  }
   334  
   335  // parseConstValue parses a ConstValue:
   336  //
   337  //	ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
   338  //	FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
   339  func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
   340  	// v3 changed to $false, $true, $convert, to avoid confusion
   341  	// with variable names in inline function bodies.
   342  	if p.tok == '$' {
   343  		p.next()
   344  		if p.tok != scanner.Ident {
   345  			p.errorf("expected identifier after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit)
   346  		}
   347  	}
   348  
   349  	switch p.tok {
   350  	case scanner.String:
   351  		str := p.parseString()
   352  		val = constant.MakeString(str)
   353  		typ = types.Typ[types.UntypedString]
   354  		return
   355  
   356  	case scanner.Ident:
   357  		b := false
   358  		switch p.lit {
   359  		case "false":
   360  		case "true":
   361  			b = true
   362  
   363  		case "convert":
   364  			return p.parseConversion(pkg)
   365  
   366  		default:
   367  			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   368  		}
   369  
   370  		p.next()
   371  		val = constant.MakeBool(b)
   372  		typ = types.Typ[types.UntypedBool]
   373  		return
   374  	}
   375  
   376  	sign := ""
   377  	if p.tok == '-' {
   378  		p.next()
   379  		sign = "-"
   380  	}
   381  
   382  	switch p.tok {
   383  	case scanner.Int:
   384  		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
   385  		if val == nil {
   386  			p.error("could not parse integer literal")
   387  		}
   388  
   389  		p.next()
   390  		if p.tok == '\'' {
   391  			p.next()
   392  			typ = types.Typ[types.UntypedRune]
   393  		} else {
   394  			typ = types.Typ[types.UntypedInt]
   395  		}
   396  
   397  	case scanner.Float:
   398  		re := sign + p.lit
   399  		p.next()
   400  
   401  		var im string
   402  		switch p.tok {
   403  		case '+':
   404  			p.next()
   405  			im = p.expect(scanner.Float)
   406  
   407  		case '-':
   408  			p.next()
   409  			im = "-" + p.expect(scanner.Float)
   410  
   411  		case scanner.Ident:
   412  			// re is in fact the imaginary component. Expect "i" below.
   413  			im = re
   414  			re = "0"
   415  
   416  		default:
   417  			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
   418  			if val == nil {
   419  				p.error("could not parse float literal")
   420  			}
   421  			typ = types.Typ[types.UntypedFloat]
   422  			return
   423  		}
   424  
   425  		p.expectKeyword("i")
   426  		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
   427  		if reval == nil {
   428  			p.error("could not parse real component of complex literal")
   429  		}
   430  		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
   431  		if imval == nil {
   432  			p.error("could not parse imag component of complex literal")
   433  		}
   434  		val = constant.BinaryOp(reval, token.ADD, imval)
   435  		typ = types.Typ[types.UntypedComplex]
   436  
   437  	default:
   438  		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   439  	}
   440  
   441  	return
   442  }
   443  
   444  // parseConst parses a Const:
   445  //
   446  //	Const = Name [Type] "=" ConstValue .
   447  func (p *parser) parseConst(pkg *types.Package) *types.Const {
   448  	name := p.parseName()
   449  	var typ types.Type
   450  	if p.tok == '<' {
   451  		typ = p.parseType(pkg)
   452  	}
   453  	p.expect('=')
   454  	val, vtyp := p.parseConstValue(pkg)
   455  	if typ == nil {
   456  		typ = vtyp
   457  	}
   458  	return types.NewConst(token.NoPos, pkg, name, typ, val)
   459  }
   460  
   461  // reserved is a singleton type used to fill type map slots that have
   462  // been reserved (i.e., for which a type number has been parsed) but
   463  // which don't have their actual type yet. When the type map is updated,
   464  // the actual type must replace a reserved entry (or we have an internal
   465  // error). Used for self-verification only - not required for correctness.
   466  var reserved = new(struct{ types.Type })
   467  
   468  // reserve reserves the type map entry n for future use.
   469  func (p *parser) reserve(n int) {
   470  	// Notes:
   471  	// - for pre-V3 export data, the type numbers we see are
   472  	//   guaranteed to be in increasing order, so we append a
   473  	//   reserved entry onto the list.
   474  	// - for V3+ export data, type numbers can appear in
   475  	//   any order, however the 'types' section tells us the
   476  	//   total number of types, hence typeList is pre-allocated.
   477  	if len(p.typeData) == 0 {
   478  		if n != len(p.typeList) {
   479  			p.errorf("invalid type number %d (out of sync)", n)
   480  		}
   481  		p.typeList = append(p.typeList, reserved)
   482  	} else {
   483  		if p.typeList[n] != nil {
   484  			p.errorf("previously visited type number %d", n)
   485  		}
   486  		p.typeList[n] = reserved
   487  	}
   488  }
   489  
   490  // update sets the type map entries for the entries in nlist to t.
   491  // An entry in nlist can be a type number in p.typeList,
   492  // used to resolve named types, or it can be a *types.Pointer,
   493  // used to resolve pointers to named types in case they are referenced
   494  // by embedded fields.
   495  func (p *parser) update(t types.Type, nlist []interface{}) {
   496  	if t == reserved {
   497  		p.errorf("internal error: update(%v) invoked on reserved", nlist)
   498  	}
   499  	if t == nil {
   500  		p.errorf("internal error: update(%v) invoked on nil", nlist)
   501  	}
   502  	for _, n := range nlist {
   503  		switch n := n.(type) {
   504  		case int:
   505  			if p.typeList[n] == t {
   506  				continue
   507  			}
   508  			if p.typeList[n] != reserved {
   509  				p.errorf("internal error: update(%v): %d not reserved", nlist, n)
   510  			}
   511  			p.typeList[n] = t
   512  		case *types.Pointer:
   513  			if *n != (types.Pointer{}) {
   514  				elem := n.Elem()
   515  				if elem == t {
   516  					continue
   517  				}
   518  				p.errorf("internal error: update: pointer already set to %v, expected %v", elem, t)
   519  			}
   520  			*n = *types.NewPointer(t)
   521  		default:
   522  			p.errorf("internal error: %T on nlist", n)
   523  		}
   524  	}
   525  }
   526  
   527  // parseNamedType parses a NamedType:
   528  //
   529  //	NamedType = TypeName [ "=" ] Type { Method } .
   530  //	TypeName  = ExportedName .
   531  //	Method    = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" .
   532  func (p *parser) parseNamedType(nlist []interface{}) types.Type {
   533  	pkg, name := p.parseExportedName()
   534  	scope := pkg.Scope()
   535  	obj := scope.Lookup(name)
   536  	if obj != nil && obj.Type() == nil {
   537  		p.errorf("%v has nil type", obj)
   538  	}
   539  
   540  	if p.tok == scanner.Ident && p.lit == "notinheap" {
   541  		p.next()
   542  		// The go/types package has no way of recording that
   543  		// this type is marked notinheap. Presumably no user
   544  		// of this package actually cares.
   545  	}
   546  
   547  	// type alias
   548  	if p.tok == '=' {
   549  		p.next()
   550  		p.aliases[nlist[len(nlist)-1].(int)] = name
   551  		if obj != nil {
   552  			// use the previously imported (canonical) type
   553  			t := obj.Type()
   554  			p.update(t, nlist)
   555  			p.parseType(pkg) // discard
   556  			return t
   557  		}
   558  		t := p.parseType(pkg, nlist...)
   559  		obj = types.NewTypeName(token.NoPos, pkg, name, t)
   560  		scope.Insert(obj)
   561  		return t
   562  	}
   563  
   564  	// defined type
   565  	if obj == nil {
   566  		// A named type may be referred to before the underlying type
   567  		// is known - set it up.
   568  		tname := types.NewTypeName(token.NoPos, pkg, name, nil)
   569  		types.NewNamed(tname, nil, nil)
   570  		scope.Insert(tname)
   571  		obj = tname
   572  	}
   573  
   574  	// use the previously imported (canonical), or newly created type
   575  	t := obj.Type()
   576  	p.update(t, nlist)
   577  
   578  	nt, ok := aliases.Unalias(t).(*types.Named)
   579  	if !ok {
   580  		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
   581  		pt := p.parseType(pkg)
   582  		if pt != t {
   583  			p.error("unexpected underlying type for non-named TypeName")
   584  		}
   585  		return t
   586  	}
   587  
   588  	underlying := p.parseType(pkg)
   589  	if nt.Underlying() == nil {
   590  		if underlying.Underlying() == nil {
   591  			fix := fixupRecord{toUpdate: nt, target: underlying}
   592  			p.fixups = append(p.fixups, fix)
   593  		} else {
   594  			nt.SetUnderlying(underlying.Underlying())
   595  		}
   596  	}
   597  
   598  	if p.tok == '\n' {
   599  		p.next()
   600  		// collect associated methods
   601  		for p.tok == scanner.Ident {
   602  			p.expectKeyword("func")
   603  			if p.tok == '/' {
   604  				// Skip a /*nointerface*/ or /*asm ID */ comment.
   605  				p.expect('/')
   606  				p.expect('*')
   607  				if p.expect(scanner.Ident) == "asm" {
   608  					p.parseUnquotedString()
   609  				}
   610  				p.expect('*')
   611  				p.expect('/')
   612  			}
   613  			p.expect('(')
   614  			receiver, _ := p.parseParam(pkg)
   615  			p.expect(')')
   616  			name := p.parseName()
   617  			params, isVariadic := p.parseParamList(pkg)
   618  			results := p.parseResultList(pkg)
   619  			p.skipInlineBody()
   620  			p.expectEOL()
   621  
   622  			sig := types.NewSignature(receiver, params, results, isVariadic)
   623  			nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
   624  		}
   625  	}
   626  
   627  	return nt
   628  }
   629  
   630  func (p *parser) parseInt64() int64 {
   631  	lit := p.expect(scanner.Int)
   632  	n, err := strconv.ParseInt(lit, 10, 64)
   633  	if err != nil {
   634  		p.error(err)
   635  	}
   636  	return n
   637  }
   638  
   639  func (p *parser) parseInt() int {
   640  	lit := p.expect(scanner.Int)
   641  	n, err := strconv.ParseInt(lit, 10, 0 /* int */)
   642  	if err != nil {
   643  		p.error(err)
   644  	}
   645  	return int(n)
   646  }
   647  
   648  // parseArrayOrSliceType parses an ArrayOrSliceType:
   649  //
   650  //	ArrayOrSliceType = "[" [ int ] "]" Type .
   651  func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []interface{}) types.Type {
   652  	p.expect('[')
   653  	if p.tok == ']' {
   654  		p.next()
   655  
   656  		t := new(types.Slice)
   657  		p.update(t, nlist)
   658  
   659  		*t = *types.NewSlice(p.parseType(pkg))
   660  		return t
   661  	}
   662  
   663  	t := new(types.Array)
   664  	p.update(t, nlist)
   665  
   666  	len := p.parseInt64()
   667  	p.expect(']')
   668  
   669  	*t = *types.NewArray(p.parseType(pkg), len)
   670  	return t
   671  }
   672  
   673  // parseMapType parses a MapType:
   674  //
   675  //	MapType = "map" "[" Type "]" Type .
   676  func (p *parser) parseMapType(pkg *types.Package, nlist []interface{}) types.Type {
   677  	p.expectKeyword("map")
   678  
   679  	t := new(types.Map)
   680  	p.update(t, nlist)
   681  
   682  	p.expect('[')
   683  	key := p.parseType(pkg)
   684  	p.expect(']')
   685  	elem := p.parseType(pkg)
   686  
   687  	*t = *types.NewMap(key, elem)
   688  	return t
   689  }
   690  
   691  // parseChanType parses a ChanType:
   692  //
   693  //	ChanType = "chan" ["<-" | "-<"] Type .
   694  func (p *parser) parseChanType(pkg *types.Package, nlist []interface{}) types.Type {
   695  	p.expectKeyword("chan")
   696  
   697  	t := new(types.Chan)
   698  	p.update(t, nlist)
   699  
   700  	dir := types.SendRecv
   701  	switch p.tok {
   702  	case '-':
   703  		p.next()
   704  		p.expect('<')
   705  		dir = types.SendOnly
   706  
   707  	case '<':
   708  		// don't consume '<' if it belongs to Type
   709  		if p.scanner.Peek() == '-' {
   710  			p.next()
   711  			p.expect('-')
   712  			dir = types.RecvOnly
   713  		}
   714  	}
   715  
   716  	*t = *types.NewChan(dir, p.parseType(pkg))
   717  	return t
   718  }
   719  
   720  // parseStructType parses a StructType:
   721  //
   722  //	StructType = "struct" "{" { Field } "}" .
   723  func (p *parser) parseStructType(pkg *types.Package, nlist []interface{}) types.Type {
   724  	p.expectKeyword("struct")
   725  
   726  	t := new(types.Struct)
   727  	p.update(t, nlist)
   728  
   729  	var fields []*types.Var
   730  	var tags []string
   731  
   732  	p.expect('{')
   733  	for p.tok != '}' && p.tok != scanner.EOF {
   734  		field, tag := p.parseField(pkg)
   735  		p.expect(';')
   736  		fields = append(fields, field)
   737  		tags = append(tags, tag)
   738  	}
   739  	p.expect('}')
   740  
   741  	*t = *types.NewStruct(fields, tags)
   742  	return t
   743  }
   744  
   745  // parseParamList parses a ParamList:
   746  //
   747  //	ParamList = "(" [ { Parameter "," } Parameter ] ")" .
   748  func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
   749  	var list []*types.Var
   750  	isVariadic := false
   751  
   752  	p.expect('(')
   753  	for p.tok != ')' && p.tok != scanner.EOF {
   754  		if len(list) > 0 {
   755  			p.expect(',')
   756  		}
   757  		par, variadic := p.parseParam(pkg)
   758  		list = append(list, par)
   759  		if variadic {
   760  			if isVariadic {
   761  				p.error("... not on final argument")
   762  			}
   763  			isVariadic = true
   764  		}
   765  	}
   766  	p.expect(')')
   767  
   768  	return types.NewTuple(list...), isVariadic
   769  }
   770  
   771  // parseResultList parses a ResultList:
   772  //
   773  //	ResultList = Type | ParamList .
   774  func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
   775  	switch p.tok {
   776  	case '<':
   777  		p.next()
   778  		if p.tok == scanner.Ident && p.lit == "inl" {
   779  			return nil
   780  		}
   781  		taa, _ := p.parseTypeAfterAngle(pkg)
   782  		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", taa))
   783  
   784  	case '(':
   785  		params, _ := p.parseParamList(pkg)
   786  		return params
   787  
   788  	default:
   789  		return nil
   790  	}
   791  }
   792  
   793  // parseFunctionType parses a FunctionType:
   794  //
   795  //	FunctionType = ParamList ResultList .
   796  func (p *parser) parseFunctionType(pkg *types.Package, nlist []interface{}) *types.Signature {
   797  	t := new(types.Signature)
   798  	p.update(t, nlist)
   799  
   800  	params, isVariadic := p.parseParamList(pkg)
   801  	results := p.parseResultList(pkg)
   802  
   803  	*t = *types.NewSignature(nil, params, results, isVariadic)
   804  	return t
   805  }
   806  
   807  // parseFunc parses a Func:
   808  //
   809  //	Func = Name FunctionType [InlineBody] .
   810  func (p *parser) parseFunc(pkg *types.Package) *types.Func {
   811  	if p.tok == '/' {
   812  		// Skip an /*asm ID */ comment.
   813  		p.expect('/')
   814  		p.expect('*')
   815  		if p.expect(scanner.Ident) == "asm" {
   816  			p.parseUnquotedString()
   817  		}
   818  		p.expect('*')
   819  		p.expect('/')
   820  	}
   821  
   822  	name := p.parseName()
   823  	f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
   824  	p.skipInlineBody()
   825  
   826  	if name[0] == '.' || name[0] == '<' || strings.ContainsRune(name, '$') {
   827  		// This is an unexported function,
   828  		// or a function defined in a different package,
   829  		// or a type$equal or type$hash function.
   830  		// We only want to record exported functions.
   831  		return nil
   832  	}
   833  
   834  	return f
   835  }
   836  
   837  // parseInterfaceType parses an InterfaceType:
   838  //
   839  //	InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
   840  func (p *parser) parseInterfaceType(pkg *types.Package, nlist []interface{}) types.Type {
   841  	p.expectKeyword("interface")
   842  
   843  	t := new(types.Interface)
   844  	p.update(t, nlist)
   845  
   846  	var methods []*types.Func
   847  	var embeddeds []types.Type
   848  
   849  	p.expect('{')
   850  	for p.tok != '}' && p.tok != scanner.EOF {
   851  		if p.tok == '?' {
   852  			p.next()
   853  			embeddeds = append(embeddeds, p.parseType(pkg))
   854  		} else {
   855  			method := p.parseFunc(pkg)
   856  			if method != nil {
   857  				methods = append(methods, method)
   858  			}
   859  		}
   860  		p.expect(';')
   861  	}
   862  	p.expect('}')
   863  
   864  	*t = *newInterface(methods, embeddeds)
   865  	return t
   866  }
   867  
   868  // parsePointerType parses a PointerType:
   869  //
   870  //	PointerType = "*" ("any" | Type) .
   871  func (p *parser) parsePointerType(pkg *types.Package, nlist []interface{}) types.Type {
   872  	p.expect('*')
   873  	if p.tok == scanner.Ident {
   874  		p.expectKeyword("any")
   875  		t := types.Typ[types.UnsafePointer]
   876  		p.update(t, nlist)
   877  		return t
   878  	}
   879  
   880  	t := new(types.Pointer)
   881  	p.update(t, nlist)
   882  
   883  	*t = *types.NewPointer(p.parseType(pkg, t))
   884  
   885  	return t
   886  }
   887  
   888  // parseTypeSpec parses a TypeSpec:
   889  //
   890  //	TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
   891  func (p *parser) parseTypeSpec(pkg *types.Package, nlist []interface{}) types.Type {
   892  	switch p.tok {
   893  	case scanner.String:
   894  		return p.parseNamedType(nlist)
   895  
   896  	case scanner.Ident:
   897  		switch p.lit {
   898  		case "map":
   899  			return p.parseMapType(pkg, nlist)
   900  
   901  		case "chan":
   902  			return p.parseChanType(pkg, nlist)
   903  
   904  		case "struct":
   905  			return p.parseStructType(pkg, nlist)
   906  
   907  		case "interface":
   908  			return p.parseInterfaceType(pkg, nlist)
   909  		}
   910  
   911  	case '*':
   912  		return p.parsePointerType(pkg, nlist)
   913  
   914  	case '[':
   915  		return p.parseArrayOrSliceType(pkg, nlist)
   916  
   917  	case '(':
   918  		return p.parseFunctionType(pkg, nlist)
   919  	}
   920  
   921  	p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
   922  	return nil
   923  }
   924  
   925  const (
   926  	// From gofrontend/go/export.h
   927  	// Note that these values are negative in the gofrontend and have been made positive
   928  	// in the gccgoimporter.
   929  	gccgoBuiltinINT8       = 1
   930  	gccgoBuiltinINT16      = 2
   931  	gccgoBuiltinINT32      = 3
   932  	gccgoBuiltinINT64      = 4
   933  	gccgoBuiltinUINT8      = 5
   934  	gccgoBuiltinUINT16     = 6
   935  	gccgoBuiltinUINT32     = 7
   936  	gccgoBuiltinUINT64     = 8
   937  	gccgoBuiltinFLOAT32    = 9
   938  	gccgoBuiltinFLOAT64    = 10
   939  	gccgoBuiltinINT        = 11
   940  	gccgoBuiltinUINT       = 12
   941  	gccgoBuiltinUINTPTR    = 13
   942  	gccgoBuiltinBOOL       = 15
   943  	gccgoBuiltinSTRING     = 16
   944  	gccgoBuiltinCOMPLEX64  = 17
   945  	gccgoBuiltinCOMPLEX128 = 18
   946  	gccgoBuiltinERROR      = 19
   947  	gccgoBuiltinBYTE       = 20
   948  	gccgoBuiltinRUNE       = 21
   949  	gccgoBuiltinANY        = 22
   950  )
   951  
   952  func lookupBuiltinType(typ int) types.Type {
   953  	return [...]types.Type{
   954  		gccgoBuiltinINT8:       types.Typ[types.Int8],
   955  		gccgoBuiltinINT16:      types.Typ[types.Int16],
   956  		gccgoBuiltinINT32:      types.Typ[types.Int32],
   957  		gccgoBuiltinINT64:      types.Typ[types.Int64],
   958  		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
   959  		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
   960  		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
   961  		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
   962  		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
   963  		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
   964  		gccgoBuiltinINT:        types.Typ[types.Int],
   965  		gccgoBuiltinUINT:       types.Typ[types.Uint],
   966  		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
   967  		gccgoBuiltinBOOL:       types.Typ[types.Bool],
   968  		gccgoBuiltinSTRING:     types.Typ[types.String],
   969  		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
   970  		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
   971  		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
   972  		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
   973  		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
   974  		gccgoBuiltinANY:        types.Universe.Lookup("any").Type(),
   975  	}[typ]
   976  }
   977  
   978  // parseType parses a Type:
   979  //
   980  //	Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
   981  //
   982  // parseType updates the type map to t for all type numbers n.
   983  func (p *parser) parseType(pkg *types.Package, n ...interface{}) types.Type {
   984  	p.expect('<')
   985  	t, _ := p.parseTypeAfterAngle(pkg, n...)
   986  	return t
   987  }
   988  
   989  // (*parser).Type after reading the "<".
   990  func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
   991  	p.expectKeyword("type")
   992  
   993  	n1 = 0
   994  	switch p.tok {
   995  	case scanner.Int:
   996  		n1 = p.parseInt()
   997  		if p.tok == '>' {
   998  			if len(p.typeData) > 0 && p.typeList[n1] == nil {
   999  				p.parseSavedType(pkg, n1, n)
  1000  			}
  1001  			t = p.typeList[n1]
  1002  			if len(p.typeData) == 0 && t == reserved {
  1003  				p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n)
  1004  			}
  1005  			p.update(t, n)
  1006  		} else {
  1007  			p.reserve(n1)
  1008  			t = p.parseTypeSpec(pkg, append(n, n1))
  1009  		}
  1010  
  1011  	case '-':
  1012  		p.next()
  1013  		n1 := p.parseInt()
  1014  		t = lookupBuiltinType(n1)
  1015  		p.update(t, n)
  1016  
  1017  	default:
  1018  		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
  1019  		return nil, 0
  1020  	}
  1021  
  1022  	if t == nil || t == reserved {
  1023  		p.errorf("internal error: bad return from parseType(%v)", n)
  1024  	}
  1025  
  1026  	p.expect('>')
  1027  	return
  1028  }
  1029  
  1030  // parseTypeExtended is identical to parseType, but if the type in
  1031  // question is a saved type, returns the index as well as the type
  1032  // pointer (index returned is zero if we parsed a builtin).
  1033  func (p *parser) parseTypeExtended(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
  1034  	p.expect('<')
  1035  	t, n1 = p.parseTypeAfterAngle(pkg, n...)
  1036  	return
  1037  }
  1038  
  1039  // InlineBody = "<inl:NN>" .{NN}
  1040  // Reports whether a body was skipped.
  1041  func (p *parser) skipInlineBody() {
  1042  	// We may or may not have seen the '<' already, depending on
  1043  	// whether the function had a result type or not.
  1044  	if p.tok == '<' {
  1045  		p.next()
  1046  		p.expectKeyword("inl")
  1047  	} else if p.tok != scanner.Ident || p.lit != "inl" {
  1048  		return
  1049  	} else {
  1050  		p.next()
  1051  	}
  1052  
  1053  	p.expect(':')
  1054  	want := p.parseInt()
  1055  	p.expect('>')
  1056  
  1057  	defer func(w uint64) {
  1058  		p.scanner.Whitespace = w
  1059  	}(p.scanner.Whitespace)
  1060  	p.scanner.Whitespace = 0
  1061  
  1062  	got := 0
  1063  	for got < want {
  1064  		r := p.scanner.Next()
  1065  		if r == scanner.EOF {
  1066  			p.error("unexpected EOF")
  1067  		}
  1068  		got += utf8.RuneLen(r)
  1069  	}
  1070  }
  1071  
  1072  // parseTypes parses a Types:
  1073  //
  1074  //	Types = "types" maxp1 exportedp1 (offset length)* .
  1075  func (p *parser) parseTypes(pkg *types.Package) {
  1076  	maxp1 := p.parseInt()
  1077  	exportedp1 := p.parseInt()
  1078  	p.typeList = make([]types.Type, maxp1)
  1079  
  1080  	type typeOffset struct {
  1081  		offset int
  1082  		length int
  1083  	}
  1084  	var typeOffsets []typeOffset
  1085  
  1086  	total := 0
  1087  	for i := 1; i < maxp1; i++ {
  1088  		len := p.parseInt()
  1089  		typeOffsets = append(typeOffsets, typeOffset{total, len})
  1090  		total += len
  1091  	}
  1092  
  1093  	defer func(w uint64) {
  1094  		p.scanner.Whitespace = w
  1095  	}(p.scanner.Whitespace)
  1096  	p.scanner.Whitespace = 0
  1097  
  1098  	// We should now have p.tok pointing to the final newline.
  1099  	// The next runes from the scanner should be the type data.
  1100  
  1101  	var sb strings.Builder
  1102  	for sb.Len() < total {
  1103  		r := p.scanner.Next()
  1104  		if r == scanner.EOF {
  1105  			p.error("unexpected EOF")
  1106  		}
  1107  		sb.WriteRune(r)
  1108  	}
  1109  	allTypeData := sb.String()
  1110  
  1111  	p.typeData = []string{""} // type 0, unused
  1112  	for _, to := range typeOffsets {
  1113  		p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length])
  1114  	}
  1115  
  1116  	for i := 1; i < int(exportedp1); i++ {
  1117  		p.parseSavedType(pkg, i, nil)
  1118  	}
  1119  }
  1120  
  1121  // parseSavedType parses one saved type definition.
  1122  func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []interface{}) {
  1123  	defer func(s *scanner.Scanner, tok rune, lit string) {
  1124  		p.scanner = s
  1125  		p.tok = tok
  1126  		p.lit = lit
  1127  	}(p.scanner, p.tok, p.lit)
  1128  
  1129  	p.scanner = new(scanner.Scanner)
  1130  	p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i]))
  1131  	p.expectKeyword("type")
  1132  	id := p.parseInt()
  1133  	if id != i {
  1134  		p.errorf("type ID mismatch: got %d, want %d", id, i)
  1135  	}
  1136  	if p.typeList[i] == reserved {
  1137  		p.errorf("internal error: %d already reserved in parseSavedType", i)
  1138  	}
  1139  	if p.typeList[i] == nil {
  1140  		p.reserve(i)
  1141  		p.parseTypeSpec(pkg, append(nlist, i))
  1142  	}
  1143  	if p.typeList[i] == nil || p.typeList[i] == reserved {
  1144  		p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist)
  1145  	}
  1146  }
  1147  
  1148  // parsePackageInit parses a PackageInit:
  1149  //
  1150  //	PackageInit = unquotedString unquotedString int .
  1151  func (p *parser) parsePackageInit() PackageInit {
  1152  	name := p.parseUnquotedString()
  1153  	initfunc := p.parseUnquotedString()
  1154  	priority := -1
  1155  	if p.version == "v1" {
  1156  		priority = p.parseInt()
  1157  	}
  1158  	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
  1159  }
  1160  
  1161  // Create the package if we have parsed both the package path and package name.
  1162  func (p *parser) maybeCreatePackage() {
  1163  	if p.pkgname != "" && p.pkgpath != "" {
  1164  		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
  1165  	}
  1166  }
  1167  
  1168  // parseInitDataDirective parses an InitDataDirective:
  1169  //
  1170  //	InitDataDirective = ( "v1" | "v2" | "v3" ) ";" |
  1171  //		"priority" int ";" |
  1172  //		"init" { PackageInit } ";" |
  1173  //		"checksum" unquotedString ";" .
  1174  func (p *parser) parseInitDataDirective() {
  1175  	if p.tok != scanner.Ident {
  1176  		// unexpected token kind; panic
  1177  		p.expect(scanner.Ident)
  1178  	}
  1179  
  1180  	switch p.lit {
  1181  	case "v1", "v2", "v3":
  1182  		p.version = p.lit
  1183  		p.next()
  1184  		p.expect(';')
  1185  		p.expect('\n')
  1186  
  1187  	case "priority":
  1188  		p.next()
  1189  		p.initdata.Priority = p.parseInt()
  1190  		p.expectEOL()
  1191  
  1192  	case "init":
  1193  		p.next()
  1194  		for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
  1195  			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
  1196  		}
  1197  		p.expectEOL()
  1198  
  1199  	case "init_graph":
  1200  		p.next()
  1201  		// The graph data is thrown away for now.
  1202  		for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
  1203  			p.parseInt64()
  1204  			p.parseInt64()
  1205  		}
  1206  		p.expectEOL()
  1207  
  1208  	case "checksum":
  1209  		// Don't let the scanner try to parse the checksum as a number.
  1210  		defer func(mode uint) {
  1211  			p.scanner.Mode = mode
  1212  		}(p.scanner.Mode)
  1213  		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
  1214  		p.next()
  1215  		p.parseUnquotedString()
  1216  		p.expectEOL()
  1217  
  1218  	default:
  1219  		p.errorf("unexpected identifier: %q", p.lit)
  1220  	}
  1221  }
  1222  
  1223  // parseDirective parses a Directive:
  1224  //
  1225  //	Directive = InitDataDirective |
  1226  //		"package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
  1227  //		"pkgpath" unquotedString ";" |
  1228  //		"prefix" unquotedString ";" |
  1229  //		"import" unquotedString unquotedString string ";" |
  1230  //		"indirectimport" unquotedString unquotedstring ";" |
  1231  //		"func" Func ";" |
  1232  //		"type" Type ";" |
  1233  //		"var" Var ";" |
  1234  //		"const" Const ";" .
  1235  func (p *parser) parseDirective() {
  1236  	if p.tok != scanner.Ident {
  1237  		// unexpected token kind; panic
  1238  		p.expect(scanner.Ident)
  1239  	}
  1240  
  1241  	switch p.lit {
  1242  	case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum":
  1243  		p.parseInitDataDirective()
  1244  
  1245  	case "package":
  1246  		p.next()
  1247  		p.pkgname = p.parseUnquotedString()
  1248  		p.maybeCreatePackage()
  1249  		if p.version != "v1" && p.tok != '\n' && p.tok != ';' {
  1250  			p.parseUnquotedString()
  1251  			p.parseUnquotedString()
  1252  		}
  1253  		p.expectEOL()
  1254  
  1255  	case "pkgpath":
  1256  		p.next()
  1257  		p.pkgpath = p.parseUnquotedString()
  1258  		p.maybeCreatePackage()
  1259  		p.expectEOL()
  1260  
  1261  	case "prefix":
  1262  		p.next()
  1263  		p.pkgpath = p.parseUnquotedString()
  1264  		p.expectEOL()
  1265  
  1266  	case "import":
  1267  		p.next()
  1268  		pkgname := p.parseUnquotedString()
  1269  		pkgpath := p.parseUnquotedString()
  1270  		p.getPkg(pkgpath, pkgname)
  1271  		p.parseString()
  1272  		p.expectEOL()
  1273  
  1274  	case "indirectimport":
  1275  		p.next()
  1276  		pkgname := p.parseUnquotedString()
  1277  		pkgpath := p.parseUnquotedString()
  1278  		p.getPkg(pkgpath, pkgname)
  1279  		p.expectEOL()
  1280  
  1281  	case "types":
  1282  		p.next()
  1283  		p.parseTypes(p.pkg)
  1284  		p.expectEOL()
  1285  
  1286  	case "func":
  1287  		p.next()
  1288  		fun := p.parseFunc(p.pkg)
  1289  		if fun != nil {
  1290  			p.pkg.Scope().Insert(fun)
  1291  		}
  1292  		p.expectEOL()
  1293  
  1294  	case "type":
  1295  		p.next()
  1296  		p.parseType(p.pkg)
  1297  		p.expectEOL()
  1298  
  1299  	case "var":
  1300  		p.next()
  1301  		v := p.parseVar(p.pkg)
  1302  		if v != nil {
  1303  			p.pkg.Scope().Insert(v)
  1304  		}
  1305  		p.expectEOL()
  1306  
  1307  	case "const":
  1308  		p.next()
  1309  		c := p.parseConst(p.pkg)
  1310  		p.pkg.Scope().Insert(c)
  1311  		p.expectEOL()
  1312  
  1313  	default:
  1314  		p.errorf("unexpected identifier: %q", p.lit)
  1315  	}
  1316  }
  1317  
  1318  // parsePackage parses a Package:
  1319  //
  1320  //	Package = { Directive } .
  1321  func (p *parser) parsePackage() *types.Package {
  1322  	for p.tok != scanner.EOF {
  1323  		p.parseDirective()
  1324  	}
  1325  	for _, f := range p.fixups {
  1326  		if f.target.Underlying() == nil {
  1327  			p.errorf("internal error: fixup can't be applied, loop required")
  1328  		}
  1329  		f.toUpdate.SetUnderlying(f.target.Underlying())
  1330  	}
  1331  	p.fixups = nil
  1332  	for _, typ := range p.typeList {
  1333  		if it, ok := aliases.Unalias(typ).(*types.Interface); ok {
  1334  			it.Complete()
  1335  		}
  1336  	}
  1337  	p.pkg.MarkComplete()
  1338  	return p.pkg
  1339  }
  1340  

View as plain text