github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgGoSource/types.go (about) 1 package kmgGoSource 2 3 import ( 4 "fmt" 5 "go/ast" 6 "path" 7 "reflect" 8 9 "github.com/bronze1man/kmg/kmgCmd" 10 _ "golang.org/x/tools/go/gcimporter" 11 "golang.org/x/tools/go/types" 12 ) 13 14 func MustGetGoTypesFromReflect(typ reflect.Type) types.Type { 15 switch typ.Kind() { 16 case reflect.Ptr: 17 return types.NewPointer(MustGetGoTypesFromReflect(typ.Elem())) 18 case reflect.Struct: 19 if typ.PkgPath() == "" { 20 panic(fmt.Errorf(`[MustGetGoTypesFromReflect] Not implement typ.PkgPath=="" name[%s]`, 21 typ.Name())) 22 } 23 //此处没有办法获取Package的实际Package名称 24 pkg := MustNewGoTypesMainPackageFromImportPath(typ.PkgPath()) 25 typObj := pkg.Scope().Lookup(typ.Name()) 26 return typObj.Type() 27 default: 28 panic(fmt.Errorf("[MustGetGoTypesFromReflect] Not implement Kind [%s]", 29 typ.Kind().String())) 30 } 31 } 32 33 // 类型名称定义 34 // github.com/bronze1man/kmg/kmgGoSource/testPackage.Demo 35 func MustGetGoTypeFromPkgPathAndTypeName(pkgPath string, typ string) types.Type { 36 pkg := MustNewGoTypesMainPackageFromImportPath(pkgPath) 37 typObj := pkg.Scope().Lookup(typ) 38 return typObj.Type() 39 } 40 41 func MustWriteGoTypes(thisPackagePath string, typi types.Type) (s string, addPkgPathList []string) { 42 switch typ := typi.(type) { 43 case *types.Basic: 44 return typ.String(), nil 45 case *types.Named: 46 if typ.Obj().Pkg() == nil { 47 return typ.Obj().Name(), nil 48 } 49 typPkgPath := typ.Obj().Pkg().Path() 50 if thisPackagePath == typPkgPath { 51 return typ.Obj().Name(), nil 52 } 53 return path.Base(typPkgPath) + "." + typ.Obj().Name(), []string{typPkgPath} 54 case *types.Pointer: 55 s, addPkgPathList = MustWriteGoTypes(thisPackagePath, typ.Elem()) 56 return "*" + s, addPkgPathList 57 case *types.Slice: 58 s, addPkgPathList = MustWriteGoTypes(thisPackagePath, typ.Elem()) 59 return "[]" + s, addPkgPathList 60 case *types.Interface: 61 return typ.String(), nil 62 //s, addPkgPathList = MustWriteGoTypes(thisPackagePath, typ.Elem()) 63 //return "[]" + s, addPkgPathList 64 default: 65 panic(fmt.Errorf("[MustWriteGoTypes] Not implement go/types [%T] [%s]", 66 typi, typi.String())) 67 } 68 return "", nil 69 } 70 71 func MustGetMethodListFromGoTypes(typ types.Type) (output []*types.Selection) { 72 methodSet := types.NewMethodSet(typ) 73 num := methodSet.Len() 74 if num == 0 { 75 return nil 76 } 77 output = make([]*types.Selection, num) 78 for i := range output { 79 output[i] = methodSet.At(i) 80 } 81 return output 82 } 83 84 //返回这个导入路径的主Package的types.Package对象 85 //TODO 解决测试package的问题 86 func MustNewGoTypesMainPackageFromImportPath(importPath string) *types.Package { 87 //TODO 去掉可编译要求? 88 kmgCmd.CmdSlice([]string{"kmg", "go", "install", importPath}).MustRun() 89 kmgCmd.CmdSlice([]string{"kmg", "go", "test", "-i", importPath}).MustRun() 90 //TODO 解决需要预先创建pkg的问题. 91 astPkg, fset := MustNewMainAstPackageFromImportPath(importPath) 92 astFileList := []*ast.File{} 93 for _, file := range astPkg.Files { 94 astFileList = append(astFileList, file) 95 } 96 //os.Chdir(kmgConfig.DefaultEnv().ProjectPath) 97 conf := &types.Config{ 98 IgnoreFuncBodies: true, 99 } 100 pkg, err := conf.Check(importPath, fset, astFileList, nil) 101 if err != nil { 102 panic(err) 103 } 104 return pkg 105 }