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 }