@@ -28,6 +28,7 @@ import (
2828 "log"
2929 "os"
3030 "reflect"
31+ "strconv"
3132 "strings"
3233)
3334
@@ -59,6 +60,8 @@ type StructInfo struct {
5960 NewStructName string
6061 Fields []FieldInfo
6162 OptionalFields []FieldInfo
63+
64+ Imports []string
6265}
6366
6467func (g * Generator ) GeneratingOptions () {
@@ -99,14 +102,19 @@ func (g *Generator) parseStruct(fileName string) bool {
99102 if structDecl , ok := typeSpec .Type .(* ast.StructType ); ok {
100103 log .Printf ("Generating Struct \" %s\" \n " , g .StructInfo .StructName )
101104 for _ , field := range structDecl .Fields .List {
105+ fieldName := ""
102106 if len (field .Names ) == 0 {
103- continue
107+ if ident , ok := field .Type .(* ast.Ident ); ok { // combined struct
108+ fieldName = ident .Name
109+ } else {
110+ continue
111+ }
112+ } else {
113+ fieldName = field .Names [0 ].Name
104114 }
105-
106115 optionIgnore := false
107116
108- fieldName := field .Names [0 ].Name
109- fieldType := field .Type .(* ast.Ident ).Name
117+ fieldType := g .getTypeName (field .Type )
110118 if field .Tag != nil {
111119 tags := strings .Replace (field .Tag .Value , "`" , "" , - 1 )
112120 tag := reflect .StructTag (tags ).Get ("opt" )
@@ -126,6 +134,8 @@ func (g *Generator) parseStruct(fileName string) bool {
126134 }
127135 log .Printf ("Generating Struct Field \" %s\" of type \" %s\" \n " , fieldName , fieldType )
128136 }
137+ // 收集 package 信息
138+ g .CollectImports (file )
129139 return true
130140 } else {
131141 log .Fatal (fmt .Sprintf ("Target[%s] type is not a struct" , g .StructInfo .StructName ))
@@ -136,7 +146,7 @@ func (g *Generator) parseStruct(fileName string) bool {
136146}
137147
138148func (g * Generator ) GenerateCodeByTemplate () {
139- tmpl , err := template .New ("options" ).Funcs (template.FuncMap {"bigCamelToSmallCamel" : stringx .BigCamelToSmallCamel }).Parse (templates .OptionsTemplateCode )
149+ tmpl , err := template .New ("options" ).Funcs (template.FuncMap {"bigCamelToSmallCamel" : stringx .BigCamelToSmallCamel , "capitalizeFirstLetter" : stringx . CapitalizeFirstLetter }).Parse (templates .OptionsTemplateCode )
140150 if err != nil {
141151 fmt .Println ("Failed to parse template:" , err )
142152 os .Exit (1 )
@@ -173,3 +183,77 @@ func (g *Generator) SetOutPath(outPath *string) {
173183 g .outPath = fileName
174184 }
175185}
186+
187+ func (g * Generator ) getTypeName (expr ast.Expr ) string {
188+ switch t := expr .(type ) {
189+ case * ast.Ident :
190+ return t .Name
191+ case * ast.SelectorExpr :
192+ return fmt .Sprintf ("%s.%s" , g .getTypeName (t .X ), t .Sel .Name )
193+ case * ast.ArrayType :
194+ if t .Len == nil {
195+ return "[]" + g .getTypeName (t .Elt )
196+ }
197+ if basicLit , ok := t .Len .(* ast.BasicLit ); ok && basicLit .Kind == token .INT {
198+ return "[" + basicLit .Value + "]" + g .getTypeName (t .Elt )
199+ } else {
200+ log .Fatalf ("Array len error: %T" , t )
201+ return ""
202+ }
203+ case * ast.MapType :
204+ return fmt .Sprintf ("map[%s]%s" , g .getTypeName (t .Key ), g .getTypeName (t .Value ))
205+ case * ast.StarExpr :
206+ return "*" + g .getTypeName (t .X )
207+ //case *ast.InterfaceType:
208+ // return "" // ignore
209+ case * ast.StructType :
210+ return "struct{}"
211+ case * ast.FuncType :
212+ return g .parseFuncType (t )
213+ case * ast.ChanType :
214+ return "chan " + g .getTypeName (t .Value )
215+ default :
216+ log .Fatalf ("Unsupported type for field: %T" , t )
217+ return ""
218+ }
219+ }
220+
221+ func (g * Generator ) parseFuncType (f * ast.FuncType ) string {
222+ var params , results []string
223+ if f .Params != nil {
224+ for _ , field := range f .Params .List {
225+ paramType := g .getTypeName (field .Type )
226+ for _ , name := range field .Names {
227+ params = append (params , fmt .Sprintf ("%s %s" , name .Name , paramType ))
228+ }
229+ }
230+ }
231+
232+ if f .Results != nil {
233+ for _ , field := range f .Results .List {
234+ resultType := g .getTypeName (field .Type )
235+ if len (field .Names ) > 0 {
236+ for _ , name := range field .Names {
237+ results = append (results , fmt .Sprintf ("%s %s" , name .Name , resultType ))
238+ }
239+ } else {
240+ results = append (results , resultType )
241+ }
242+ }
243+ }
244+
245+ if len (results ) == 1 {
246+ return fmt .Sprintf ("func(%s) %s" , strings .Join (params , ", " ), results [0 ])
247+ }
248+ return fmt .Sprintf ("func(%s) (%s)" , strings .Join (params , ", " ), strings .Join (results , ", " ))
249+ }
250+
251+ func (g * Generator ) CollectImports (file * ast.File ) {
252+ for _ , imp := range file .Imports {
253+ path , err := strconv .Unquote (imp .Path .Value )
254+ if err != nil {
255+ log .Fatalf ("Failed to unquote import path: %v" , err )
256+ }
257+ g .StructInfo .Imports = append (g .StructInfo .Imports , path )
258+ }
259+ }
0 commit comments