github.com/goplus/gop@v1.2.6/x/typesutil/info_test.go (about)

     1  package typesutil_test
     2  
     3  import (
     4  	"fmt"
     5  
     6  	goast "go/ast"
     7  	goformat "go/format"
     8  	goparser "go/parser"
     9  
    10  	"go/constant"
    11  	"go/importer"
    12  	"go/types"
    13  	"sort"
    14  	"strings"
    15  	"testing"
    16  	"unsafe"
    17  
    18  	"github.com/goplus/gogen"
    19  	"github.com/goplus/gop"
    20  	"github.com/goplus/gop/ast"
    21  	"github.com/goplus/gop/format"
    22  	"github.com/goplus/gop/parser"
    23  	"github.com/goplus/gop/token"
    24  	"github.com/goplus/gop/x/typesutil"
    25  	"github.com/goplus/mod/env"
    26  	"github.com/goplus/mod/gopmod"
    27  	"github.com/goplus/mod/modfile"
    28  	"github.com/goplus/mod/modload"
    29  )
    30  
    31  var spxProject = &modfile.Project{
    32  	Ext: ".tgmx", Class: "*MyGame",
    33  	Works:    []*modfile.Class{{Ext: ".tspx", Class: "Sprite"}},
    34  	PkgPaths: []string{"github.com/goplus/gop/cl/internal/spx", "math"}}
    35  
    36  var spxMod *gopmod.Module
    37  
    38  func init() {
    39  	spxMod = gopmod.New(modload.Default)
    40  	spxMod.Opt.Projects = append(spxMod.Opt.Projects, spxProject)
    41  	spxMod.ImportClasses()
    42  }
    43  
    44  func lookupClass(ext string) (c *modfile.Project, ok bool) {
    45  	switch ext {
    46  	case ".tgmx", ".tspx":
    47  		return spxProject, true
    48  	}
    49  	return
    50  }
    51  
    52  func spxParserConf() parser.Config {
    53  	return parser.Config{
    54  		ClassKind: func(fname string) (isProj bool, ok bool) {
    55  			ext := modfile.ClassExt(fname)
    56  			c, ok := lookupClass(ext)
    57  			if ok {
    58  				isProj = c.IsProj(ext, fname)
    59  			}
    60  			return
    61  		},
    62  	}
    63  }
    64  
    65  func parseMixedSource(mod *gopmod.Module, fset *token.FileSet, name, src string, goname string, gosrc string, parserConf parser.Config, updateGoTypesOverload bool) (*types.Package, *typesutil.Info, *types.Info, error) {
    66  	f, err := parser.ParseEntry(fset, name, src, parserConf)
    67  	if err != nil {
    68  		return nil, nil, nil, err
    69  	}
    70  	var gofiles []*goast.File
    71  	if len(gosrc) > 0 {
    72  		f, err := goparser.ParseFile(fset, goname, gosrc, goparser.ParseComments)
    73  		if err != nil {
    74  			return nil, nil, nil, err
    75  		}
    76  		gofiles = append(gofiles, f)
    77  	}
    78  
    79  	conf := &types.Config{}
    80  	conf.Importer = gop.NewImporter(nil, &env.Gop{Root: "../..", Version: "1.0"}, fset)
    81  	chkOpts := &typesutil.Config{
    82  		Types:                 types.NewPackage("main", f.Name.Name),
    83  		Fset:                  fset,
    84  		Mod:                   mod,
    85  		UpdateGoTypesOverload: updateGoTypesOverload,
    86  	}
    87  	info := &typesutil.Info{
    88  		Types:      make(map[ast.Expr]types.TypeAndValue),
    89  		Defs:       make(map[*ast.Ident]types.Object),
    90  		Uses:       make(map[*ast.Ident]types.Object),
    91  		Implicits:  make(map[ast.Node]types.Object),
    92  		Selections: make(map[*ast.SelectorExpr]*types.Selection),
    93  		Scopes:     make(map[ast.Node]*types.Scope),
    94  		Overloads:  make(map[*ast.Ident][]types.Object),
    95  	}
    96  	ginfo := &types.Info{
    97  		Types:      make(map[goast.Expr]types.TypeAndValue),
    98  		Defs:       make(map[*goast.Ident]types.Object),
    99  		Uses:       make(map[*goast.Ident]types.Object),
   100  		Implicits:  make(map[goast.Node]types.Object),
   101  		Selections: make(map[*goast.SelectorExpr]*types.Selection),
   102  		Scopes:     make(map[goast.Node]*types.Scope),
   103  	}
   104  	check := typesutil.NewChecker(conf, chkOpts, ginfo, info)
   105  	err = check.Files(gofiles, []*ast.File{f})
   106  	return chkOpts.Types, info, ginfo, err
   107  }
   108  
   109  func parseSource(fset *token.FileSet, filename string, src interface{}, mode parser.Mode) (*types.Package, *typesutil.Info, error) {
   110  	f, err := parser.ParseEntry(fset, filename, src, parser.Config{
   111  		Mode: mode,
   112  	})
   113  	if err != nil {
   114  		return nil, nil, err
   115  	}
   116  
   117  	pkg := types.NewPackage("", f.Name.Name)
   118  	conf := &types.Config{}
   119  	conf.Importer = importer.Default()
   120  	chkOpts := &typesutil.Config{
   121  		Types: pkg,
   122  		Fset:  fset,
   123  		Mod:   gopmod.Default,
   124  	}
   125  	info := &typesutil.Info{
   126  		Types:      make(map[ast.Expr]types.TypeAndValue),
   127  		Defs:       make(map[*ast.Ident]types.Object),
   128  		Uses:       make(map[*ast.Ident]types.Object),
   129  		Implicits:  make(map[ast.Node]types.Object),
   130  		Selections: make(map[*ast.SelectorExpr]*types.Selection),
   131  		Scopes:     make(map[ast.Node]*types.Scope),
   132  		Overloads:  make(map[*ast.Ident][]types.Object),
   133  	}
   134  	check := typesutil.NewChecker(conf, chkOpts, nil, info)
   135  	err = check.Files(nil, []*ast.File{f})
   136  	return pkg, info, err
   137  }
   138  
   139  func parseGoSource(fset *token.FileSet, filename string, src interface{}, mode goparser.Mode) (*types.Package, *types.Info, error) {
   140  	f, err := goparser.ParseFile(fset, filename, src, mode)
   141  	if err != nil {
   142  		return nil, nil, err
   143  	}
   144  
   145  	conf := &types.Config{}
   146  	conf.Importer = importer.Default()
   147  	info := &types.Info{
   148  		Types:      make(map[goast.Expr]types.TypeAndValue),
   149  		Defs:       make(map[*goast.Ident]types.Object),
   150  		Uses:       make(map[*goast.Ident]types.Object),
   151  		Implicits:  make(map[goast.Node]types.Object),
   152  		Selections: make(map[*goast.SelectorExpr]*types.Selection),
   153  		Scopes:     make(map[goast.Node]*types.Scope),
   154  	}
   155  	pkg := types.NewPackage("", f.Name.Name)
   156  	check := types.NewChecker(conf, fset, pkg, info)
   157  	err = check.Files([]*goast.File{f})
   158  	return pkg, info, err
   159  }
   160  
   161  func testGopInfo(t *testing.T, src string, gosrc string, expect string) {
   162  	testGopInfoEx(t, gopmod.Default, "main.gop", src, "main.go", gosrc, expect, parser.Config{})
   163  }
   164  
   165  func testSpxInfo(t *testing.T, name string, src string, expect string) {
   166  	testGopInfoEx(t, spxMod, name, src, "main.go", "", expect, spxParserConf())
   167  }
   168  
   169  func testGopInfoEx(t *testing.T, mod *gopmod.Module, name string, src string, goname string, gosrc string, expect string, parseConf parser.Config) {
   170  	fset := token.NewFileSet()
   171  	_, info, _, err := parseMixedSource(mod, fset, name, src, goname, gosrc, parseConf, false)
   172  	if err != nil {
   173  		t.Fatal("parserMixedSource error", err)
   174  	}
   175  	var list []string
   176  	list = append(list, "== types ==")
   177  	list = append(list, typesList(fset, info.Types, false)...)
   178  	list = append(list, "== defs ==")
   179  	list = append(list, defsList(fset, info.Defs, true)...)
   180  	list = append(list, "== uses ==")
   181  	list = append(list, usesList(fset, info.Uses)...)
   182  	result := strings.Join(list, "\n")
   183  	t.Log(result)
   184  	if result != expect {
   185  		t.Fatal("bad expect\n", expect)
   186  	}
   187  }
   188  
   189  func testInfo(t *testing.T, src interface{}) {
   190  	fset := token.NewFileSet()
   191  	_, info, err := parseSource(fset, "main.gop", src, parser.ParseComments)
   192  	if err != nil {
   193  		t.Fatal("parserSource error", err)
   194  	}
   195  	_, goinfo, err := parseGoSource(fset, "main.go", src, goparser.ParseComments)
   196  	if err != nil {
   197  		t.Fatal("parserGoSource error", err)
   198  	}
   199  	testItems(t, "types", typesList(fset, info.Types, true), goTypesList(fset, goinfo.Types, true))
   200  	testItems(t, "defs", defsList(fset, info.Defs, true), goDefsList(fset, goinfo.Defs, true))
   201  	testItems(t, "uses", usesList(fset, info.Uses), goUsesList(fset, goinfo.Uses))
   202  	// TODO check selections
   203  	//testItems(t, "selections", selectionList(fset, info.Selections), goSelectionList(fset, goinfo.Selections))
   204  }
   205  
   206  func testItems(t *testing.T, name string, items []string, goitems []string) {
   207  	text := strings.Join(items, "\n")
   208  	gotext := strings.Join(goitems, "\n")
   209  	if len(items) != len(goitems) || text != gotext {
   210  		t.Errorf(`====== check %v error (Go+ count: %v, Go count %v) ====== 
   211  ------ Go+ ------
   212  %v
   213  ------ Go ------
   214  %v
   215  `,
   216  			name, len(items), len(goitems),
   217  			text, gotext)
   218  	} else {
   219  		t.Logf(`====== check %v pass (count: %v) ======
   220  %v
   221  `, name, len(items), text)
   222  	}
   223  }
   224  
   225  func sortItems(items []string) []string {
   226  	sort.Strings(items)
   227  	for i := 0; i < len(items); i++ {
   228  		items[i] = fmt.Sprintf("%03v: %v", i, items[i])
   229  	}
   230  	return items
   231  }
   232  
   233  func typesList(fset *token.FileSet, types map[ast.Expr]types.TypeAndValue, skipBasicLit bool) []string {
   234  	var items []string
   235  	for expr, tv := range types {
   236  		var buf strings.Builder
   237  		posn := fset.Position(expr.Pos())
   238  		tvstr := tv.Type.String()
   239  		if skipBasicLit {
   240  			if t, ok := expr.(*ast.BasicLit); ok {
   241  				tvstr = t.Kind.String()
   242  			}
   243  		}
   244  		if tv.Value != nil {
   245  			tvstr += " = " + tv.Value.String()
   246  		}
   247  		// line:col | expr | mode : type = value
   248  		fmt.Fprintf(&buf, "%2d:%2d | %-19s %-30T | %-7s : %s | %v",
   249  			posn.Line, posn.Column, exprString(fset, expr), expr,
   250  			mode(tv), tvstr, (*TypeAndValue)(unsafe.Pointer(&tv)).mode)
   251  		items = append(items, buf.String())
   252  	}
   253  	return sortItems(items)
   254  }
   255  
   256  func goTypesList(fset *token.FileSet, types map[goast.Expr]types.TypeAndValue, skipBasicLit bool) []string {
   257  	var items []string
   258  	for expr, tv := range types {
   259  		var buf strings.Builder
   260  		posn := fset.Position(expr.Pos())
   261  		tvstr := tv.Type.String()
   262  		if skipBasicLit {
   263  			if t, ok := expr.(*goast.BasicLit); ok {
   264  				tvstr = t.Kind.String()
   265  			}
   266  		}
   267  		if tv.Value != nil {
   268  			tvstr += " = " + tv.Value.String()
   269  		}
   270  		// line:col | expr | mode : type = value
   271  		fmt.Fprintf(&buf, "%2d:%2d | %-19s %-30T | %-7s : %s | %v",
   272  			posn.Line, posn.Column, goexprString(fset, expr), expr,
   273  			mode(tv), tvstr, (*TypeAndValue)(unsafe.Pointer(&tv)).mode)
   274  		items = append(items, buf.String())
   275  	}
   276  	return sortItems(items)
   277  }
   278  
   279  func defsList(fset *token.FileSet, uses map[*ast.Ident]types.Object, skipNil bool) []string {
   280  	var items []string
   281  	for expr, obj := range uses {
   282  		if skipNil && obj == nil {
   283  			continue
   284  		}
   285  		var buf strings.Builder
   286  		posn := fset.Position(expr.Pos())
   287  		// line:col | expr | mode : type = value
   288  		fmt.Fprintf(&buf, "%2d:%2d | %-19s | %s",
   289  			posn.Line, posn.Column, expr,
   290  			obj)
   291  		items = append(items, buf.String())
   292  	}
   293  	return sortItems(items)
   294  }
   295  
   296  func goDefsList(fset *token.FileSet, uses map[*goast.Ident]types.Object, skipNil bool) []string {
   297  	var items []string
   298  	for expr, obj := range uses {
   299  		if skipNil && obj == nil {
   300  			continue // skip nil object
   301  		}
   302  		var buf strings.Builder
   303  		posn := fset.Position(expr.Pos())
   304  		// line:col | expr | mode : type = value
   305  		fmt.Fprintf(&buf, "%2d:%2d | %-19s | %s",
   306  			posn.Line, posn.Column, expr,
   307  			obj)
   308  		items = append(items, buf.String())
   309  	}
   310  	return sortItems(items)
   311  }
   312  
   313  func usesList(fset *token.FileSet, uses map[*ast.Ident]types.Object) []string {
   314  	var items []string
   315  	for expr, obj := range uses {
   316  		var buf strings.Builder
   317  		posn := fset.Position(expr.Pos())
   318  		// line:col | expr | mode : type = value
   319  		fmt.Fprintf(&buf, "%2d:%2d | %-19s | %s",
   320  			posn.Line, posn.Column, expr,
   321  			obj)
   322  		items = append(items, buf.String())
   323  	}
   324  	return sortItems(items)
   325  }
   326  
   327  func goUsesList(fset *token.FileSet, uses map[*goast.Ident]types.Object) []string {
   328  	var items []string
   329  	for expr, obj := range uses {
   330  		if obj == nil {
   331  			continue // skip nil object
   332  		}
   333  		var buf strings.Builder
   334  		posn := fset.Position(expr.Pos())
   335  		// line:col | expr | mode : type = value
   336  		fmt.Fprintf(&buf, "%2d:%2d | %-19s | %s",
   337  			posn.Line, posn.Column, expr,
   338  			obj)
   339  		items = append(items, buf.String())
   340  	}
   341  	return sortItems(items)
   342  }
   343  
   344  /*
   345  func selectionList(fset *token.FileSet, sels map[*ast.SelectorExpr]*types.Selection) []string {
   346  	var items []string
   347  	for expr, sel := range sels {
   348  		var buf strings.Builder
   349  		posn := fset.Position(expr.Pos())
   350  		// line:col | expr | mode : type = value
   351  		fmt.Fprintf(&buf, "%2d:%2d | %-19s | %s",
   352  			posn.Line, posn.Column, exprString(fset, expr),
   353  			sel)
   354  		items = append(items, buf.String())
   355  	}
   356  	return sortItems(items)
   357  }
   358  
   359  func goSelectionList(fset *token.FileSet, sels map[*goast.SelectorExpr]*types.Selection) []string {
   360  	var items []string
   361  	for expr, sel := range sels {
   362  		var buf strings.Builder
   363  		posn := fset.Position(expr.Pos())
   364  		// line:col | expr | mode : type = value
   365  		fmt.Fprintf(&buf, "%2d:%2d | %-19s | %s",
   366  			posn.Line, posn.Column, goexprString(fset, expr),
   367  			sel)
   368  		items = append(items, buf.String())
   369  	}
   370  	return sortItems(items)
   371  }
   372  */
   373  
   374  func mode(tv types.TypeAndValue) string {
   375  	switch {
   376  	case tv.IsVoid():
   377  		return "void"
   378  	case tv.IsType():
   379  		return "type"
   380  	case tv.IsBuiltin():
   381  		return "builtin"
   382  	case tv.IsNil():
   383  		return "nil"
   384  	case tv.Assignable():
   385  		if tv.Addressable() {
   386  			return "var"
   387  		}
   388  		return "mapindex"
   389  	case tv.IsValue():
   390  		return "value"
   391  	default:
   392  		return "unknown"
   393  	}
   394  }
   395  
   396  func exprString(fset *token.FileSet, expr ast.Expr) string {
   397  	var buf strings.Builder
   398  	format.Node(&buf, fset, expr)
   399  	return buf.String()
   400  }
   401  
   402  func goexprString(fset *token.FileSet, expr goast.Expr) string {
   403  	var buf strings.Builder
   404  	goformat.Node(&buf, fset, expr)
   405  	return buf.String()
   406  }
   407  
   408  type operandMode byte
   409  
   410  const (
   411  	invalid   operandMode = iota // operand is invalid
   412  	novalue                      // operand represents no value (result of a function call w/o result)
   413  	builtin                      // operand is a built-in function
   414  	typexpr                      // operand is a type
   415  	constant_                    // operand is a constant; the operand's typ is a Basic type
   416  	variable                     // operand is an addressable variable
   417  	mapindex                     // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
   418  	value                        // operand is a computed value
   419  	commaok                      // like value, but operand may be used in a comma,ok expression
   420  	commaerr                     // like commaok, but second value is error, not boolean
   421  	cgofunc                      // operand is a cgo function
   422  )
   423  
   424  func (v operandMode) String() string {
   425  	return operandModeString[int(v)]
   426  }
   427  
   428  var operandModeString = [...]string{
   429  	invalid:   "invalid operand",
   430  	novalue:   "no value",
   431  	builtin:   "built-in",
   432  	typexpr:   "type",
   433  	constant_: "constant",
   434  	variable:  "variable",
   435  	mapindex:  "map index expression",
   436  	value:     "value",
   437  	commaok:   "comma, ok expression",
   438  	commaerr:  "comma, error expression",
   439  	cgofunc:   "cgo function",
   440  }
   441  
   442  type TypeAndValue struct {
   443  	mode  operandMode
   444  	Type  types.Type
   445  	Value constant.Value
   446  }
   447  
   448  func TestVarTypes(t *testing.T) {
   449  	testInfo(t, `package main
   450  type T struct {
   451  	x int
   452  	y int
   453  }
   454  var v *int = nil
   455  var v1 []int
   456  var v2 map[int8]string
   457  var v3 struct{}
   458  var v4 *T = &T{100,200}
   459  var v5 = [6]int{}
   460  var v6 = v5[0]
   461  var v7 = [6]int{}[0]
   462  var m map[int]string
   463  func init() {
   464  	v5[0] = 100
   465  	_ = v5[:][0]
   466  	m[0] = "hello"
   467  	_ = m[0]
   468  	_ = map[int]string{}[0]
   469  	_ = &v3
   470  	_ = *(&v3)
   471  	a := []int{1,2,3,4,5}[0]
   472  	_ = a
   473  }
   474  `)
   475  }
   476  
   477  func TestStruct(t *testing.T) {
   478  	testInfo(t, `package main
   479  import "fmt"
   480  
   481  type Person struct {
   482  	name string
   483  	age  int8
   484  }
   485  
   486  func test() {
   487  	p := Person{
   488  		name: "jack",
   489  	}
   490  	_ = p.name
   491  	p.name = "name"
   492  	fmt.Println(p)
   493  }
   494  `)
   495  }
   496  
   497  func TestTypeAssert(t *testing.T) {
   498  	testInfo(t, `package main
   499  
   500  func test() {
   501  	var a interface{} = 100
   502  	if n, ok := a.(int); ok {
   503  		_ = n
   504  	}
   505  }
   506  `)
   507  }
   508  
   509  func TestChan(t *testing.T) {
   510  	testInfo(t, `package main
   511  
   512  func test() {
   513  	var ch chan int
   514  	select {
   515  	case n, ok := <-ch:
   516  		_ = n
   517  		_ = ok
   518  		break
   519  	}
   520  }
   521  `)
   522  }
   523  
   524  func TestRange(t *testing.T) {
   525  	testInfo(t, `package main
   526  func test() {
   527  	a := []int{100,200}
   528  	for k, v := range a {
   529  		_ = k
   530  		_ = v
   531  	}
   532  	var m map[int]string
   533  	for k, v := range m {
   534  		_ = k
   535  		_ = v
   536  	}
   537  	for v := range m {
   538  		_ = v
   539  	}
   540  }
   541  `)
   542  }
   543  
   544  func TestFuncLit(t *testing.T) {
   545  	testInfo(t, `package main
   546  func test() {
   547  	add := func(n1 int, n2 int) int {
   548  		return n1+n2
   549  	}
   550  	_ = add(1,2)
   551  
   552  	go func(n int) {
   553  		_ = n+100
   554  	}(100)
   555  }
   556  `)
   557  }
   558  
   559  func TestSliceLit(t *testing.T) {
   560  	testGopInfo(t, `
   561  a := [100,200]
   562  println a
   563  `, ``, `== types ==
   564  000:  2: 7 | 100                 *ast.BasicLit                  | value   : untyped int = 100 | constant
   565  001:  2:11 | 200                 *ast.BasicLit                  | value   : untyped int = 200 | constant
   566  002:  3: 1 | println             *ast.Ident                     | value   : func(a ...any) (n int, err error) | value
   567  003:  3: 1 | println a           *ast.CallExpr                  | value   : (n int, err error) | value
   568  004:  3: 9 | a                   *ast.Ident                     | var     : []int | variable
   569  == defs ==
   570  000:  2: 1 | a                   | var a []int
   571  001:  2: 1 | main                | func main.main()
   572  == uses ==
   573  000:  3: 1 | println             | func fmt.Println(a ...any) (n int, err error)
   574  001:  3: 9 | a                   | var a []int`)
   575  }
   576  
   577  func TestForPhrase1(t *testing.T) {
   578  	testGopInfo(t, `
   579  sum := 0
   580  for x <- [1, 3, 5, 7, 11, 13, 17], x > 3 {
   581  	sum = sum + x
   582  }
   583  println sum
   584  `, ``, `== types ==
   585  000:  2: 8 | 0                   *ast.BasicLit                  | value   : untyped int = 0 | constant
   586  001:  3:11 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
   587  002:  3:14 | 3                   *ast.BasicLit                  | value   : untyped int = 3 | constant
   588  003:  3:17 | 5                   *ast.BasicLit                  | value   : untyped int = 5 | constant
   589  004:  3:20 | 7                   *ast.BasicLit                  | value   : untyped int = 7 | constant
   590  005:  3:23 | 11                  *ast.BasicLit                  | value   : untyped int = 11 | constant
   591  006:  3:27 | 13                  *ast.BasicLit                  | value   : untyped int = 13 | constant
   592  007:  3:31 | 17                  *ast.BasicLit                  | value   : untyped int = 17 | constant
   593  008:  3:36 | x                   *ast.Ident                     | var     : int | variable
   594  009:  3:36 | x > 3               *ast.BinaryExpr                | value   : untyped bool | value
   595  010:  3:40 | 3                   *ast.BasicLit                  | value   : untyped int = 3 | constant
   596  011:  4: 2 | sum                 *ast.Ident                     | var     : int | variable
   597  012:  4: 8 | sum                 *ast.Ident                     | var     : int | variable
   598  013:  4: 8 | sum + x             *ast.BinaryExpr                | value   : int | value
   599  014:  4:14 | x                   *ast.Ident                     | var     : int | variable
   600  015:  6: 1 | println             *ast.Ident                     | value   : func(a ...any) (n int, err error) | value
   601  016:  6: 1 | println sum         *ast.CallExpr                  | value   : (n int, err error) | value
   602  017:  6: 9 | sum                 *ast.Ident                     | var     : int | variable
   603  == defs ==
   604  000:  2: 1 | main                | func main.main()
   605  001:  2: 1 | sum                 | var sum int
   606  002:  3: 5 | x                   | var x int
   607  == uses ==
   608  000:  3:36 | x                   | var x int
   609  001:  4: 2 | sum                 | var sum int
   610  002:  4: 8 | sum                 | var sum int
   611  003:  4:14 | x                   | var x int
   612  004:  6: 1 | println             | func fmt.Println(a ...any) (n int, err error)
   613  005:  6: 9 | sum                 | var sum int`)
   614  }
   615  
   616  func TestForPhrase2(t *testing.T) {
   617  	testGopInfo(t, `
   618  sum := 0
   619  for i, x <- [1, 3, 5, 7, 11, 13, 17], i%2 == 1 && x > 3 {
   620  	sum = sum + x
   621  }
   622  println sum
   623  `, ``, `== types ==
   624  000:  2: 8 | 0                   *ast.BasicLit                  | value   : untyped int = 0 | constant
   625  001:  3:14 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
   626  002:  3:17 | 3                   *ast.BasicLit                  | value   : untyped int = 3 | constant
   627  003:  3:20 | 5                   *ast.BasicLit                  | value   : untyped int = 5 | constant
   628  004:  3:23 | 7                   *ast.BasicLit                  | value   : untyped int = 7 | constant
   629  005:  3:26 | 11                  *ast.BasicLit                  | value   : untyped int = 11 | constant
   630  006:  3:30 | 13                  *ast.BasicLit                  | value   : untyped int = 13 | constant
   631  007:  3:34 | 17                  *ast.BasicLit                  | value   : untyped int = 17 | constant
   632  008:  3:39 | i                   *ast.Ident                     | var     : int | variable
   633  009:  3:39 | i % 2               *ast.BinaryExpr                | value   : int | value
   634  010:  3:39 | i%2 == 1            *ast.BinaryExpr                | value   : untyped bool | value
   635  011:  3:39 | i%2 == 1 && x > 3   *ast.BinaryExpr                | value   : untyped bool | value
   636  012:  3:41 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
   637  013:  3:46 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
   638  014:  3:51 | x                   *ast.Ident                     | var     : int | variable
   639  015:  3:51 | x > 3               *ast.BinaryExpr                | value   : untyped bool | value
   640  016:  3:55 | 3                   *ast.BasicLit                  | value   : untyped int = 3 | constant
   641  017:  4: 2 | sum                 *ast.Ident                     | var     : int | variable
   642  018:  4: 8 | sum                 *ast.Ident                     | var     : int | variable
   643  019:  4: 8 | sum + x             *ast.BinaryExpr                | value   : int | value
   644  020:  4:14 | x                   *ast.Ident                     | var     : int | variable
   645  021:  6: 1 | println             *ast.Ident                     | value   : func(a ...any) (n int, err error) | value
   646  022:  6: 1 | println sum         *ast.CallExpr                  | value   : (n int, err error) | value
   647  023:  6: 9 | sum                 *ast.Ident                     | var     : int | variable
   648  == defs ==
   649  000:  2: 1 | main                | func main.main()
   650  001:  2: 1 | sum                 | var sum int
   651  002:  3: 5 | i                   | var i int
   652  003:  3: 8 | x                   | var x int
   653  == uses ==
   654  000:  3:39 | i                   | var i int
   655  001:  3:51 | x                   | var x int
   656  002:  4: 2 | sum                 | var sum int
   657  003:  4: 8 | sum                 | var sum int
   658  004:  4:14 | x                   | var x int
   659  005:  6: 1 | println             | func fmt.Println(a ...any) (n int, err error)
   660  006:  6: 9 | sum                 | var sum int`)
   661  }
   662  
   663  func TestMapComprehension(t *testing.T) {
   664  	testGopInfo(t, `
   665  y := {x: i for i, x <- ["1", "3", "5", "7", "11"]}
   666  println y
   667  `, ``, `== types ==
   668  000:  2: 7 | x                   *ast.Ident                     | var     : string | variable
   669  001:  2:10 | i                   *ast.Ident                     | var     : int | variable
   670  002:  2:25 | "1"                 *ast.BasicLit                  | value   : untyped string = "1" | constant
   671  003:  2:30 | "3"                 *ast.BasicLit                  | value   : untyped string = "3" | constant
   672  004:  2:35 | "5"                 *ast.BasicLit                  | value   : untyped string = "5" | constant
   673  005:  2:40 | "7"                 *ast.BasicLit                  | value   : untyped string = "7" | constant
   674  006:  2:45 | "11"                *ast.BasicLit                  | value   : untyped string = "11" | constant
   675  007:  3: 1 | println             *ast.Ident                     | value   : func(a ...any) (n int, err error) | value
   676  008:  3: 1 | println y           *ast.CallExpr                  | value   : (n int, err error) | value
   677  009:  3: 9 | y                   *ast.Ident                     | var     : map[string]int | variable
   678  == defs ==
   679  000:  2: 1 | main                | func main.main()
   680  001:  2: 1 | y                   | var y map[string]int
   681  002:  2:16 | i                   | var i int
   682  003:  2:19 | x                   | var x string
   683  == uses ==
   684  000:  2: 7 | x                   | var x string
   685  001:  2:10 | i                   | var i int
   686  002:  3: 1 | println             | func fmt.Println(a ...any) (n int, err error)
   687  003:  3: 9 | y                   | var y map[string]int`)
   688  }
   689  
   690  func TestListComprehension(t *testing.T) {
   691  	testGopInfo(t, `
   692  a := [1, 3.4, 5]
   693  b := [x*x for x <- a]
   694  _ = b
   695  `, ``, `== types ==
   696  000:  2: 7 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
   697  001:  2:10 | 3.4                 *ast.BasicLit                  | value   : untyped float = 3.4 | constant
   698  002:  2:15 | 5                   *ast.BasicLit                  | value   : untyped int = 5 | constant
   699  003:  3: 7 | x                   *ast.Ident                     | var     : float64 | variable
   700  004:  3: 7 | x * x               *ast.BinaryExpr                | value   : float64 | value
   701  005:  3: 9 | x                   *ast.Ident                     | var     : float64 | variable
   702  006:  3:20 | a                   *ast.Ident                     | var     : []float64 | variable
   703  007:  4: 5 | b                   *ast.Ident                     | var     : []float64 | variable
   704  == defs ==
   705  000:  2: 1 | a                   | var a []float64
   706  001:  2: 1 | main                | func main.main()
   707  002:  3: 1 | b                   | var b []float64
   708  003:  3:15 | x                   | var x float64
   709  == uses ==
   710  000:  3: 7 | x                   | var x float64
   711  001:  3: 9 | x                   | var x float64
   712  002:  3:20 | a                   | var a []float64
   713  003:  4: 5 | b                   | var b []float64`)
   714  }
   715  
   716  func TestListComprehensionMultiLevel(t *testing.T) {
   717  	testGopInfo(t, `
   718  arr := [1, 2, 3, 4.1, 5, 6]
   719  x := [[a, b] for a <- arr, a < b for b <- arr, b > 2]
   720  println("x:", x)
   721  `, ``, `== types ==
   722  000:  2: 9 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
   723  001:  2:12 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
   724  002:  2:15 | 3                   *ast.BasicLit                  | value   : untyped int = 3 | constant
   725  003:  2:18 | 4.1                 *ast.BasicLit                  | value   : untyped float = 4.1 | constant
   726  004:  2:23 | 5                   *ast.BasicLit                  | value   : untyped int = 5 | constant
   727  005:  2:26 | 6                   *ast.BasicLit                  | value   : untyped int = 6 | constant
   728  006:  3: 8 | a                   *ast.Ident                     | var     : float64 | variable
   729  007:  3:11 | b                   *ast.Ident                     | var     : float64 | variable
   730  008:  3:23 | arr                 *ast.Ident                     | var     : []float64 | variable
   731  009:  3:28 | a                   *ast.Ident                     | var     : float64 | variable
   732  010:  3:28 | a < b               *ast.BinaryExpr                | value   : untyped bool | value
   733  011:  3:32 | b                   *ast.Ident                     | var     : float64 | variable
   734  012:  3:43 | arr                 *ast.Ident                     | var     : []float64 | variable
   735  013:  3:48 | b                   *ast.Ident                     | var     : float64 | variable
   736  014:  3:48 | b > 2               *ast.BinaryExpr                | value   : untyped bool | value
   737  015:  3:52 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
   738  016:  4: 1 | println             *ast.Ident                     | value   : func(a ...any) (n int, err error) | value
   739  017:  4: 1 | println("x:", x)    *ast.CallExpr                  | value   : (n int, err error) | value
   740  018:  4: 9 | "x:"                *ast.BasicLit                  | value   : untyped string = "x:" | constant
   741  019:  4:15 | x                   *ast.Ident                     | var     : [][]float64 | variable
   742  == defs ==
   743  000:  2: 1 | arr                 | var arr []float64
   744  001:  2: 1 | main                | func main.main()
   745  002:  3: 1 | x                   | var x [][]float64
   746  003:  3:18 | a                   | var a float64
   747  004:  3:38 | b                   | var b float64
   748  == uses ==
   749  000:  3: 8 | a                   | var a float64
   750  001:  3:11 | b                   | var b float64
   751  002:  3:23 | arr                 | var arr []float64
   752  003:  3:28 | a                   | var a float64
   753  004:  3:32 | b                   | var b float64
   754  005:  3:43 | arr                 | var arr []float64
   755  006:  3:48 | b                   | var b float64
   756  007:  4: 1 | println             | func fmt.Println(a ...any) (n int, err error)
   757  008:  4:15 | x                   | var x [][]float64`)
   758  }
   759  
   760  func TestFileEnumLines(t *testing.T) {
   761  	testGopInfo(t, `
   762  import "os"
   763  
   764  for line <- os.Stdin {
   765  	println line
   766  }
   767  `, ``, `== types ==
   768  000:  4:13 | os.Stdin            *ast.SelectorExpr              | var     : *os.File | variable
   769  001:  5: 2 | println             *ast.Ident                     | value   : func(a ...any) (n int, err error) | value
   770  002:  5: 2 | println line        *ast.CallExpr                  | value   : (n int, err error) | value
   771  003:  5:10 | line                *ast.Ident                     | var     : string | variable
   772  == defs ==
   773  000:  4: 1 | main                | func main.main()
   774  001:  4: 5 | line                | var line string
   775  == uses ==
   776  000:  4:13 | os                  | package os
   777  001:  4:16 | Stdin               | var os.Stdin *os.File
   778  002:  5: 2 | println             | func fmt.Println(a ...any) (n int, err error)
   779  003:  5:10 | line                | var line string`)
   780  }
   781  
   782  func TestLambdaExpr(t *testing.T) {
   783  	testGopInfo(t, `package main
   784  func Map(c []float64, t func(float64) float64) {
   785  	// ...
   786  }
   787  
   788  func Map2(c []float64, t func(float64) (float64, float64)) {
   789  	// ...
   790  }
   791  
   792  Map([1.2, 3.5, 6], x => x * x)
   793  Map2([1.2, 3.5, 6], x => (x * x, x + x))
   794  `, ``, `== types ==
   795  000:  2:12 | []float64           *ast.ArrayType                 | type    : []float64 | type
   796  001:  2:14 | float64             *ast.Ident                     | type    : float64 | type
   797  002:  2:25 | func(float64) float64 *ast.FuncType                  | type    : func(float64) float64 | type
   798  003:  2:30 | float64             *ast.Ident                     | type    : float64 | type
   799  004:  2:39 | float64             *ast.Ident                     | type    : float64 | type
   800  005:  6:13 | []float64           *ast.ArrayType                 | type    : []float64 | type
   801  006:  6:15 | float64             *ast.Ident                     | type    : float64 | type
   802  007:  6:26 | func(float64) (float64, float64) *ast.FuncType                  | type    : func(float64) (float64, float64) | type
   803  008:  6:31 | float64             *ast.Ident                     | type    : float64 | type
   804  009:  6:41 | float64             *ast.Ident                     | type    : float64 | type
   805  010:  6:50 | float64             *ast.Ident                     | type    : float64 | type
   806  011: 10: 1 | Map                 *ast.Ident                     | value   : func(c []float64, t func(float64) float64) | value
   807  012: 10: 1 | Map([1.2, 3.5, 6], x => x * x) *ast.CallExpr                  | void    : () | no value
   808  013: 10: 6 | 1.2                 *ast.BasicLit                  | value   : untyped float = 1.2 | constant
   809  014: 10:11 | 3.5                 *ast.BasicLit                  | value   : untyped float = 3.5 | constant
   810  015: 10:16 | 6                   *ast.BasicLit                  | value   : untyped int = 6 | constant
   811  016: 10:25 | x                   *ast.Ident                     | var     : float64 | variable
   812  017: 10:25 | x * x               *ast.BinaryExpr                | value   : float64 | value
   813  018: 10:29 | x                   *ast.Ident                     | var     : float64 | variable
   814  019: 11: 1 | Map2                *ast.Ident                     | value   : func(c []float64, t func(float64) (float64, float64)) | value
   815  020: 11: 1 | Map2([1.2, 3.5, 6], x => (x * x, x + x)) *ast.CallExpr                  | void    : () | no value
   816  021: 11: 7 | 1.2                 *ast.BasicLit                  | value   : untyped float = 1.2 | constant
   817  022: 11:12 | 3.5                 *ast.BasicLit                  | value   : untyped float = 3.5 | constant
   818  023: 11:17 | 6                   *ast.BasicLit                  | value   : untyped int = 6 | constant
   819  024: 11:27 | x                   *ast.Ident                     | var     : float64 | variable
   820  025: 11:27 | x * x               *ast.BinaryExpr                | value   : float64 | value
   821  026: 11:31 | x                   *ast.Ident                     | var     : float64 | variable
   822  027: 11:34 | x                   *ast.Ident                     | var     : float64 | variable
   823  028: 11:34 | x + x               *ast.BinaryExpr                | value   : float64 | value
   824  029: 11:38 | x                   *ast.Ident                     | var     : float64 | variable
   825  == defs ==
   826  000:  2: 6 | Map                 | func main.Map(c []float64, t func(float64) float64)
   827  001:  2:10 | c                   | var c []float64
   828  002:  2:23 | t                   | var t func(float64) float64
   829  003:  6: 6 | Map2                | func main.Map2(c []float64, t func(float64) (float64, float64))
   830  004:  6:11 | c                   | var c []float64
   831  005:  6:24 | t                   | var t func(float64) (float64, float64)
   832  006: 10: 1 | main                | func main.main()
   833  007: 10:20 | x                   | var x float64
   834  008: 11:21 | x                   | var x float64
   835  == uses ==
   836  000:  2:14 | float64             | type float64
   837  001:  2:30 | float64             | type float64
   838  002:  2:39 | float64             | type float64
   839  003:  6:15 | float64             | type float64
   840  004:  6:31 | float64             | type float64
   841  005:  6:41 | float64             | type float64
   842  006:  6:50 | float64             | type float64
   843  007: 10: 1 | Map                 | func main.Map(c []float64, t func(float64) float64)
   844  008: 10:25 | x                   | var x float64
   845  009: 10:29 | x                   | var x float64
   846  010: 11: 1 | Map2                | func main.Map2(c []float64, t func(float64) (float64, float64))
   847  011: 11:27 | x                   | var x float64
   848  012: 11:31 | x                   | var x float64
   849  013: 11:34 | x                   | var x float64
   850  014: 11:38 | x                   | var x float64`)
   851  }
   852  
   853  func TestLambdaExpr2(t *testing.T) {
   854  	testGopInfo(t, `package main
   855  func Map(c []float64, t func(float64) float64) {
   856  	// ...
   857  }
   858  
   859  func Map2(c []float64, t func(float64) (float64, float64)) {
   860  	// ...
   861  }
   862  
   863  Map([1.2, 3.5, 6], x => {
   864  	return x * x
   865  })
   866  Map2([1.2, 3.5, 6], x => {
   867  	return x * x, x + x
   868  })
   869  `, ``, `== types ==
   870  000:  2:12 | []float64           *ast.ArrayType                 | type    : []float64 | type
   871  001:  2:14 | float64             *ast.Ident                     | type    : float64 | type
   872  002:  2:25 | func(float64) float64 *ast.FuncType                  | type    : func(float64) float64 | type
   873  003:  2:30 | float64             *ast.Ident                     | type    : float64 | type
   874  004:  2:39 | float64             *ast.Ident                     | type    : float64 | type
   875  005:  6:13 | []float64           *ast.ArrayType                 | type    : []float64 | type
   876  006:  6:15 | float64             *ast.Ident                     | type    : float64 | type
   877  007:  6:26 | func(float64) (float64, float64) *ast.FuncType                  | type    : func(float64) (float64, float64) | type
   878  008:  6:31 | float64             *ast.Ident                     | type    : float64 | type
   879  009:  6:41 | float64             *ast.Ident                     | type    : float64 | type
   880  010:  6:50 | float64             *ast.Ident                     | type    : float64 | type
   881  011: 10: 1 | Map                 *ast.Ident                     | value   : func(c []float64, t func(float64) float64) | value
   882  012: 10: 1 | Map([1.2, 3.5, 6], x => {
   883  	return x * x
   884  }) *ast.CallExpr                  | void    : () | no value
   885  013: 10: 6 | 1.2                 *ast.BasicLit                  | value   : untyped float = 1.2 | constant
   886  014: 10:11 | 3.5                 *ast.BasicLit                  | value   : untyped float = 3.5 | constant
   887  015: 10:16 | 6                   *ast.BasicLit                  | value   : untyped int = 6 | constant
   888  016: 11: 9 | x                   *ast.Ident                     | var     : float64 | variable
   889  017: 11: 9 | x * x               *ast.BinaryExpr                | value   : float64 | value
   890  018: 11:13 | x                   *ast.Ident                     | var     : float64 | variable
   891  019: 13: 1 | Map2                *ast.Ident                     | value   : func(c []float64, t func(float64) (float64, float64)) | value
   892  020: 13: 1 | Map2([1.2, 3.5, 6], x => {
   893  	return x * x, x + x
   894  }) *ast.CallExpr                  | void    : () | no value
   895  021: 13: 7 | 1.2                 *ast.BasicLit                  | value   : untyped float = 1.2 | constant
   896  022: 13:12 | 3.5                 *ast.BasicLit                  | value   : untyped float = 3.5 | constant
   897  023: 13:17 | 6                   *ast.BasicLit                  | value   : untyped int = 6 | constant
   898  024: 14: 9 | x                   *ast.Ident                     | var     : float64 | variable
   899  025: 14: 9 | x * x               *ast.BinaryExpr                | value   : float64 | value
   900  026: 14:13 | x                   *ast.Ident                     | var     : float64 | variable
   901  027: 14:16 | x                   *ast.Ident                     | var     : float64 | variable
   902  028: 14:16 | x + x               *ast.BinaryExpr                | value   : float64 | value
   903  029: 14:20 | x                   *ast.Ident                     | var     : float64 | variable
   904  == defs ==
   905  000:  2: 6 | Map                 | func main.Map(c []float64, t func(float64) float64)
   906  001:  2:10 | c                   | var c []float64
   907  002:  2:23 | t                   | var t func(float64) float64
   908  003:  6: 6 | Map2                | func main.Map2(c []float64, t func(float64) (float64, float64))
   909  004:  6:11 | c                   | var c []float64
   910  005:  6:24 | t                   | var t func(float64) (float64, float64)
   911  006: 10: 1 | main                | func main.main()
   912  007: 10:20 | x                   | var x float64
   913  008: 13:21 | x                   | var x float64
   914  == uses ==
   915  000:  2:14 | float64             | type float64
   916  001:  2:30 | float64             | type float64
   917  002:  2:39 | float64             | type float64
   918  003:  6:15 | float64             | type float64
   919  004:  6:31 | float64             | type float64
   920  005:  6:41 | float64             | type float64
   921  006:  6:50 | float64             | type float64
   922  007: 10: 1 | Map                 | func main.Map(c []float64, t func(float64) float64)
   923  008: 11: 9 | x                   | var x float64
   924  009: 11:13 | x                   | var x float64
   925  010: 13: 1 | Map2                | func main.Map2(c []float64, t func(float64) (float64, float64))
   926  011: 14: 9 | x                   | var x float64
   927  012: 14:13 | x                   | var x float64
   928  013: 14:16 | x                   | var x float64
   929  014: 14:20 | x                   | var x float64`)
   930  }
   931  
   932  func TestMixedOverload1(t *testing.T) {
   933  	testGopInfo(t, `
   934  type Mesh struct {
   935  }
   936  
   937  func (p *Mesh) Name() string {
   938  	return "hello"
   939  }
   940  
   941  var (
   942  	m1 = &Mesh{}
   943  	m2 = &Mesh{}
   944  )
   945  
   946  OnKey "hello", => {
   947  }
   948  OnKey "hello", key => {
   949  }
   950  OnKey ["1"], => {
   951  }
   952  OnKey ["2"], key => {
   953  }
   954  OnKey [m1, m2], => {
   955  }
   956  OnKey [m1, m2], key => {
   957  }
   958  OnKey ["a"], ["b"], key => {
   959  }
   960  OnKey ["a"], [m1, m2], key => {
   961  }
   962  OnKey ["a"], nil, key => {
   963  }
   964  OnKey 100, 200
   965  OnKey "a", "b", x => x * x, x => {
   966  	return x * 2
   967  }
   968  OnKey "a", "b", 1, 2, 3
   969  OnKey("a", "b", [1, 2, 3]...)
   970  `, `
   971  package main
   972  
   973  type Mesher interface {
   974  	Name() string
   975  }
   976  
   977  type N struct {
   978  }
   979  
   980  func (m *N) OnKey__0(a string, fn func()) {
   981  }
   982  
   983  func (m *N) OnKey__1(a string, fn func(key string)) {
   984  }
   985  
   986  func (m *N) OnKey__2(a []string, fn func()) {
   987  }
   988  
   989  func (m *N) OnKey__3(a []string, fn func(key string)) {
   990  }
   991  
   992  func (m *N) OnKey__4(a []Mesher, fn func()) {
   993  }
   994  
   995  func (m *N) OnKey__5(a []Mesher, fn func(key Mesher)) {
   996  }
   997  
   998  func (m *N) OnKey__6(a []string, b []string, fn func(key string)) {
   999  }
  1000  
  1001  func (m *N) OnKey__7(a []string, b []Mesher, fn func(key string)) {
  1002  }
  1003  
  1004  func (m *N) OnKey__8(x int, y int) {
  1005  }
  1006  
  1007  
  1008  func OnKey__0(a string, fn func()) {
  1009  }
  1010  
  1011  func OnKey__1(a string, fn func(key string)) {
  1012  }
  1013  
  1014  func OnKey__2(a []string, fn func()) {
  1015  }
  1016  
  1017  func OnKey__3(a []string, fn func(key string)) {
  1018  }
  1019  
  1020  func OnKey__4(a []Mesher, fn func()) {
  1021  }
  1022  
  1023  func OnKey__5(a []Mesher, fn func(key Mesher)) {
  1024  }
  1025  
  1026  func OnKey__6(a []string, b []string, fn func(key string)) {
  1027  }
  1028  
  1029  func OnKey__7(a []string, b []Mesher, fn func(key string)) {
  1030  }
  1031  
  1032  func OnKey__8(x int, y int) {
  1033  }
  1034  
  1035  func OnKey__9(a, b string, fn ...func(x int) int) {
  1036  }
  1037  
  1038  func OnKey__a(a, b string, v ...int) {
  1039  }
  1040  `, `== types ==
  1041  000:  2:11 | struct {
  1042  }          *ast.StructType                | type    : struct{} | type
  1043  001:  5:10 | Mesh                *ast.Ident                     | type    : main.Mesh | type
  1044  002:  5:23 | string              *ast.Ident                     | type    : string | type
  1045  003:  6: 9 | "hello"             *ast.BasicLit                  | value   : untyped string = "hello" | constant
  1046  004: 10: 7 | &Mesh{}             *ast.UnaryExpr                 | value   : *main.Mesh | value
  1047  005: 10: 8 | Mesh                *ast.Ident                     | type    : main.Mesh | type
  1048  006: 10: 8 | Mesh{}              *ast.CompositeLit              | value   : main.Mesh | value
  1049  007: 11: 7 | &Mesh{}             *ast.UnaryExpr                 | value   : *main.Mesh | value
  1050  008: 11: 8 | Mesh                *ast.Ident                     | type    : main.Mesh | type
  1051  009: 11: 8 | Mesh{}              *ast.CompositeLit              | value   : main.Mesh | value
  1052  010: 14: 1 | OnKey               *ast.Ident                     | value   : func(a string, fn func()) | value
  1053  011: 14: 1 | OnKey "hello", => {
  1054  } *ast.CallExpr                  | void    : () | no value
  1055  012: 14: 7 | "hello"             *ast.BasicLit                  | value   : untyped string = "hello" | constant
  1056  013: 16: 1 | OnKey               *ast.Ident                     | value   : func(a string, fn func(key string)) | value
  1057  014: 16: 1 | OnKey "hello", key => {
  1058  } *ast.CallExpr                  | void    : () | no value
  1059  015: 16: 7 | "hello"             *ast.BasicLit                  | value   : untyped string = "hello" | constant
  1060  016: 18: 1 | OnKey               *ast.Ident                     | value   : func(a []string, fn func()) | value
  1061  017: 18: 1 | OnKey ["1"], => {
  1062  } *ast.CallExpr                  | void    : () | no value
  1063  018: 18: 8 | "1"                 *ast.BasicLit                  | value   : untyped string = "1" | constant
  1064  019: 20: 1 | OnKey               *ast.Ident                     | value   : func(a []string, fn func(key string)) | value
  1065  020: 20: 1 | OnKey ["2"], key => {
  1066  } *ast.CallExpr                  | void    : () | no value
  1067  021: 20: 8 | "2"                 *ast.BasicLit                  | value   : untyped string = "2" | constant
  1068  022: 22: 1 | OnKey               *ast.Ident                     | value   : func(a []main.Mesher, fn func()) | value
  1069  023: 22: 1 | OnKey [m1, m2], => {
  1070  } *ast.CallExpr                  | void    : () | no value
  1071  024: 22: 8 | m1                  *ast.Ident                     | var     : *main.Mesh | variable
  1072  025: 22:12 | m2                  *ast.Ident                     | var     : *main.Mesh | variable
  1073  026: 24: 1 | OnKey               *ast.Ident                     | value   : func(a []main.Mesher, fn func(key main.Mesher)) | value
  1074  027: 24: 1 | OnKey [m1, m2], key => {
  1075  } *ast.CallExpr                  | void    : () | no value
  1076  028: 24: 8 | m1                  *ast.Ident                     | var     : *main.Mesh | variable
  1077  029: 24:12 | m2                  *ast.Ident                     | var     : *main.Mesh | variable
  1078  030: 26: 1 | OnKey               *ast.Ident                     | value   : func(a []string, b []string, fn func(key string)) | value
  1079  031: 26: 1 | OnKey ["a"], ["b"], key => {
  1080  } *ast.CallExpr                  | void    : () | no value
  1081  032: 26: 8 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1082  033: 26:15 | "b"                 *ast.BasicLit                  | value   : untyped string = "b" | constant
  1083  034: 28: 1 | OnKey               *ast.Ident                     | value   : func(a []string, b []main.Mesher, fn func(key string)) | value
  1084  035: 28: 1 | OnKey ["a"], [m1, m2], key => {
  1085  } *ast.CallExpr                  | void    : () | no value
  1086  036: 28: 8 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1087  037: 28:15 | m1                  *ast.Ident                     | var     : *main.Mesh | variable
  1088  038: 28:19 | m2                  *ast.Ident                     | var     : *main.Mesh | variable
  1089  039: 30: 1 | OnKey               *ast.Ident                     | value   : func(a []string, b []string, fn func(key string)) | value
  1090  040: 30: 1 | OnKey ["a"], nil, key => {
  1091  } *ast.CallExpr                  | void    : () | no value
  1092  041: 30: 8 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1093  042: 30:14 | nil                 *ast.Ident                     | nil     : untyped nil | value
  1094  043: 32: 1 | OnKey               *ast.Ident                     | value   : func(x int, y int) | value
  1095  044: 32: 1 | OnKey 100, 200      *ast.CallExpr                  | void    : () | no value
  1096  045: 32: 7 | 100                 *ast.BasicLit                  | value   : untyped int = 100 | constant
  1097  046: 32:12 | 200                 *ast.BasicLit                  | value   : untyped int = 200 | constant
  1098  047: 33: 1 | OnKey               *ast.Ident                     | value   : func(a string, b string, fn ...func(x int) int) | value
  1099  048: 33: 1 | OnKey "a", "b", x => x * x, x => {
  1100  	return x * 2
  1101  } *ast.CallExpr                  | void    : () | no value
  1102  049: 33: 7 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1103  050: 33:12 | "b"                 *ast.BasicLit                  | value   : untyped string = "b" | constant
  1104  051: 33:22 | x                   *ast.Ident                     | var     : int | variable
  1105  052: 33:22 | x * x               *ast.BinaryExpr                | value   : int | value
  1106  053: 33:26 | x                   *ast.Ident                     | var     : int | variable
  1107  054: 34: 9 | x                   *ast.Ident                     | var     : int | variable
  1108  055: 34: 9 | x * 2               *ast.BinaryExpr                | value   : int | value
  1109  056: 34:13 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
  1110  057: 36: 1 | OnKey               *ast.Ident                     | value   : func(a string, b string, v ...int) | value
  1111  058: 36: 1 | OnKey "a", "b", 1, 2, 3 *ast.CallExpr                  | void    : () | no value
  1112  059: 36: 7 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1113  060: 36:12 | "b"                 *ast.BasicLit                  | value   : untyped string = "b" | constant
  1114  061: 36:17 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
  1115  062: 36:20 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
  1116  063: 36:23 | 3                   *ast.BasicLit                  | value   : untyped int = 3 | constant
  1117  064: 37: 1 | OnKey               *ast.Ident                     | value   : func(a string, b string, v ...int) | value
  1118  065: 37: 1 | OnKey("a", "b", [1, 2, 3]...) *ast.CallExpr                  | void    : () | no value
  1119  066: 37: 7 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1120  067: 37:12 | "b"                 *ast.BasicLit                  | value   : untyped string = "b" | constant
  1121  068: 37:18 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
  1122  069: 37:21 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
  1123  070: 37:24 | 3                   *ast.BasicLit                  | value   : untyped int = 3 | constant
  1124  == defs ==
  1125  000:  2: 6 | Mesh                | type main.Mesh struct{}
  1126  001:  5: 7 | p                   | var p *main.Mesh
  1127  002:  5:16 | Name                | func (*main.Mesh).Name() string
  1128  003: 10: 2 | m1                  | var main.m1 *main.Mesh
  1129  004: 11: 2 | m2                  | var main.m2 *main.Mesh
  1130  005: 14: 1 | main                | func main.main()
  1131  006: 16:16 | key                 | var key string
  1132  007: 20:14 | key                 | var key string
  1133  008: 24:17 | key                 | var key main.Mesher
  1134  009: 26:21 | key                 | var key string
  1135  010: 28:24 | key                 | var key string
  1136  011: 30:19 | key                 | var key string
  1137  012: 33:17 | x                   | var x int
  1138  013: 33:29 | x                   | var x int
  1139  == uses ==
  1140  000:  5:10 | Mesh                | type main.Mesh struct{}
  1141  001:  5:23 | string              | type string
  1142  002: 10: 8 | Mesh                | type main.Mesh struct{}
  1143  003: 11: 8 | Mesh                | type main.Mesh struct{}
  1144  004: 14: 1 | OnKey               | func main.OnKey__0(a string, fn func())
  1145  005: 16: 1 | OnKey               | func main.OnKey__1(a string, fn func(key string))
  1146  006: 18: 1 | OnKey               | func main.OnKey__2(a []string, fn func())
  1147  007: 20: 1 | OnKey               | func main.OnKey__3(a []string, fn func(key string))
  1148  008: 22: 1 | OnKey               | func main.OnKey__4(a []main.Mesher, fn func())
  1149  009: 22: 8 | m1                  | var main.m1 *main.Mesh
  1150  010: 22:12 | m2                  | var main.m2 *main.Mesh
  1151  011: 24: 1 | OnKey               | func main.OnKey__5(a []main.Mesher, fn func(key main.Mesher))
  1152  012: 24: 8 | m1                  | var main.m1 *main.Mesh
  1153  013: 24:12 | m2                  | var main.m2 *main.Mesh
  1154  014: 26: 1 | OnKey               | func main.OnKey__6(a []string, b []string, fn func(key string))
  1155  015: 28: 1 | OnKey               | func main.OnKey__7(a []string, b []main.Mesher, fn func(key string))
  1156  016: 28:15 | m1                  | var main.m1 *main.Mesh
  1157  017: 28:19 | m2                  | var main.m2 *main.Mesh
  1158  018: 30: 1 | OnKey               | func main.OnKey__6(a []string, b []string, fn func(key string))
  1159  019: 30:14 | nil                 | nil
  1160  020: 32: 1 | OnKey               | func main.OnKey__8(x int, y int)
  1161  021: 33: 1 | OnKey               | func main.OnKey__9(a string, b string, fn ...func(x int) int)
  1162  022: 33:22 | x                   | var x int
  1163  023: 33:26 | x                   | var x int
  1164  024: 34: 9 | x                   | var x int
  1165  025: 36: 1 | OnKey               | func main.OnKey__a(a string, b string, v ...int)
  1166  026: 37: 1 | OnKey               | func main.OnKey__a(a string, b string, v ...int)`)
  1167  }
  1168  
  1169  func TestMixedOverload2(t *testing.T) {
  1170  	testGopInfo(t, `
  1171  type Mesh struct {
  1172  }
  1173  
  1174  func (p *Mesh) Name() string {
  1175  	return "hello"
  1176  }
  1177  
  1178  var (
  1179  	m1 = &Mesh{}
  1180  	m2 = &Mesh{}
  1181  )
  1182  
  1183  n := &N{}
  1184  n.onKey "hello", => {
  1185  }
  1186  n.onKey "hello", key => {
  1187  }
  1188  n.onKey ["1"], => {
  1189  }
  1190  n.onKey ["2"], key => {
  1191  }
  1192  n.onKey [m1, m2], => {
  1193  }
  1194  n.onKey [m1, m2], key => {
  1195  }
  1196  n.onKey ["a"], ["b"], key => {
  1197  }
  1198  n.onKey ["a"], [m1, m2], key => {
  1199  }
  1200  n.onKey ["a"], nil, key => {
  1201  }
  1202  n.onKey 100, 200
  1203  `, `
  1204  package main
  1205  
  1206  type Mesher interface {
  1207  	Name() string
  1208  }
  1209  
  1210  type N struct {
  1211  }
  1212  
  1213  func (m *N) OnKey__0(a string, fn func()) {
  1214  }
  1215  
  1216  func (m *N) OnKey__1(a string, fn func(key string)) {
  1217  }
  1218  
  1219  func (m *N) OnKey__2(a []string, fn func()) {
  1220  }
  1221  
  1222  func (m *N) OnKey__3(a []string, fn func(key string)) {
  1223  }
  1224  
  1225  func (m *N) OnKey__4(a []Mesher, fn func()) {
  1226  }
  1227  
  1228  func (m *N) OnKey__5(a []Mesher, fn func(key Mesher)) {
  1229  }
  1230  
  1231  func (m *N) OnKey__6(a []string, b []string, fn func(key string)) {
  1232  }
  1233  
  1234  func (m *N) OnKey__7(a []string, b []Mesher, fn func(key string)) {
  1235  }
  1236  
  1237  func (m *N) OnKey__8(x int, y int) {
  1238  }
  1239  
  1240  
  1241  func OnKey__0(a string, fn func()) {
  1242  }
  1243  
  1244  func OnKey__1(a string, fn func(key string)) {
  1245  }
  1246  
  1247  func OnKey__2(a []string, fn func()) {
  1248  }
  1249  
  1250  func OnKey__3(a []string, fn func(key string)) {
  1251  }
  1252  
  1253  func OnKey__4(a []Mesher, fn func()) {
  1254  }
  1255  
  1256  func OnKey__5(a []Mesher, fn func(key Mesher)) {
  1257  }
  1258  
  1259  func OnKey__6(a []string, b []string, fn func(key string)) {
  1260  }
  1261  
  1262  func OnKey__7(a []string, b []Mesher, fn func(key string)) {
  1263  }
  1264  
  1265  func OnKey__8(x int, y int) {
  1266  }
  1267  
  1268  func OnKey__9(a, b string, fn ...func(x int) int) {
  1269  }
  1270  
  1271  func OnKey__a(a, b string, v ...int) {
  1272  }
  1273  `, `== types ==
  1274  000:  2:11 | struct {
  1275  }          *ast.StructType                | type    : struct{} | type
  1276  001:  5:10 | Mesh                *ast.Ident                     | type    : main.Mesh | type
  1277  002:  5:23 | string              *ast.Ident                     | type    : string | type
  1278  003:  6: 9 | "hello"             *ast.BasicLit                  | value   : untyped string = "hello" | constant
  1279  004: 10: 7 | &Mesh{}             *ast.UnaryExpr                 | value   : *main.Mesh | value
  1280  005: 10: 8 | Mesh                *ast.Ident                     | type    : main.Mesh | type
  1281  006: 10: 8 | Mesh{}              *ast.CompositeLit              | value   : main.Mesh | value
  1282  007: 11: 7 | &Mesh{}             *ast.UnaryExpr                 | value   : *main.Mesh | value
  1283  008: 11: 8 | Mesh                *ast.Ident                     | type    : main.Mesh | type
  1284  009: 11: 8 | Mesh{}              *ast.CompositeLit              | value   : main.Mesh | value
  1285  010: 14: 6 | &N{}                *ast.UnaryExpr                 | value   : *main.N | value
  1286  011: 14: 7 | N                   *ast.Ident                     | type    : main.N | type
  1287  012: 14: 7 | N{}                 *ast.CompositeLit              | value   : main.N | value
  1288  013: 15: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1289  014: 15: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a string, fn func()) | value
  1290  015: 15: 1 | n.onKey "hello", => {
  1291  } *ast.CallExpr                  | void    : () | no value
  1292  016: 15: 9 | "hello"             *ast.BasicLit                  | value   : untyped string = "hello" | constant
  1293  017: 17: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1294  018: 17: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a string, fn func(key string)) | value
  1295  019: 17: 1 | n.onKey "hello", key => {
  1296  } *ast.CallExpr                  | void    : () | no value
  1297  020: 17: 9 | "hello"             *ast.BasicLit                  | value   : untyped string = "hello" | constant
  1298  021: 19: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1299  022: 19: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a []string, fn func()) | value
  1300  023: 19: 1 | n.onKey ["1"], => {
  1301  } *ast.CallExpr                  | void    : () | no value
  1302  024: 19:10 | "1"                 *ast.BasicLit                  | value   : untyped string = "1" | constant
  1303  025: 21: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1304  026: 21: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a []string, fn func(key string)) | value
  1305  027: 21: 1 | n.onKey ["2"], key => {
  1306  } *ast.CallExpr                  | void    : () | no value
  1307  028: 21:10 | "2"                 *ast.BasicLit                  | value   : untyped string = "2" | constant
  1308  029: 23: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1309  030: 23: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a []main.Mesher, fn func()) | value
  1310  031: 23: 1 | n.onKey [m1, m2], => {
  1311  } *ast.CallExpr                  | void    : () | no value
  1312  032: 23:10 | m1                  *ast.Ident                     | var     : *main.Mesh | variable
  1313  033: 23:14 | m2                  *ast.Ident                     | var     : *main.Mesh | variable
  1314  034: 25: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1315  035: 25: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a []main.Mesher, fn func(key main.Mesher)) | value
  1316  036: 25: 1 | n.onKey [m1, m2], key => {
  1317  } *ast.CallExpr                  | void    : () | no value
  1318  037: 25:10 | m1                  *ast.Ident                     | var     : *main.Mesh | variable
  1319  038: 25:14 | m2                  *ast.Ident                     | var     : *main.Mesh | variable
  1320  039: 27: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1321  040: 27: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a []string, b []string, fn func(key string)) | value
  1322  041: 27: 1 | n.onKey ["a"], ["b"], key => {
  1323  } *ast.CallExpr                  | void    : () | no value
  1324  042: 27:10 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1325  043: 27:17 | "b"                 *ast.BasicLit                  | value   : untyped string = "b" | constant
  1326  044: 29: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1327  045: 29: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a []string, b []main.Mesher, fn func(key string)) | value
  1328  046: 29: 1 | n.onKey ["a"], [m1, m2], key => {
  1329  } *ast.CallExpr                  | void    : () | no value
  1330  047: 29:10 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1331  048: 29:17 | m1                  *ast.Ident                     | var     : *main.Mesh | variable
  1332  049: 29:21 | m2                  *ast.Ident                     | var     : *main.Mesh | variable
  1333  050: 31: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1334  051: 31: 1 | n.onKey             *ast.SelectorExpr              | value   : func(a []string, b []string, fn func(key string)) | value
  1335  052: 31: 1 | n.onKey ["a"], nil, key => {
  1336  } *ast.CallExpr                  | void    : () | no value
  1337  053: 31:10 | "a"                 *ast.BasicLit                  | value   : untyped string = "a" | constant
  1338  054: 31:16 | nil                 *ast.Ident                     | nil     : untyped nil | value
  1339  055: 33: 1 | n                   *ast.Ident                     | var     : *main.N | variable
  1340  056: 33: 1 | n.onKey             *ast.SelectorExpr              | value   : func(x int, y int) | value
  1341  057: 33: 1 | n.onKey 100, 200    *ast.CallExpr                  | void    : () | no value
  1342  058: 33: 9 | 100                 *ast.BasicLit                  | value   : untyped int = 100 | constant
  1343  059: 33:14 | 200                 *ast.BasicLit                  | value   : untyped int = 200 | constant
  1344  == defs ==
  1345  000:  2: 6 | Mesh                | type main.Mesh struct{}
  1346  001:  5: 7 | p                   | var p *main.Mesh
  1347  002:  5:16 | Name                | func (*main.Mesh).Name() string
  1348  003: 10: 2 | m1                  | var main.m1 *main.Mesh
  1349  004: 11: 2 | m2                  | var main.m2 *main.Mesh
  1350  005: 14: 1 | main                | func main.main()
  1351  006: 14: 1 | n                   | var n *main.N
  1352  007: 17:18 | key                 | var key string
  1353  008: 21:16 | key                 | var key string
  1354  009: 25:19 | key                 | var key main.Mesher
  1355  010: 27:23 | key                 | var key string
  1356  011: 29:26 | key                 | var key string
  1357  012: 31:21 | key                 | var key string
  1358  == uses ==
  1359  000:  5:10 | Mesh                | type main.Mesh struct{}
  1360  001:  5:23 | string              | type string
  1361  002: 10: 8 | Mesh                | type main.Mesh struct{}
  1362  003: 11: 8 | Mesh                | type main.Mesh struct{}
  1363  004: 14: 7 | N                   | type main.N struct{}
  1364  005: 15: 1 | n                   | var n *main.N
  1365  006: 15: 3 | onKey               | func (*main.N).OnKey__0(a string, fn func())
  1366  007: 17: 1 | n                   | var n *main.N
  1367  008: 17: 3 | onKey               | func (*main.N).OnKey__1(a string, fn func(key string))
  1368  009: 19: 1 | n                   | var n *main.N
  1369  010: 19: 3 | onKey               | func (*main.N).OnKey__2(a []string, fn func())
  1370  011: 21: 1 | n                   | var n *main.N
  1371  012: 21: 3 | onKey               | func (*main.N).OnKey__3(a []string, fn func(key string))
  1372  013: 23: 1 | n                   | var n *main.N
  1373  014: 23: 3 | onKey               | func (*main.N).OnKey__4(a []main.Mesher, fn func())
  1374  015: 23:10 | m1                  | var main.m1 *main.Mesh
  1375  016: 23:14 | m2                  | var main.m2 *main.Mesh
  1376  017: 25: 1 | n                   | var n *main.N
  1377  018: 25: 3 | onKey               | func (*main.N).OnKey__5(a []main.Mesher, fn func(key main.Mesher))
  1378  019: 25:10 | m1                  | var main.m1 *main.Mesh
  1379  020: 25:14 | m2                  | var main.m2 *main.Mesh
  1380  021: 27: 1 | n                   | var n *main.N
  1381  022: 27: 3 | onKey               | func (*main.N).OnKey__6(a []string, b []string, fn func(key string))
  1382  023: 29: 1 | n                   | var n *main.N
  1383  024: 29: 3 | onKey               | func (*main.N).OnKey__7(a []string, b []main.Mesher, fn func(key string))
  1384  025: 29:17 | m1                  | var main.m1 *main.Mesh
  1385  026: 29:21 | m2                  | var main.m2 *main.Mesh
  1386  027: 31: 1 | n                   | var n *main.N
  1387  028: 31: 3 | onKey               | func (*main.N).OnKey__6(a []string, b []string, fn func(key string))
  1388  029: 31:16 | nil                 | nil
  1389  030: 33: 1 | n                   | var n *main.N
  1390  031: 33: 3 | onKey               | func (*main.N).OnKey__8(x int, y int)`)
  1391  }
  1392  
  1393  func TestMixedOverload3(t *testing.T) {
  1394  	testGopInfo(t, `
  1395  Test
  1396  Test 100
  1397  var n N
  1398  n.test
  1399  n.test 100
  1400  `, `
  1401  package main
  1402  
  1403  func Test__0() {
  1404  }
  1405  func Test__1(n int) {
  1406  }
  1407  type N struct {
  1408  }
  1409  func (p *N) Test__0() {
  1410  }
  1411  func (p *N) Test__1(n int) {
  1412  }
  1413  `, `== types ==
  1414  000:  2: 1 | Test                *ast.Ident                     | value   : func() | value
  1415  001:  3: 1 | Test                *ast.Ident                     | value   : func(n int) | value
  1416  002:  3: 1 | Test 100            *ast.CallExpr                  | void    : () | no value
  1417  003:  3: 6 | 100                 *ast.BasicLit                  | value   : untyped int = 100 | constant
  1418  004:  4: 7 | N                   *ast.Ident                     | type    : main.N | type
  1419  005:  5: 1 | n                   *ast.Ident                     | var     : main.N | variable
  1420  006:  5: 1 | n.test              *ast.SelectorExpr              | value   : func() | value
  1421  007:  6: 1 | n                   *ast.Ident                     | var     : main.N | variable
  1422  008:  6: 1 | n.test              *ast.SelectorExpr              | value   : func(n int) | value
  1423  009:  6: 1 | n.test 100          *ast.CallExpr                  | void    : () | no value
  1424  010:  6: 8 | 100                 *ast.BasicLit                  | value   : untyped int = 100 | constant
  1425  == defs ==
  1426  000:  2: 1 | main                | func main.main()
  1427  001:  4: 5 | n                   | var n main.N
  1428  == uses ==
  1429  000:  2: 1 | Test                | func main.Test__0()
  1430  001:  3: 1 | Test                | func main.Test__1(n int)
  1431  002:  4: 7 | N                   | type main.N struct{}
  1432  003:  5: 1 | n                   | var n main.N
  1433  004:  5: 3 | test                | func (*main.N).Test__0()
  1434  005:  6: 1 | n                   | var n main.N
  1435  006:  6: 3 | test                | func (*main.N).Test__1(n int)`)
  1436  }
  1437  
  1438  func TestOverloadNamed(t *testing.T) {
  1439  	testGopInfo(t, `
  1440  import "github.com/goplus/gop/cl/internal/overload/bar"
  1441  
  1442  var a bar.Var[int]
  1443  var b bar.Var[bar.M]
  1444  c := bar.Var(string)
  1445  d := bar.Var(bar.M)
  1446  `, ``, `== types ==
  1447  000:  4: 7 | bar.Var             *ast.SelectorExpr              | type    : github.com/goplus/gop/cl/internal/overload/bar.Var__0[int] | type
  1448  001:  4: 7 | bar.Var[int]        *ast.IndexExpr                 | type    : github.com/goplus/gop/cl/internal/overload/bar.Var__0[int] | type
  1449  002:  4:15 | int                 *ast.Ident                     | type    : int | type
  1450  003:  5: 7 | bar.Var             *ast.SelectorExpr              | type    : github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any] | type
  1451  004:  5: 7 | bar.Var[bar.M]      *ast.IndexExpr                 | type    : github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any] | type
  1452  005:  5:15 | bar.M               *ast.SelectorExpr              | type    : map[string]any | type
  1453  006:  6: 6 | bar.Var             *ast.SelectorExpr              | value   : func[T github.com/goplus/gop/cl/internal/overload/bar.basetype]() *github.com/goplus/gop/cl/internal/overload/bar.Var__0[T] | value
  1454  007:  6: 6 | bar.Var(string)     *ast.CallExpr                  | value   : *github.com/goplus/gop/cl/internal/overload/bar.Var__0[string] | value
  1455  008:  6:14 | string              *ast.Ident                     | type    : string | type
  1456  009:  7: 6 | bar.Var             *ast.SelectorExpr              | value   : func[T map[string]any]() *github.com/goplus/gop/cl/internal/overload/bar.Var__1[T] | value
  1457  010:  7: 6 | bar.Var(bar.M)      *ast.CallExpr                  | value   : *github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any] | value
  1458  011:  7:14 | bar.M               *ast.SelectorExpr              | var     : map[string]any | variable
  1459  == defs ==
  1460  000:  4: 5 | a                   | var main.a github.com/goplus/gop/cl/internal/overload/bar.Var__0[int]
  1461  001:  5: 5 | b                   | var main.b github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any]
  1462  002:  6: 1 | c                   | var c *github.com/goplus/gop/cl/internal/overload/bar.Var__0[string]
  1463  003:  6: 1 | main                | func main.main()
  1464  004:  7: 1 | d                   | var d *github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any]
  1465  == uses ==
  1466  000:  4: 7 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
  1467  001:  4:11 | Var                 | type github.com/goplus/gop/cl/internal/overload/bar.Var__0[T github.com/goplus/gop/cl/internal/overload/bar.basetype] struct{val T}
  1468  002:  4:15 | int                 | type int
  1469  003:  5: 7 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
  1470  004:  5:11 | Var                 | type github.com/goplus/gop/cl/internal/overload/bar.Var__1[T map[string]any] struct{val T}
  1471  005:  5:15 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
  1472  006:  5:19 | M                   | type github.com/goplus/gop/cl/internal/overload/bar.M = map[string]any
  1473  007:  6: 6 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
  1474  008:  6:10 | Var                 | func github.com/goplus/gop/cl/internal/overload/bar.Gopx_Var_Cast__0[T github.com/goplus/gop/cl/internal/overload/bar.basetype]() *github.com/goplus/gop/cl/internal/overload/bar.Var__0[T]
  1475  009:  6:14 | string              | type string
  1476  010:  7: 6 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
  1477  011:  7:10 | Var                 | func github.com/goplus/gop/cl/internal/overload/bar.Gopx_Var_Cast__1[T map[string]any]() *github.com/goplus/gop/cl/internal/overload/bar.Var__1[T]
  1478  012:  7:14 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
  1479  013:  7:18 | M                   | type github.com/goplus/gop/cl/internal/overload/bar.M = map[string]any`)
  1480  }
  1481  
  1482  func TestMixedOverloadNamed(t *testing.T) {
  1483  	testGopInfo(t, `
  1484  var a Var[int]
  1485  var b Var[M]
  1486  c := Var(string)
  1487  d := Var(M)
  1488  `, `
  1489  package main
  1490  
  1491  type M = map[string]any
  1492  
  1493  type basetype interface {
  1494  	string | int | bool | float64
  1495  }
  1496  
  1497  type Var__0[T basetype] struct {
  1498  	val T
  1499  }
  1500  
  1501  type Var__1[T map[string]any] struct {
  1502  	val T
  1503  }
  1504  
  1505  func Gopx_Var_Cast__0[T basetype]() *Var__0[T] {
  1506  	return new(Var__0[T])
  1507  }
  1508  
  1509  func Gopx_Var_Cast__1[T map[string]any]() *Var__1[T] {
  1510  	return new(Var__1[T])
  1511  }
  1512  `, `== types ==
  1513  000:  2: 7 | Var                 *ast.Ident                     | type    : main.Var__0[int] | type
  1514  001:  2: 7 | Var[int]            *ast.IndexExpr                 | type    : main.Var__0[int] | type
  1515  002:  2:11 | int                 *ast.Ident                     | type    : int | type
  1516  003:  3: 7 | Var                 *ast.Ident                     | type    : main.Var__1[map[string]interface{}] | type
  1517  004:  3: 7 | Var[M]              *ast.IndexExpr                 | type    : main.Var__1[map[string]interface{}] | type
  1518  005:  3:11 | M                   *ast.Ident                     | type    : map[string]interface{} | type
  1519  006:  4: 6 | Var                 *ast.Ident                     | value   : func[T main.basetype]() *main.Var__0[T] | value
  1520  007:  4: 6 | Var(string)         *ast.CallExpr                  | value   : *main.Var__0[string] | value
  1521  008:  4:10 | string              *ast.Ident                     | type    : string | type
  1522  009:  5: 6 | Var                 *ast.Ident                     | value   : func[T map[string]interface{}]() *main.Var__1[T] | value
  1523  010:  5: 6 | Var(M)              *ast.CallExpr                  | value   : *main.Var__1[map[string]interface{}] | value
  1524  011:  5:10 | M                   *ast.Ident                     | type    : map[string]interface{} | type
  1525  == defs ==
  1526  000:  2: 5 | a                   | var main.a main.Var__0[int]
  1527  001:  3: 5 | b                   | var main.b main.Var__1[map[string]interface{}]
  1528  002:  4: 1 | c                   | var c *main.Var__0[string]
  1529  003:  4: 1 | main                | func main.main()
  1530  004:  5: 1 | d                   | var d *main.Var__1[map[string]interface{}]
  1531  == uses ==
  1532  000:  2: 7 | Var                 | type main.Var__0[T main.basetype] struct{val T}
  1533  001:  2:11 | int                 | type int
  1534  002:  3: 7 | Var                 | type main.Var__1[T map[string]any] struct{val T}
  1535  003:  3:11 | M                   | type main.M = map[string]any
  1536  004:  4: 6 | Var                 | func main.Gopx_Var_Cast__0[T main.basetype]() *main.Var__0[T]
  1537  005:  4:10 | string              | type string
  1538  006:  5: 6 | Var                 | func main.Gopx_Var_Cast__1[T map[string]any]() *main.Var__1[T]
  1539  007:  5:10 | M                   | type main.M = map[string]any`)
  1540  }
  1541  
  1542  func TestMixedRawNamed(t *testing.T) {
  1543  	testGopInfo(t, `
  1544  var a Var__0[int]
  1545  var b Var__1[M]
  1546  c := Gopx_Var_Cast__0[string]
  1547  d := Gopx_Var_Cast__1[M]
  1548  `, `
  1549  package main
  1550  
  1551  type M = map[string]any
  1552  
  1553  type basetype interface {
  1554  	string | int | bool | float64
  1555  }
  1556  
  1557  type Var__0[T basetype] struct {
  1558  	val T
  1559  }
  1560  
  1561  type Var__1[T map[string]any] struct {
  1562  	val T
  1563  }
  1564  
  1565  func Gopx_Var_Cast__0[T basetype]() *Var__0[T] {
  1566  	return new(Var__0[T])
  1567  }
  1568  
  1569  func Gopx_Var_Cast__1[T map[string]any]() *Var__1[T] {
  1570  	return new(Var__1[T])
  1571  }
  1572  `, `== types ==
  1573  000:  2: 7 | Var__0              *ast.Ident                     | type    : main.Var__0[int] | type
  1574  001:  2: 7 | Var__0[int]         *ast.IndexExpr                 | type    : main.Var__0[int] | type
  1575  002:  2:14 | int                 *ast.Ident                     | type    : int | type
  1576  003:  3: 7 | Var__1              *ast.Ident                     | type    : main.Var__1[map[string]interface{}] | type
  1577  004:  3: 7 | Var__1[M]           *ast.IndexExpr                 | type    : main.Var__1[map[string]interface{}] | type
  1578  005:  3:14 | M                   *ast.Ident                     | type    : map[string]interface{} | type
  1579  006:  4: 6 | Gopx_Var_Cast__0    *ast.Ident                     | value   : func[T main.basetype]() *main.Var__0[T] | value
  1580  007:  4: 6 | Gopx_Var_Cast__0[string] *ast.IndexExpr                 | var     : func() *main.Var__0[string] | variable
  1581  008:  4:23 | string              *ast.Ident                     | type    : string | type
  1582  009:  5: 6 | Gopx_Var_Cast__1    *ast.Ident                     | value   : func[T map[string]interface{}]() *main.Var__1[T] | value
  1583  010:  5: 6 | Gopx_Var_Cast__1[M] *ast.IndexExpr                 | var     : func() *main.Var__1[map[string]interface{}] | variable
  1584  011:  5:23 | M                   *ast.Ident                     | type    : map[string]interface{} | type
  1585  == defs ==
  1586  000:  2: 5 | a                   | var main.a main.Var__0[int]
  1587  001:  3: 5 | b                   | var main.b main.Var__1[map[string]interface{}]
  1588  002:  4: 1 | c                   | var c func() *main.Var__0[string]
  1589  003:  4: 1 | main                | func main.main()
  1590  004:  5: 1 | d                   | var d func() *main.Var__1[map[string]interface{}]
  1591  == uses ==
  1592  000:  2: 7 | Var__0              | type main.Var__0[T main.basetype] struct{val T}
  1593  001:  2:14 | int                 | type int
  1594  002:  3: 7 | Var__1              | type main.Var__1[T map[string]any] struct{val T}
  1595  003:  3:14 | M                   | type main.M = map[string]any
  1596  004:  4: 6 | Gopx_Var_Cast__0    | func main.Gopx_Var_Cast__0[T main.basetype]() *main.Var__0[T]
  1597  005:  4:23 | string              | type string
  1598  006:  5: 6 | Gopx_Var_Cast__1    | func main.Gopx_Var_Cast__1[T map[string]any]() *main.Var__1[T]
  1599  007:  5:23 | M                   | type main.M = map[string]any`)
  1600  }
  1601  
  1602  func TestSpxInfo(t *testing.T) {
  1603  	testSpxInfo(t, "Kai.tspx", `
  1604  var (
  1605  	a int
  1606  )
  1607  
  1608  type info struct {
  1609  	x int
  1610  	y int
  1611  }
  1612  
  1613  func onInit() {
  1614  	a = 1
  1615  	clone
  1616  	clone info{1,2}
  1617  	clone &info{1,2}
  1618  }
  1619  
  1620  func onCloned() {
  1621  	say("Hi")
  1622  }
  1623  `, `== types ==
  1624  000:  0: 0 | "Kai"               *ast.BasicLit                  | value   : untyped string = "Kai" | constant
  1625  001:  0: 0 | *MyGame             *ast.StarExpr                  | type    : *main.MyGame | type
  1626  002:  0: 0 | Kai                 *ast.Ident                     | type    : main.Kai | type
  1627  003:  0: 0 | MyGame              *ast.Ident                     | type    : main.MyGame | type
  1628  004:  0: 0 | string              *ast.Ident                     | type    : string | type
  1629  005:  3: 4 | int                 *ast.Ident                     | type    : int | type
  1630  006:  6:11 | struct {
  1631  	x int
  1632  	y int
  1633  } *ast.StructType                | type    : struct{x int; y int} | type
  1634  007:  7: 4 | int                 *ast.Ident                     | type    : int | type
  1635  008:  8: 4 | int                 *ast.Ident                     | type    : int | type
  1636  009: 12: 2 | a                   *ast.Ident                     | var     : int | variable
  1637  010: 12: 6 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
  1638  011: 13: 2 | clone               *ast.Ident                     | value   : func(sprite interface{}) | value
  1639  012: 14: 2 | clone               *ast.Ident                     | value   : func(sprite interface{}, data interface{}) | value
  1640  013: 14: 2 | clone info{1, 2}    *ast.CallExpr                  | void    : () | no value
  1641  014: 14: 8 | info                *ast.Ident                     | type    : main.info | type
  1642  015: 14: 8 | info{1, 2}          *ast.CompositeLit              | value   : main.info | value
  1643  016: 14:13 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
  1644  017: 14:15 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
  1645  018: 15: 2 | clone               *ast.Ident                     | value   : func(sprite interface{}, data interface{}) | value
  1646  019: 15: 2 | clone &info{1, 2}   *ast.CallExpr                  | void    : () | no value
  1647  020: 15: 8 | &info{1, 2}         *ast.UnaryExpr                 | value   : *main.info | value
  1648  021: 15: 9 | info                *ast.Ident                     | type    : main.info | type
  1649  022: 15: 9 | info{1, 2}          *ast.CompositeLit              | value   : main.info | value
  1650  023: 15:14 | 1                   *ast.BasicLit                  | value   : untyped int = 1 | constant
  1651  024: 15:16 | 2                   *ast.BasicLit                  | value   : untyped int = 2 | constant
  1652  025: 19: 2 | say                 *ast.Ident                     | value   : func(msg string, secs ...float64) | value
  1653  026: 19: 2 | say("Hi")           *ast.CallExpr                  | void    : () | no value
  1654  027: 19: 6 | "Hi"                *ast.BasicLit                  | value   : untyped string = "Hi" | constant
  1655  == defs ==
  1656  000:  0: 0 | Classfname          | func (*main.Kai).Classfname() string
  1657  001:  0: 0 | Main                | func (*main.Kai).Main()
  1658  002:  0: 0 | this                | var this *main.Kai
  1659  003:  3: 2 | a                   | field a int
  1660  004:  6: 6 | info                | type main.info struct{x int; y int}
  1661  005:  7: 2 | x                   | field x int
  1662  006:  8: 2 | y                   | field y int
  1663  007: 11: 6 | onInit              | func (*main.Kai).onInit()
  1664  008: 18: 6 | onCloned            | func (*main.Kai).onCloned()
  1665  == uses ==
  1666  000:  0: 0 | Kai                 | type main.Kai struct{github.com/goplus/gop/cl/internal/spx.Sprite; *main.MyGame; a int}
  1667  001:  0: 0 | MyGame              | type main.MyGame struct{*github.com/goplus/gop/cl/internal/spx.MyGame}
  1668  002:  0: 0 | string              | type string
  1669  003:  3: 4 | int                 | type int
  1670  004:  7: 4 | int                 | type int
  1671  005:  8: 4 | int                 | type int
  1672  006: 12: 2 | a                   | field a int
  1673  007: 13: 2 | clone               | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__0(sprite interface{})
  1674  008: 14: 2 | clone               | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite interface{}, data interface{})
  1675  009: 14: 8 | info                | type main.info struct{x int; y int}
  1676  010: 15: 2 | clone               | func github.com/goplus/gop/cl/internal/spx.Gopt_Sprite_Clone__1(sprite interface{}, data interface{})
  1677  011: 15: 9 | info                | type main.info struct{x int; y int}
  1678  012: 19: 2 | say                 | func (*github.com/goplus/gop/cl/internal/spx.Sprite).Say(msg string, secs ...float64)`)
  1679  }
  1680  
  1681  func TestScopesInfo(t *testing.T) {
  1682  	var tests = []struct {
  1683  		src    string
  1684  		scopes []string // list of scope descriptors of the form kind:varlist
  1685  	}{
  1686  		{`package p0`, []string{
  1687  			"file:",
  1688  		}},
  1689  		{`package p1; import ( "fmt"; m "math"; _ "os" ); var ( _ = fmt.Println; _ = m.Pi )`, []string{
  1690  			"file:fmt m",
  1691  		}},
  1692  		{`package p2; func _() {}`, []string{
  1693  			"file:", "func:",
  1694  		}},
  1695  		{`package p3; func _(x, y int) {}`, []string{
  1696  			"file:", "func:x y",
  1697  		}},
  1698  		{`package p4; func _(x, y int) { x, z := 1, 2; _ = z }`, []string{
  1699  			"file:", "func:x y z", // redeclaration of x
  1700  		}},
  1701  		{`package p5; func _(x, y int) (u, _ int) { return }`, []string{
  1702  			"file:", "func:u x y",
  1703  		}},
  1704  		{`package p6; func _() { { var x int; _ = x } }`, []string{
  1705  			"file:", "func:", "block:x",
  1706  		}},
  1707  		{`package p7; func _() { if true {} }`, []string{
  1708  			"file:", "func:", "if:", "block:",
  1709  		}},
  1710  		{`package p8; func _() { if x := 0; x < 0 { y := x; _ = y } }`, []string{
  1711  			"file:", "func:", "if:x", "block:y",
  1712  		}},
  1713  		{`package p9; func _() { switch x := 0; x {} }`, []string{
  1714  			"file:", "func:", "switch:x",
  1715  		}},
  1716  		{`package p10; func _() { switch x := 0; x { case 1: y := x; _ = y; default: }}`, []string{
  1717  			"file:", "func:", "switch:x", "case:y", "case:",
  1718  		}},
  1719  		{`package p11; func _(t interface{}) { switch t.(type) {} }`, []string{
  1720  			"file:", "func:t", "type switch:",
  1721  		}},
  1722  		{`package p12; func _(t interface{}) { switch t := t; t.(type) {} }`, []string{
  1723  			"file:", "func:t", "type switch:t",
  1724  		}},
  1725  		{`package p13; func _(t interface{}) { switch x := t.(type) { case int: _ = x } }`, []string{
  1726  			"file:", "func:t", "type switch:", "case:x", // x implicitly declared
  1727  		}},
  1728  		{`package p14; func _() { select{} }`, []string{
  1729  			"file:", "func:",
  1730  		}},
  1731  		{`package p15; func _(c chan int) { select{ case <-c: } }`, []string{
  1732  			"file:", "func:c", "comm:",
  1733  		}},
  1734  		{`package p16; func _(c chan int) { select{ case i := <-c: x := i; _ = x} }`, []string{
  1735  			"file:", "func:c", "comm:i x",
  1736  		}},
  1737  		{`package p17; func _() { for{} }`, []string{
  1738  			"file:", "func:", "for:", "block:",
  1739  		}},
  1740  		{`package p18; func _(n int) { for i := 0; i < n; i++ { _ = i } }`, []string{
  1741  			"file:", "func:n", "for:i", "block:",
  1742  		}},
  1743  		{`package p19; func _(a []int) { for i := range a { _ = i} }`, []string{
  1744  			"file:", "func:a", "range:i", "block:",
  1745  		}},
  1746  		{`package p20; var s int; func _(a []int) { for i, x := range a { s += x; _ = i } }`, []string{
  1747  			"file:", "func:a", "range:i x", "block:",
  1748  		}},
  1749  		{`package p21; var s int; func _(a []int) { for i, x := range a { c := i; println(c) } }`, []string{
  1750  			"file:", "func:a", "range:i x", "block:c",
  1751  		}},
  1752  		{`package p22; func _(){ sum := 0; for x <- [1, 3, 5, 7, 11, 13, 17], x > 3 { sum = sum + x; c := sum; _ = c } }`, []string{
  1753  			"file:", "func:sum", "for phrase:x", "block:c",
  1754  		}},
  1755  		{`package p23; func _(){ sum := 0; for x <- [1, 3, 5, 7, 11, 13, 17] { sum = sum + x; c := sum; _ = c } }`, []string{
  1756  			"file:", "func:sum", "for phrase:x", "block:c",
  1757  		}},
  1758  		{`package p23; func test(fn func(int)int){};func _(){test(func(x int) int { y := x*x; return y } ) }`, []string{
  1759  			"file:test", "func:fn", "func:", "func:x y",
  1760  		}},
  1761  		{`package p24; func test(fn func(int)int){};func _(){test( x => x*x );}`, []string{
  1762  			"file:test", "func:fn", "func:", "lambda:x",
  1763  		}},
  1764  		{`package p25; func test(fn func(int)int){};func _(){test( x => { y := x*x; return y } ) }`, []string{
  1765  			"file:test", "func:fn", "func:", "lambda:x y",
  1766  		}},
  1767  		{`package p26; func _(){ b := {for x <- ["1", "3", "5", "7", "11"], x == "5"}; _ = b }`, []string{
  1768  			"file:", "func:b", "for phrase:x",
  1769  		}},
  1770  		{`package p27; func _(){ b, ok := {i for i, x <- ["1", "3", "5", "7", "11"], x == "5"}; _ = b; _ = ok }`, []string{
  1771  			"file:", "func:b ok", "for phrase:i x",
  1772  		}},
  1773  		{`package p28; func _(){ a := [x*x for x <- [1, 3.4, 5] if x > 2 ]; _ = a }`, []string{
  1774  			"file:", "func:a", "for phrase:x",
  1775  		}},
  1776  		{`package p29; func _(){ arr := [1, 2, 3, 4.1, 5, 6];x := [[a, b] for a <- arr, a < b for b <- arr, b > 2]; _ = x }`, []string{
  1777  			"file:", "func:arr x", "for phrase:b", "for phrase:a",
  1778  		}},
  1779  		{`package p30; func _(){ y := {x: i for i, x <- ["1", "3", "5", "7", "11"]}; _ = y }`, []string{
  1780  			"file:", "func:y", "for phrase:i x",
  1781  		}},
  1782  		{`package p31; func _(){ z := {v: k for k, v <- {"Hello": 1, "Hi": 3, "xsw": 5, "Go+": 7}, v > 3}; _ = z }`, []string{
  1783  			"file:", "func:z", "for phrase:k v",
  1784  		}},
  1785  	}
  1786  
  1787  	for _, test := range tests {
  1788  		pkg, info, err := parseSource(token.NewFileSet(), "src.gop", test.src, 0)
  1789  		if err != nil {
  1790  			t.Fatalf("parse source failed: %v", test.src)
  1791  		}
  1792  		name := pkg.Name()
  1793  		// number of scopes must match
  1794  		if len(info.Scopes) != len(test.scopes) {
  1795  			t.Errorf("package %s: got %d scopes; want %d\n%v\n%v", name, len(info.Scopes), len(test.scopes),
  1796  				test.scopes, info.Scopes)
  1797  		}
  1798  
  1799  		// scope descriptions must match
  1800  		for node, scope := range info.Scopes {
  1801  			kind := "<unknown node kind>"
  1802  			switch node.(type) {
  1803  			case *ast.File:
  1804  				kind = "file"
  1805  			case *ast.FuncType:
  1806  				kind = "func"
  1807  			case *ast.BlockStmt:
  1808  				kind = "block"
  1809  			case *ast.IfStmt:
  1810  				kind = "if"
  1811  			case *ast.SwitchStmt:
  1812  				kind = "switch"
  1813  			case *ast.TypeSwitchStmt:
  1814  				kind = "type switch"
  1815  			case *ast.CaseClause:
  1816  				kind = "case"
  1817  			case *ast.CommClause:
  1818  				kind = "comm"
  1819  			case *ast.ForStmt:
  1820  				kind = "for"
  1821  			case *ast.RangeStmt:
  1822  				kind = "range"
  1823  			case *ast.ForPhraseStmt:
  1824  				kind = "for phrase"
  1825  			case *ast.LambdaExpr:
  1826  				kind = "lambda"
  1827  			case *ast.LambdaExpr2:
  1828  				kind = "lambda"
  1829  			case *ast.ForPhrase:
  1830  				kind = "for phrase"
  1831  			default:
  1832  				kind = fmt.Sprintf("<unknown node kind> %T", node)
  1833  			}
  1834  
  1835  			// look for matching scope description
  1836  			desc := kind + ":" + strings.Join(scope.Names(), " ")
  1837  			found := false
  1838  			for _, d := range test.scopes {
  1839  				if desc == d {
  1840  					found = true
  1841  					break
  1842  				}
  1843  			}
  1844  			if !found {
  1845  				t.Errorf("package %s: no matching scope found for %s", name, desc)
  1846  			}
  1847  		}
  1848  	}
  1849  }
  1850  
  1851  func TestAddress(t *testing.T) {
  1852  	testInfo(t, `package address
  1853  
  1854  type foo struct{ c int; p *int }
  1855  
  1856  func (f foo) ptr() *foo { return &f }
  1857  func (f foo) clone() foo { return f }
  1858  
  1859  type nested struct {
  1860  	f foo
  1861  	a [2]foo
  1862  	s []foo
  1863  	m map[int]foo
  1864  }
  1865  
  1866  func _() {
  1867  	getNested := func() nested { return nested{} }
  1868  	getNestedPtr := func() *nested { return &nested{} }
  1869  
  1870  	_ = getNested().f.c
  1871  	_ = getNested().a[0].c
  1872  	_ = getNested().s[0].c
  1873  	_ = getNested().m[0].c
  1874  	_ = getNested().f.ptr().c
  1875  	_ = getNested().f.clone().c
  1876  	_ = getNested().f.clone().ptr().c
  1877  
  1878  	_ = getNestedPtr().f.c
  1879  	_ = getNestedPtr().a[0].c
  1880  	_ = getNestedPtr().s[0].c
  1881  	_ = getNestedPtr().m[0].c
  1882  	_ = getNestedPtr().f.ptr().c
  1883  	_ = getNestedPtr().f.clone().c
  1884  	_ = getNestedPtr().f.clone().ptr().c
  1885  }
  1886  `)
  1887  }
  1888  
  1889  func TestAddress2(t *testing.T) {
  1890  	testInfo(t, `package load
  1891  import "os"
  1892  
  1893  func _() { _ = os.Stdout }
  1894  func _() {
  1895  	var a int
  1896  	_ = a
  1897  }
  1898  func _() {
  1899  	var p *int
  1900  	_ = *p
  1901  }
  1902  func _() {
  1903  	var s []int
  1904  	_ = s[0]
  1905  }
  1906  func _() {
  1907  	var s struct{f int}
  1908  	_ = s.f
  1909  }
  1910  func _() {
  1911  	var a [10]int
  1912  	_ = a[0]
  1913  }
  1914  func _(x int) {
  1915  	_ = x
  1916  }
  1917  func _()(x int) {
  1918  	_ = x
  1919  	return
  1920  }
  1921  type T int
  1922  func (x T) _() {
  1923  	_ = x
  1924  }
  1925  
  1926  func _() {
  1927  	var a, b int
  1928  	_ = a + b
  1929  }
  1930  func _() {
  1931  	_ = &[]int{1}
  1932  }
  1933  func _() {
  1934  	_ = func(){}
  1935  }
  1936  func f() { _ = f }
  1937  func _() {
  1938  	var m map[int]int
  1939  	_ = m[0]
  1940  	_, _ = m[0]
  1941  }
  1942  func _() {
  1943  	var ch chan int
  1944  	_ = <-ch
  1945  	_, _ = <-ch
  1946  }
  1947  `)
  1948  }
  1949  
  1950  func TestMixedPackage(t *testing.T) {
  1951  	fset := token.NewFileSet()
  1952  	pkg, _, _, err := parseMixedSource(gopmod.Default, fset, "main.gop", `
  1953  Test
  1954  Test 100
  1955  var n N
  1956  n.test
  1957  n.test 100
  1958  `, "main.go", `
  1959  package main
  1960  
  1961  func Test__0() {
  1962  }
  1963  func Test__1(n int) {
  1964  }
  1965  type N struct {
  1966  }
  1967  func (p *N) Test__0() {
  1968  }
  1969  func (p *N) Test__1(n int) {
  1970  }`, parser.Config{}, true)
  1971  	if err != nil {
  1972  		t.Fatal(err)
  1973  	}
  1974  	obj := pkg.Scope().Lookup("N")
  1975  	named := obj.Type().(*types.Named)
  1976  	if named.NumMethods() == 2 {
  1977  		t.Fatal("found overload method failed")
  1978  	}
  1979  	ext, ok := gogen.CheckFuncEx(named.Method(2).Type().(*types.Signature))
  1980  	if !ok {
  1981  		t.Fatal("checkFuncEx failed")
  1982  	}
  1983  	m, ok := ext.(*gogen.TyOverloadMethod)
  1984  	if !ok || len(m.Methods) != 2 {
  1985  		t.Fatal("check TyOverloadMethod failed")
  1986  	}
  1987  }
  1988  
  1989  func TestGopOverloadUses(t *testing.T) {
  1990  	testGopInfo(t, `
  1991  func MulInt(a, b int) int {
  1992  	return a * b
  1993  }
  1994  
  1995  func MulFloat(a, b float64) float64 {
  1996  	return a * b
  1997  }
  1998  
  1999  func Mul = (
  2000  	MulInt
  2001  	MulFloat
  2002  	func(x, y, z int) int {
  2003  		return x * y * z
  2004  	}
  2005  )
  2006  
  2007  Mul 100,200
  2008  Mul 100,200,300
  2009  `, ``, `== types ==
  2010  000:  0: 0 | "MulInt,MulFloat,"  *ast.BasicLit                  | value   : untyped string = "MulInt,MulFloat," | constant
  2011  001:  2:18 | int                 *ast.Ident                     | type    : int | type
  2012  002:  2:23 | int                 *ast.Ident                     | type    : int | type
  2013  003:  3: 9 | a                   *ast.Ident                     | var     : int | variable
  2014  004:  3: 9 | a * b               *ast.BinaryExpr                | value   : int | value
  2015  005:  3:13 | b                   *ast.Ident                     | var     : int | variable
  2016  006:  6:20 | float64             *ast.Ident                     | type    : float64 | type
  2017  007:  6:29 | float64             *ast.Ident                     | type    : float64 | type
  2018  008:  7: 9 | a                   *ast.Ident                     | var     : float64 | variable
  2019  009:  7: 9 | a * b               *ast.BinaryExpr                | value   : float64 | value
  2020  010:  7:13 | b                   *ast.Ident                     | var     : float64 | variable
  2021  011: 13:15 | int                 *ast.Ident                     | type    : int | type
  2022  012: 13:20 | int                 *ast.Ident                     | type    : int | type
  2023  013: 14:10 | x                   *ast.Ident                     | var     : int | variable
  2024  014: 14:10 | x * y               *ast.BinaryExpr                | value   : int | value
  2025  015: 14:10 | x * y * z           *ast.BinaryExpr                | value   : int | value
  2026  016: 14:14 | y                   *ast.Ident                     | var     : int | variable
  2027  017: 14:18 | z                   *ast.Ident                     | var     : int | variable
  2028  018: 18: 1 | Mul                 *ast.Ident                     | value   : func(a int, b int) int | value
  2029  019: 18: 1 | Mul 100, 200        *ast.CallExpr                  | value   : int | value
  2030  020: 18: 5 | 100                 *ast.BasicLit                  | value   : untyped int = 100 | constant
  2031  021: 18: 9 | 200                 *ast.BasicLit                  | value   : untyped int = 200 | constant
  2032  022: 19: 1 | Mul                 *ast.Ident                     | value   : func(x int, y int, z int) int | value
  2033  023: 19: 1 | Mul 100, 200, 300   *ast.CallExpr                  | value   : int | value
  2034  024: 19: 5 | 100                 *ast.BasicLit                  | value   : untyped int = 100 | constant
  2035  025: 19: 9 | 200                 *ast.BasicLit                  | value   : untyped int = 200 | constant
  2036  026: 19:13 | 300                 *ast.BasicLit                  | value   : untyped int = 300 | constant
  2037  == defs ==
  2038  000:  0: 0 | Gopo_Mul            | const main.Gopo_Mul untyped string
  2039  001:  2: 6 | MulInt              | func main.MulInt(a int, b int) int
  2040  002:  2:13 | a                   | var a int
  2041  003:  2:16 | b                   | var b int
  2042  004:  6: 6 | MulFloat            | func main.MulFloat(a float64, b float64) float64
  2043  005:  6:15 | a                   | var a float64
  2044  006:  6:18 | b                   | var b float64
  2045  007: 13: 2 | Mul__2              | func main.Mul__2(x int, y int, z int) int
  2046  008: 13: 7 | x                   | var x int
  2047  009: 13:10 | y                   | var y int
  2048  010: 13:13 | z                   | var z int
  2049  011: 18: 1 | main                | func main.main()
  2050  == uses ==
  2051  000:  2:18 | int                 | type int
  2052  001:  2:23 | int                 | type int
  2053  002:  3: 9 | a                   | var a int
  2054  003:  3:13 | b                   | var b int
  2055  004:  6:20 | float64             | type float64
  2056  005:  6:29 | float64             | type float64
  2057  006:  7: 9 | a                   | var a float64
  2058  007:  7:13 | b                   | var b float64
  2059  008: 11: 2 | MulInt              | func main.MulInt(a int, b int) int
  2060  009: 12: 2 | MulFloat            | func main.MulFloat(a float64, b float64) float64
  2061  010: 13:15 | int                 | type int
  2062  011: 13:20 | int                 | type int
  2063  012: 14:10 | x                   | var x int
  2064  013: 14:14 | y                   | var y int
  2065  014: 14:18 | z                   | var z int
  2066  015: 18: 1 | Mul                 | func main.MulInt(a int, b int) int
  2067  016: 19: 1 | Mul                 | func main.Mul__2(x int, y int, z int) int`)
  2068  
  2069  	testGopInfo(t, `
  2070  type foo struct {
  2071  }
  2072  
  2073  func (a *foo) mulInt(b int) *foo {
  2074  	return a
  2075  }
  2076  
  2077  func (a *foo) mulFoo(b *foo) *foo {
  2078  	return a
  2079  }
  2080  
  2081  func (foo).mul = (
  2082  	(foo).mulInt
  2083  	(foo).mulFoo
  2084  )
  2085  
  2086  var a, b *foo
  2087  var c = a.mul(100)
  2088  var d = a.mul(c)
  2089  `, ``, `== types ==
  2090  000:  0: 0 | ".mulInt,.mulFoo"   *ast.BasicLit                  | value   : untyped string = ".mulInt,.mulFoo" | constant
  2091  001:  2:10 | struct {
  2092  }          *ast.StructType                | type    : struct{} | type
  2093  002:  5:10 | foo                 *ast.Ident                     | type    : main.foo | type
  2094  003:  5:24 | int                 *ast.Ident                     | type    : int | type
  2095  004:  5:29 | *foo                *ast.StarExpr                  | type    : *main.foo | type
  2096  005:  5:30 | foo                 *ast.Ident                     | type    : main.foo | type
  2097  006:  6: 9 | a                   *ast.Ident                     | var     : *main.foo | variable
  2098  007:  9:10 | foo                 *ast.Ident                     | type    : main.foo | type
  2099  008:  9:24 | *foo                *ast.StarExpr                  | type    : *main.foo | type
  2100  009:  9:25 | foo                 *ast.Ident                     | type    : main.foo | type
  2101  010:  9:30 | *foo                *ast.StarExpr                  | type    : *main.foo | type
  2102  011:  9:31 | foo                 *ast.Ident                     | type    : main.foo | type
  2103  012: 10: 9 | a                   *ast.Ident                     | var     : *main.foo | variable
  2104  013: 18:10 | *foo                *ast.StarExpr                  | type    : *main.foo | type
  2105  014: 18:11 | foo                 *ast.Ident                     | type    : main.foo | type
  2106  015: 19: 9 | a                   *ast.Ident                     | var     : *main.foo | variable
  2107  016: 19: 9 | a.mul               *ast.SelectorExpr              | value   : func(b int) *main.foo | value
  2108  017: 19: 9 | a.mul(100)          *ast.CallExpr                  | value   : *main.foo | value
  2109  018: 19:15 | 100                 *ast.BasicLit                  | value   : untyped int = 100 | constant
  2110  019: 20: 9 | a                   *ast.Ident                     | var     : *main.foo | variable
  2111  020: 20: 9 | a.mul               *ast.SelectorExpr              | value   : func(b *main.foo) *main.foo | value
  2112  021: 20: 9 | a.mul(c)            *ast.CallExpr                  | value   : *main.foo | value
  2113  022: 20:15 | c                   *ast.Ident                     | var     : *main.foo | variable
  2114  == defs ==
  2115  000:  0: 0 | Gopo_foo_mul        | const main.Gopo_foo_mul untyped string
  2116  001:  2: 6 | foo                 | type main.foo struct{}
  2117  002:  5: 7 | a                   | var a *main.foo
  2118  003:  5:15 | mulInt              | func (*main.foo).mulInt(b int) *main.foo
  2119  004:  5:22 | b                   | var b int
  2120  005:  9: 7 | a                   | var a *main.foo
  2121  006:  9:15 | mulFoo              | func (*main.foo).mulFoo(b *main.foo) *main.foo
  2122  007:  9:22 | b                   | var b *main.foo
  2123  008: 18: 5 | a                   | var main.a *main.foo
  2124  009: 18: 8 | b                   | var main.b *main.foo
  2125  010: 19: 5 | c                   | var main.c *main.foo
  2126  011: 20: 5 | d                   | var main.d *main.foo
  2127  == uses ==
  2128  000:  5:10 | foo                 | type main.foo struct{}
  2129  001:  5:24 | int                 | type int
  2130  002:  5:30 | foo                 | type main.foo struct{}
  2131  003:  6: 9 | a                   | var a *main.foo
  2132  004:  9:10 | foo                 | type main.foo struct{}
  2133  005:  9:25 | foo                 | type main.foo struct{}
  2134  006:  9:31 | foo                 | type main.foo struct{}
  2135  007: 10: 9 | a                   | var a *main.foo
  2136  008: 13: 7 | foo                 | type main.foo struct{}
  2137  009: 14: 3 | foo                 | type main.foo struct{}
  2138  010: 14: 8 | mulInt              | func (*main.foo).mulInt(b int) *main.foo
  2139  011: 15: 3 | foo                 | type main.foo struct{}
  2140  012: 15: 8 | mulFoo              | func (*main.foo).mulFoo(b *main.foo) *main.foo
  2141  013: 18:11 | foo                 | type main.foo struct{}
  2142  014: 19: 9 | a                   | var main.a *main.foo
  2143  015: 19:11 | mul                 | func (*main.foo).mulInt(b int) *main.foo
  2144  016: 20: 9 | a                   | var main.a *main.foo
  2145  017: 20:11 | mul                 | func (*main.foo).mulFoo(b *main.foo) *main.foo
  2146  018: 20:15 | c                   | var main.c *main.foo`)
  2147  }