github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgGoSource/Package.go (about) 1 package kmgGoSource 2 3 import ( 4 "go/ast" 5 "go/doc" 6 "go/parser" 7 "go/token" 8 "strings" 9 10 "github.com/bronze1man/kmg/kmgConfig" 11 ) 12 13 // 这个东西目前 有2个问题, 14 // 1.从ast生成回Type. 15 // 2.运行必须能反射. 16 // 3.import似乎很难处理. 17 // 4.把各种类型都加入复杂度比较高(生成struct的时候还是要使用的.) 18 19 // golang.org/x/tools/go/types 和 golang.org/x/tools/go/ssa 的问题 20 // 1.接口过度复杂和奇葩, 学习成本高. 21 // 2.写回类型的时候没有import信息 22 23 //表示一个golang里面的package 24 type Package struct { 25 docPkg *doc.Package 26 } 27 28 func (pkg *Package) getDocTypeByName(name string) *doc.Type { 29 for _, docType := range pkg.docPkg.Types { 30 if docType.Name == name { 31 return docType 32 } 33 } 34 return nil 35 } 36 37 // 填在import的那个路径的值 38 func (pkg *Package) PkgPath() string { 39 return pkg.docPkg.ImportPath 40 } 41 42 // package 的名字,填在 package 那个地方的名字 43 // package kmgReflect 44 func (pkg *Package) Name() string { 45 return pkg.docPkg.Name 46 } 47 48 //使用importPath获取一个Package, 49 // 仅支持导入一个目录作为一个package 50 // 只导入一个package里面的主package,xxx_test不导入. 51 // 注意: 需要源代码,需要使用kmg配置GOPATH 52 func MustNewPackageFromImportPath(importPath string) *Package { 53 astPkg, _ := MustNewMainAstPackageFromImportPath(importPath) 54 docPkg := doc.New(astPkg, importPath, doc.AllMethods) 55 return &Package{ 56 docPkg: docPkg, 57 } 58 } 59 60 func GetImportPathListFromFile(filepath string) (importPathList []string, err error) { 61 fset := token.NewFileSet() 62 pkgs, err := parser.ParseFile(fset, filepath, nil, parser.ImportsOnly) 63 if err != nil { 64 return nil, err 65 } 66 for _, thisImport := range pkgs.Imports { 67 //目前没有找到反序列化golang的双引号的方法,暂时使用简单的办法 68 pkgName, err := UnquoteGolangDoubleQuote(thisImport.Path.Value) 69 if err != nil { 70 return nil, err 71 } 72 importPathList = append(importPathList, pkgName) 73 } 74 return importPathList, nil 75 } 76 77 func MustNewMainAstPackageFromImportPath(importPath string) (pkg *ast.Package, fset *token.FileSet) { 78 pkgDir := kmgConfig.DefaultEnv().MustGetPathFromImportPath(importPath) 79 fset = token.NewFileSet() 80 astPkgMap, err := parser.ParseDir(fset, pkgDir, nil, 0) 81 if err != nil { 82 panic(err) 83 } 84 if len(astPkgMap) == 0 { 85 panic("can not found package") 86 } 87 for name, astPkg := range astPkgMap { 88 if strings.HasSuffix(name, "_test") { 89 continue 90 } 91 return astPkg, fset 92 } 93 panic("impossible execute path") 94 }