github.com/goplus/gop@v1.2.6/x/typesutil/check_test.go (about) 1 package typesutil_test 2 3 import ( 4 goast "go/ast" 5 "go/importer" 6 goparser "go/parser" 7 "go/types" 8 "log" 9 "os" 10 "path/filepath" 11 "testing" 12 13 "github.com/goplus/gop/ast" 14 "github.com/goplus/gop/parser" 15 "github.com/goplus/gop/token" 16 "github.com/goplus/gop/x/typesutil" 17 "github.com/goplus/mod/gopmod" 18 ) 19 20 func init() { 21 if os.Getenv("GOPROOT") == "" { 22 dir, _ := os.Getwd() 23 os.Setenv("GOPROOT", filepath.Clean(filepath.Join(dir, "./../.."))) 24 } 25 typesutil.SetDebug(typesutil.DbgFlagDefault) 26 } 27 28 func loadFiles(fset *token.FileSet, file string, src interface{}, goxfile string, goxsrc interface{}, gofile string, gosrc interface{}) ([]*ast.File, []*goast.File, error) { 29 var files []*ast.File 30 var gofiles []*goast.File 31 if file != "" { 32 f, err := parser.ParseFile(fset, file, src, 0) 33 if err != nil { 34 return nil, nil, err 35 } 36 files = append(files, f) 37 } 38 if goxfile != "" { 39 f, err := parser.ParseFile(fset, goxfile, goxsrc, parser.ParseGoPlusClass) 40 if err != nil { 41 return nil, nil, err 42 } 43 files = append(files, f) 44 } 45 if gofile != "" { 46 f, err := goparser.ParseFile(fset, gofile, gosrc, 0) 47 if err != nil { 48 return nil, nil, err 49 } 50 gofiles = append(gofiles, f) 51 } 52 return files, gofiles, nil 53 } 54 55 func checkFiles(fset *token.FileSet, file string, src interface{}, goxfile string, goxsrc interface{}, gofile string, gosrc interface{}) (*typesutil.Info, *types.Info, error) { 56 files, gofiles, err := loadFiles(fset, file, src, goxfile, goxsrc, gofile, gosrc) 57 if err != nil { 58 return nil, nil, err 59 } 60 return checkInfo(fset, files, gofiles) 61 } 62 63 func checkInfo(fset *token.FileSet, files []*ast.File, gofiles []*goast.File) (*typesutil.Info, *types.Info, error) { 64 conf := &types.Config{} 65 conf.Importer = importer.Default() 66 conf.Error = func(err error) { 67 log.Println(err) 68 } 69 chkOpts := &typesutil.Config{ 70 Types: types.NewPackage("main", "main"), 71 Fset: fset, 72 Mod: gopmod.Default, 73 } 74 info := &typesutil.Info{ 75 Types: make(map[ast.Expr]types.TypeAndValue), 76 Defs: make(map[*ast.Ident]types.Object), 77 Uses: make(map[*ast.Ident]types.Object), 78 Implicits: make(map[ast.Node]types.Object), 79 Selections: make(map[*ast.SelectorExpr]*types.Selection), 80 Scopes: make(map[ast.Node]*types.Scope), 81 Overloads: make(map[*ast.Ident][]types.Object), 82 } 83 ginfo := &types.Info{ 84 Types: make(map[goast.Expr]types.TypeAndValue), 85 Defs: make(map[*goast.Ident]types.Object), 86 Uses: make(map[*goast.Ident]types.Object), 87 Implicits: make(map[goast.Node]types.Object), 88 Selections: make(map[*goast.SelectorExpr]*types.Selection), 89 Scopes: make(map[goast.Node]*types.Scope), 90 } 91 check := typesutil.NewChecker(conf, chkOpts, ginfo, info) 92 err := check.Files(gofiles, files) 93 return info, ginfo, err 94 } 95 96 func TestCheckFiles(t *testing.T) { 97 fset := token.NewFileSet() 98 info, ginfo, err := checkFiles(fset, "main.gop", ` 99 import "fmt" 100 101 type Point struct { 102 x int 103 y int 104 } 105 pt := &Point{} 106 pt.x = 100 107 pt.y = 200 108 fmt.Println(pt) 109 110 gopt := GoPoint{100,200} 111 gopt.Test() 112 gotest() 113 fmt.Println(GoValue) 114 fmt.Println(&Rect{100,200}) 115 `, "Rect.gox", ` 116 var ( 117 x int 118 y int 119 ) 120 `, "util.go", `package main 121 var GoValue string 122 type GoPoint struct { 123 x int 124 y int 125 } 126 func (p *GoPoint) Test() { 127 } 128 func gotest() { 129 } 130 `) 131 if err != nil || info == nil || ginfo == nil { 132 t.Fatalf("check failed: %v", err) 133 } 134 135 for def, obj := range info.Defs { 136 o := info.ObjectOf(def) 137 if o != obj { 138 t.Fatal("bad obj", o) 139 } 140 } 141 for use, obj := range info.Uses { 142 o := info.ObjectOf(use) 143 if o.String() != obj.String() { 144 t.Fatal("bad obj", o) 145 } 146 typ := info.TypeOf(use) 147 if typ.String() != obj.Type().String() { 148 t.Fatal("bad typ", typ) 149 } 150 } 151 152 } 153 154 func TestCheckGoFiles(t *testing.T) { 155 fset := token.NewFileSet() 156 info, ginfo, err := checkFiles(fset, "", "", "", "", "main.go", `package main 157 type GoPoint struct { 158 x int 159 y int 160 } 161 func main() { 162 } 163 `) 164 if err != nil || info == nil || ginfo == nil { 165 t.Fatalf("check failed: %v", err) 166 } 167 } 168 169 func TestCheckError(t *testing.T) { 170 fset := token.NewFileSet() 171 _, _, err := checkFiles(fset, "main.gop", ` 172 type Point struct { 173 x int 174 y int 175 } 176 pt := &Point1{} 177 println(pt) 178 `, "", "", "", "") 179 if err == nil { 180 t.Fatal("no error") 181 } 182 _, _, err = checkFiles(fset, "main.gop", ` 183 var i int = "hello" 184 `, "", "", "", "") 185 if err == nil { 186 t.Fatal("no error") 187 } 188 } 189 190 func TestBadFile(t *testing.T) { 191 conf := &types.Config{} 192 opt := &typesutil.Config{} 193 opt.Fset = token.NewFileSet() 194 opt.Types = types.NewPackage("", "main") 195 checker := typesutil.NewChecker(conf, opt, nil, nil) 196 _ = checker.Files([]*goast.File{{Name: goast.NewIdent("main")}}, 197 []*ast.File{{Name: ast.NewIdent("main")}}) 198 }