func TestExportedType(t *testing.T) { tests := []struct { typString string exp bool }{ {"int", true}, {"string", false}, // references the shadowed builtin "string" {"T", true}, {"t", false}, {"*T", true}, {"*t", false}, {"map[int]complex128", true}, } for _, test := range tests { src := `package foo; type T int; type t int; type string struct{}` fset := token.NewFileSet() file, err := parser.ParseFile(fset, "foo.go", src, 0) if err != nil { t.Fatalf("Parsing %q: %v", src, err) } // use the package name as package path pkg, err := types.Check(file.Name.Name, fset, []*ast.File{file}) if err != nil { t.Fatalf("Type checking %q: %v", src, err) } tv, err := types.Eval(fset, pkg, token.NoPos, test.typString) if err != nil { t.Errorf("types.Eval(%q): %v", test.typString, err) continue } if got := exportedType(tv.Type); got != test.exp { t.Errorf("exportedType(%v) = %t, want %t", tv.Type, got, test.exp) } } }
func TestDemo(ot *testing.T) { importPath := "github.com/bronze1man/kmg/kmgGoSource" kmgCmd.MustRun("kmg go test -i " + importPath) pkgDir := kmgConfig.DefaultEnv().MustGetPathFromImportPath(importPath) fset := token.NewFileSet() astPkgMap, err := parser.ParseDir(fset, pkgDir, nil, 0) if err != nil { panic(err) } astPkg := astPkgMap["kmgGoSource_test"] astFileList := []*ast.File{} for _, file := range astPkg.Files { astFileList = append(astFileList, file) } //os.Chdir(kmgConfig.DefaultEnv().ProjectPath) pkg, err := types.Check(pkgDir, fset, astFileList) if err != nil { panic(err) } funcA := pkg.Scope().Lookup("FuncA") recvPkg := types.NewPackage("github.com/bronze1man/kmg/kmgGoSource", "kmgGoSource") kmgDebug.Println(types.TypeString(recvPkg, funcA.Type())) funTypParams := funcA.Type().(*types.Signature).Params() for i := 0; i < funTypParams.Len(); i++ { kmgDebug.Println(funTypParams.At(i).Name()) kmgDebug.Println(funTypParams.At(i).Type().String()) } //for _,p:=range funcA.Type().(*types.Signature).Params(). //kmgDebug.Println(funcA.Type().(*types.Signature).Params().String()) }
func ParsePackage(name, dir string) (*types.Package, *token.FileSet) { fset := token.NewFileSet() pkgs, err := parser.ParseDir(fset, dir, fileFilter, parser.DeclarationErrors) astFiles := []*ast.File{} for _, pkg := range pkgs { for _, f := range pkg.Files { astFiles = append(astFiles, f) } } tPackage, err := types.Check(name, fset, astFiles) if err != nil { log.Fatal(err) } if !tPackage.Complete() { log.Fatal("Parsing of package incomplete.") } return tPackage, fset }
func gotypes(data []byte) (err error) { defer func() { x := recover() if x != nil { if str, ok := x.(string); ok && strings.Contains(str, "not an Int") { // https://github.com/golang/go/issues/11325 err = errors.New(str) return } panic(x) } }() fset := token.NewFileSet() var f *ast.File f, err = parser.ParseFile(fset, "src.go", data, parser.ParseComments|parser.DeclarationErrors|parser.AllErrors) if err != nil { return } _, err = types.Check("pkg", fset, []*ast.File{f}) if err != nil { return } return }
func (w *World) CompilePackage(fset *token.FileSet, files []*ast.File, pkgpath string) (Code, error) { pkgFiles := make(map[string]*ast.File) for _, f := range files { pkgFiles[f.Name.Name] = f } //pkg, err := ast.NewPackage(fset, pkgFiles, srcImporter, types.Universe) pkg, err := types.Check(files[0].Name.String(), fset, files) if err != nil { return nil, err } if pkg == nil { return nil, errors.New("could not create an AST package out of ast.Files") } switch g_visiting[pkgpath] { case done: return &pkgCode{w, make(code, 0)}, nil case visiting: //fmt.Printf("** package dependency cycle **\n") return nil, errors.New("package dependency cycle") } g_visiting[pkgpath] = visiting // create a new scope in which to process this new package imports := []*ast.ImportSpec{} for _, f := range files { imports = append(imports, f.Imports...) } for _, imp := range imports { path, _ := strconv.Unquote(imp.Path.Value) if _, ok := universe.pkgs[path]; ok { // already compiled continue } imp_files, err := findPkgFiles(path) if err != nil { return nil, errors.New(fmt.Sprintf("could not find files for package [%s]", path)) } code, err := w.CompilePackage(fset, imp_files, path) if err != nil { return nil, err } _, err = code.Run() if err != nil { return nil, err } } prev_scope := w.scope w.scope = w.scope.ChildScope() w.scope.global = true defer func() { g_visiting[pkgpath] = done // add this scope (the package's scope) to the lookup-table of packages universe.pkgs[pkgpath] = w.scope // restore the previous scope w.scope.exit() if pkgpath != "main" { w.scope = prev_scope } }() decls := make([]ast.Decl, 0) for _, f := range files { decls = append(decls, f.Decls...) } code, err := w.CompileDeclList(fset, decls) if err != nil { return nil, err } _, err = code.Run() if err != nil { return nil, err } //FIXME: make sure all the imports are used at this point. { // store the init function (if any) for later use init_code, init_err := w.Compile(fset, "init()") if init_code != nil { if init_err == nil || init_err != nil { w.inits = append(w.inits, init_code) } } } return code, err }