From c3252696edcd8bc1e6967755bc04fb3a7aa68780 Mon Sep 17 00:00:00 2001 From: visualfc Date: Tue, 12 Dec 2023 21:47:39 +0800 Subject: [PATCH 1/2] x/typesutil: testGopInfo --- x/typesutil/info_test.go | 82 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go index f69f6ddf4..c6068ef3d 100644 --- a/x/typesutil/info_test.go +++ b/x/typesutil/info_test.go @@ -23,6 +23,50 @@ import ( "github.com/goplus/mod/gopmod" ) +func parserMixedSource(fset *token.FileSet, src string, gosrc string) (*typesutil.Info, *types.Info, error) { + f, err := parser.ParseEntry(fset, "main.gop", src, parser.Config{ + Mode: parser.ParseComments, + }) + if err != nil { + return nil, nil, err + } + var gofiles []*goast.File + if len(gosrc) > 0 { + f, err := goparser.ParseFile(fset, "main.go", gosrc, goparser.ParseComments) + if err != nil { + return nil, nil, err + } + gofiles = append(gofiles, f) + } + + conf := &types.Config{} + conf.Importer = importer.Default() + chkOpts := &typesutil.Config{ + Types: types.NewPackage("main", "main"), + Fset: fset, + Mod: gopmod.Default, + } + info := &typesutil.Info{ + Types: make(map[ast.Expr]types.TypeAndValue), + Defs: make(map[*ast.Ident]types.Object), + Uses: make(map[*ast.Ident]types.Object), + Implicits: make(map[ast.Node]types.Object), + Selections: make(map[*ast.SelectorExpr]*types.Selection), + Scopes: make(map[ast.Node]*types.Scope), + } + ginfo := &types.Info{ + Types: make(map[goast.Expr]types.TypeAndValue), + Defs: make(map[*goast.Ident]types.Object), + Uses: make(map[*goast.Ident]types.Object), + Implicits: make(map[goast.Node]types.Object), + Selections: make(map[*goast.SelectorExpr]*types.Selection), + Scopes: make(map[goast.Node]*types.Scope), + } + check := typesutil.NewChecker(conf, chkOpts, ginfo, info) + err = check.Files(gofiles, []*ast.File{f}) + return info, ginfo, err +} + func parserSource(fset *token.FileSet, filename string, src interface{}, mode parser.Mode) (*typesutil.Info, error) { f, err := parser.ParseEntry(fset, filename, src, parser.Config{ Mode: mode, @@ -73,6 +117,26 @@ func parserGoSource(fset *token.FileSet, filename string, src interface{}, mode return info, err } +func testGopInfo(t *testing.T, src string, gosrc string, expect string) { + fset := token.NewFileSet() + info, _, err := parserMixedSource(fset, src, gosrc) + if err != nil { + t.Fatal("parserMixedSource error", err) + } + var list []string + list = append(list, "== types ==") + list = append(list, typesList(fset, info.Types, false)...) + list = append(list, "== defs ==") + list = append(list, defsList(fset, info.Defs, true)...) + list = append(list, "== uses ==") + list = append(list, usesList(fset, info.Uses)...) + result := strings.Join(list, "\n") + t.Log(result) + if result != expect { + t.Fatal("bad expect\n", expect) + } +} + func testInfo(t *testing.T, src interface{}) { fset := token.NewFileSet() info, err := parserSource(fset, "main.gop", src, parser.ParseComments) @@ -440,3 +504,21 @@ func test() { } `) } + +func TestGopList(t *testing.T) { + testGopInfo(t, ` +a := [100,200] +println a +`, ``, `== types == +000: 2: 7 | 100 *ast.BasicLit | value : untyped int = 100 | constant +001: 2:11 | 200 *ast.BasicLit | value : untyped int = 200 | constant +002: 3: 1 | println *ast.Ident | builtin : invalid type | built-in +003: 3: 1 | println a *ast.CallExpr | value : (n int, err error) | value +004: 3: 9 | a *ast.Ident | var : []int | variable +== defs == +000: 2: 1 | a | var a []int +001: 2: 1 | main | func main.main() +== uses == +000: 3: 1 | println | builtin println +001: 3: 9 | a | var a []int`) +} From 3b1a1de69a0ecae8e851e23a74d20a0948db2fbe Mon Sep 17 00:00:00 2001 From: visualfc Date: Tue, 12 Dec 2023 22:22:20 +0800 Subject: [PATCH 2/2] cl: compileForPhraseStmt types record define kv --- cl/stmt.go | 6 +++ x/typesutil/info_test.go | 88 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/cl/stmt.go b/cl/stmt.go index 149365ab0..8bb4a30c4 100644 --- a/cl/stmt.go +++ b/cl/stmt.go @@ -384,17 +384,23 @@ func compileForPhraseStmt(ctx *blockCtx, v *ast.ForPhraseStmt) { cb := ctx.cb comments, once := cb.BackupComments() names := make([]string, 1, 2) + defineNames := make([]*ast.Ident, 0, 2) if v.Key == nil { names[0] = "_" } else { names[0] = v.Key.Name + defineNames = append(defineNames, v.Key) } if v.Value != nil { names = append(names, v.Value.Name) + defineNames = append(defineNames, v.Value) } cb.ForRange(names...) compileExpr(ctx, v.X) cb.RangeAssignThen(v.TokPos) + if len(defineNames) > 0 { + defNames(ctx, defineNames, cb.Scope()) + } if v.Cond != nil { cb.If() compileExpr(ctx, v.Cond) diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go index c6068ef3d..1ce5a7d86 100644 --- a/x/typesutil/info_test.go +++ b/x/typesutil/info_test.go @@ -505,7 +505,7 @@ func test() { `) } -func TestGopList(t *testing.T) { +func TestSliceLit(t *testing.T) { testGopInfo(t, ` a := [100,200] println a @@ -522,3 +522,89 @@ println a 000: 3: 1 | println | builtin println 001: 3: 9 | a | var a []int`) } + +func TestForPhrase1(t *testing.T) { + testGopInfo(t, ` +sum := 0 +for x <- [1, 3, 5, 7, 11, 13, 17], x > 3 { + sum = sum + x +} +println sum +`, ``, `== types == +000: 2: 8 | 0 *ast.BasicLit | value : untyped int = 0 | constant +001: 3:11 | 1 *ast.BasicLit | value : untyped int = 1 | constant +002: 3:14 | 3 *ast.BasicLit | value : untyped int = 3 | constant +003: 3:17 | 5 *ast.BasicLit | value : untyped int = 5 | constant +004: 3:20 | 7 *ast.BasicLit | value : untyped int = 7 | constant +005: 3:23 | 11 *ast.BasicLit | value : untyped int = 11 | constant +006: 3:27 | 13 *ast.BasicLit | value : untyped int = 13 | constant +007: 3:31 | 17 *ast.BasicLit | value : untyped int = 17 | constant +008: 3:36 | x *ast.Ident | var : int | variable +009: 3:36 | x > 3 *ast.BinaryExpr | value : untyped bool | value +010: 3:40 | 3 *ast.BasicLit | value : untyped int = 3 | constant +011: 4: 2 | sum *ast.Ident | var : int | variable +012: 4: 8 | sum *ast.Ident | var : int | variable +013: 4: 8 | sum + x *ast.BinaryExpr | value : int | value +014: 4:14 | x *ast.Ident | var : int | variable +015: 6: 1 | println *ast.Ident | builtin : invalid type | built-in +016: 6: 1 | println sum *ast.CallExpr | value : (n int, err error) | value +017: 6: 9 | sum *ast.Ident | var : int | variable +== defs == +000: 2: 1 | main | func main.main() +001: 2: 1 | sum | var sum int +002: 3: 5 | x | var x int +== uses == +000: 3:36 | x | var x int +001: 4: 2 | sum | var sum int +002: 4: 8 | sum | var sum int +003: 4:14 | x | var x int +004: 6: 1 | println | builtin println +005: 6: 9 | sum | var sum int`) +} + +func TestForPhrase2(t *testing.T) { + testGopInfo(t, ` +sum := 0 +for i, x <- [1, 3, 5, 7, 11, 13, 17], i%2 == 1 && x > 3 { + sum = sum + x +} +println sum +`, ``, `== types == +000: 2: 8 | 0 *ast.BasicLit | value : untyped int = 0 | constant +001: 3:14 | 1 *ast.BasicLit | value : untyped int = 1 | constant +002: 3:17 | 3 *ast.BasicLit | value : untyped int = 3 | constant +003: 3:20 | 5 *ast.BasicLit | value : untyped int = 5 | constant +004: 3:23 | 7 *ast.BasicLit | value : untyped int = 7 | constant +005: 3:26 | 11 *ast.BasicLit | value : untyped int = 11 | constant +006: 3:30 | 13 *ast.BasicLit | value : untyped int = 13 | constant +007: 3:34 | 17 *ast.BasicLit | value : untyped int = 17 | constant +008: 3:39 | i *ast.Ident | var : int | variable +009: 3:39 | i % 2 *ast.BinaryExpr | value : int | value +010: 3:39 | i%2 == 1 *ast.BinaryExpr | value : untyped bool | value +011: 3:39 | i%2 == 1 && x > 3 *ast.BinaryExpr | value : untyped bool | value +012: 3:41 | 2 *ast.BasicLit | value : untyped int = 2 | constant +013: 3:46 | 1 *ast.BasicLit | value : untyped int = 1 | constant +014: 3:51 | x *ast.Ident | var : int | variable +015: 3:51 | x > 3 *ast.BinaryExpr | value : untyped bool | value +016: 3:55 | 3 *ast.BasicLit | value : untyped int = 3 | constant +017: 4: 2 | sum *ast.Ident | var : int | variable +018: 4: 8 | sum *ast.Ident | var : int | variable +019: 4: 8 | sum + x *ast.BinaryExpr | value : int | value +020: 4:14 | x *ast.Ident | var : int | variable +021: 6: 1 | println *ast.Ident | builtin : invalid type | built-in +022: 6: 1 | println sum *ast.CallExpr | value : (n int, err error) | value +023: 6: 9 | sum *ast.Ident | var : int | variable +== defs == +000: 2: 1 | main | func main.main() +001: 2: 1 | sum | var sum int +002: 3: 5 | i | var i int +003: 3: 8 | x | var x int +== uses == +000: 3:39 | i | var i int +001: 3:51 | x | var x int +002: 4: 2 | sum | var sum int +003: 4: 8 | sum | var sum int +004: 4:14 | x | var x int +005: 6: 1 | println | builtin println +006: 6: 9 | sum | var sum int`) +}