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  }