Skip to content

Commit

Permalink
Merge pull request #1575 from visualfc/typesutil_gop
Browse files Browse the repository at this point in the history
cl: compileForPhraseStmt types record define kv
  • Loading branch information
xushiwei authored Dec 14, 2023
2 parents 4cf8b5e + 3b1a1de commit a205ad4
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cl/stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
168 changes: 168 additions & 0 deletions x/typesutil/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -440,3 +504,107 @@ func test() {
}
`)
}

func TestSliceLit(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`)
}

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`)
}

0 comments on commit a205ad4

Please sign in to comment.