@@ -2,20 +2,15 @@ package gen
2
2
3
3
import (
4
4
"errors"
5
- "fmt"
6
5
"io"
7
6
"path/filepath"
8
- "regexp"
9
- "strconv"
10
7
"strings"
11
8
12
9
"kcl-lang.io/kcl-go/pkg/loader"
13
- "kcl-lang.io/kcl-go/pkg/logger"
14
10
)
15
11
16
12
type GenKclOptions struct {
17
13
Mode Mode
18
- ParseFromTag bool
19
14
CastingOption castingOption
20
15
UseIntegersForNumbers bool
21
16
}
@@ -104,180 +99,3 @@ func (k *kclGenerator) GenSchema(w io.Writer, filename string, src interface{})
104
99
return errors .New ("unknown mode" )
105
100
}
106
101
}
107
-
108
- func (k * kclGenerator ) genSchemaFromGoStruct (w io.Writer , filename string , src interface {}) error {
109
- fmt .Fprintln (w )
110
- goStructs , err := ParseGoSourceCode (filename , src )
111
- if err != nil {
112
- return err
113
- }
114
- for _ , goStruct := range goStructs {
115
- fmt .Fprintf (w , "schema %s:\n " , goStruct .Name )
116
- if goStruct .StructComment != "" {
117
- fmt .Fprintf (w , " \" \" \" %s\" \" \" \n " , goStruct .StructComment )
118
- }
119
- for _ , field := range goStruct .Fields {
120
- kclFieldName , kclFieldType , err := k .GetTypeName (field )
121
- if err != nil {
122
- logger .GetLogger ().Warningf ("get struct tag key kcl info err: %s, will generate kcl schema from the struct field metadata data, field info %#v" , err .Error (), field )
123
- kclFieldName , kclFieldType = k .GetKclTypeFromStructField (field )
124
- }
125
- fmt .Fprintf (w , " %s: %s\n " , kclFieldName , kclFieldType )
126
- }
127
- fmt .Fprintf (w , "\n " )
128
- }
129
- return nil
130
- }
131
-
132
- func (k * kclGenerator ) GetTypeName (f * GoStructField ) (string , string , error ) {
133
- if k .opts .ParseFromTag {
134
- return k .parserGoStructFieldTag (f .FieldTag )
135
- }
136
- fieldName , fieldType := k .GetKclTypeFromStructField (f )
137
- return fieldName , fieldType , nil
138
- }
139
-
140
- func (k * kclGenerator ) parserGoStructFieldTag (tag string ) (string , string , error ) {
141
- tagMap := make (map [string ]string , 0 )
142
- sp := strings .Split (tag , "`" )
143
- if len (sp ) == 1 {
144
- return "" , "" , errors .New ("this field not found tag string like ``" )
145
- }
146
- value , ok := k .Lookup (sp [1 ], "kcl" )
147
- if ! ok {
148
- return "" , "" , errors .New ("not found tag key named kcl" )
149
- }
150
- reg := "name=.*,type=.*"
151
- match , err := regexp .Match (reg , []byte (value ))
152
- if err != nil {
153
- return "" , "" , err
154
- }
155
- if ! match {
156
- return "" , "" , errors .New ("don't match the kcl tag info, the tag info style is name=NAME,type=TYPE" )
157
- }
158
- tagInfo := strings .Split (value , "," )
159
- for _ , s := range tagInfo {
160
- t := strings .Split (s , "=" )
161
- tagMap [t [0 ]] = t [1 ]
162
- }
163
- fieldType := tagMap ["type" ]
164
- if strings .Contains (tagMap ["type" ], ")|" ) {
165
- typeUnionList := strings .Split (tagMap ["type" ], "|" )
166
- var ss []string
167
- for _ , u := range typeUnionList {
168
- _ , _ , litValue := k .isLitType (u )
169
- ss = append (ss , litValue )
170
- }
171
- fieldType = strings .Join (ss , "|" )
172
- }
173
- return tagMap ["name" ], fieldType , nil
174
- }
175
-
176
- func (k * kclGenerator ) GetKclTypeFromStructField (f * GoStructField ) (string , string ) {
177
- return f .FieldName , k .isLitGoType (f .FieldType )
178
- }
179
-
180
- func (k * kclGenerator ) isLitType (fieldType string ) (ok bool , basicTyp , litValue string ) {
181
- if ! strings .HasSuffix (fieldType , ")" ) {
182
- return
183
- }
184
-
185
- i := strings .Index (fieldType , "(" ) + 1
186
- j := strings .LastIndex (fieldType , ")" )
187
-
188
- switch {
189
- case strings .HasPrefix (fieldType , "bool(" ):
190
- return true , "bool" , fieldType [i :j ]
191
- case strings .HasPrefix (fieldType , "int(" ):
192
- return true , "int" , fieldType [i :j ]
193
- case strings .HasPrefix (fieldType , "float(" ):
194
- return true , "float" , fieldType [i :j ]
195
- case strings .HasPrefix (fieldType , "str(" ):
196
- return true , "str" , strconv .Quote (fieldType [i :j ])
197
- }
198
- return
199
- }
200
-
201
- func (k * kclGenerator ) isLitGoType (fieldType string ) string {
202
- switch fieldType {
203
- case "int" , "int32" , "int64" :
204
- return "int"
205
- case "float" , "float64" :
206
- return "float"
207
- case "string" :
208
- return "str"
209
- case "bool" :
210
- return "bool"
211
- case "interface{}" :
212
- return "any"
213
- default :
214
- if strings .HasPrefix (fieldType , "*" ) {
215
- i := strings .Index (fieldType , "*" ) + 1
216
- return k .isLitGoType (fieldType [i :])
217
- }
218
- if strings .HasPrefix (fieldType , "map" ) {
219
- i := strings .Index (fieldType , "[" ) + 1
220
- j := strings .Index (fieldType , "]" )
221
- return fmt .Sprintf ("{%s:%s}" , k .isLitGoType (fieldType [i :j ]), k .isLitGoType (fieldType [j + 1 :]))
222
- }
223
- if strings .HasPrefix (fieldType , "[]" ) {
224
- i := strings .Index (fieldType , "]" ) + 1
225
- return fmt .Sprintf ("[%s]" , k .isLitGoType (fieldType [i :]))
226
- }
227
- return fieldType
228
- }
229
- }
230
-
231
- func (k * kclGenerator ) Lookup (tag , key string ) (value string , ok bool ) {
232
- // When modifying this code, also update the validateStructTag code
233
- // in cmd/vet/structtag.go.
234
-
235
- for tag != "" {
236
- // Skip leading space.
237
- i := 0
238
- for i < len (tag ) && tag [i ] == ' ' {
239
- i ++
240
- }
241
- tag = tag [i :]
242
- if tag == "" {
243
- break
244
- }
245
-
246
- // Scan to colon. A space, a quote or a control character is a syntax error.
247
- // Strictly speaking, control chars include the range [0x7f, 0x9f], not just
248
- // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
249
- // as it is simpler to inspect the tag's bytes than the tag's runes.
250
- i = 0
251
- for i < len (tag ) && tag [i ] > ' ' && tag [i ] != ':' && tag [i ] != '"' && tag [i ] != 0x7f {
252
- i ++
253
- }
254
- if i == 0 || i + 1 >= len (tag ) || tag [i ] != ':' || tag [i + 1 ] != '"' {
255
- break
256
- }
257
- name := string (tag [:i ])
258
- tag = tag [i + 1 :]
259
-
260
- // Scan quoted string to find value.
261
- i = 1
262
- for i < len (tag ) && tag [i ] != '"' {
263
- if tag [i ] == '\\' {
264
- i ++
265
- }
266
- i ++
267
- }
268
- if i >= len (tag ) {
269
- break
270
- }
271
- qvalue := string (tag [:i + 1 ])
272
- tag = tag [i + 1 :]
273
-
274
- if key == name {
275
- value , err := strconv .Unquote (qvalue )
276
- if err != nil {
277
- break
278
- }
279
- return value , true
280
- }
281
- }
282
- return "" , false
283
- }
0 commit comments