8
8
from PyQt5 .QtWidgets import QLabel , QComboBox , QMessageBox
9
9
10
10
# 验证json字符串是否合法
11
- from code_top import get_top_code_list
11
+ from template_code import get_top_code_dict
12
12
13
- from code_top import get_top_code_dict
13
+ msg_box_ui = None
14
14
15
15
16
16
def is_json (myjson ):
@@ -29,44 +29,198 @@ def jformat(inp):
29
29
return outp
30
30
31
31
32
+ def check_level_type (t ):
33
+ if t in ('int' , 'double' , 'bool' , 'Object' ):
34
+ # 普通数据类型
35
+ return 1
36
+ if t == 'String' :
37
+ # 字符串类型
38
+ return 2
39
+ if t .startswith ('List<' ):
40
+ # 数组类型
41
+ return 3
42
+ # 字典类型
43
+ return 4
44
+
45
+
46
+ def list_code_loop (code , count , total , n , ct ):
47
+ template = r"""
48
+ ${list_count}${class_type}${>count} ${name}${current_child} = [];
49
+ for (var ${name}${current_items} in ${name}${parent_items}){
50
+ ${loop}
51
+ ${name}${current_child}.add(${name}${child_child});
52
+ }
53
+ """
54
+
55
+ list_count = 'List<' * (total - count )
56
+ ab_count = '>' * (total - count )
57
+
58
+ current_child = 'Child' * count
59
+ child_child = 'Child' * (count + 1 )
60
+
61
+ current_items = 'Item' * (count + 1 )
62
+ parent_items = 'Item' * count
63
+
64
+ fragment = template \
65
+ .replace ('${list_count}' , list_count ) \
66
+ .replace ('${class_type}' , ct ) \
67
+ .replace ('${>count}' , ab_count ) \
68
+ .replace ('${name}' , n ) \
69
+ .replace ('${current_child}' , current_child ) \
70
+ .replace ('${child_child}' , child_child ) \
71
+ .replace ('${current_items}' , current_items ) \
72
+ .replace ('${parent_items}' , parent_items )
73
+
74
+ if code == '' :
75
+ return fragment
76
+ else :
77
+ return code .replace ('${loop}' , fragment )
78
+
79
+
80
+ # 向代码模板中插入变量
81
+ def build_list_construction (f , t , n ):
82
+ class_type = t .replace ('List<' , '' ).replace ('>' , '' )
83
+
84
+ list_loop = '[];\n '
85
+ assert isinstance (t , str )
86
+
87
+ code = ''
88
+
89
+ total = t .count ('>' )
90
+ for i in range (total ):
91
+ code = list_code_loop (code , i , total , n , class_type )
92
+
93
+ # 嵌套模板的后续处理
94
+ code = code .replace ('%s%s' % (n , 'Child' * total ), 'new %s(%s%s)' % (class_type , n , ('Item' * total )))
95
+ code = code [code .find (';' ) + 1 :]
96
+ code = code .replace ('%s){' % n , 'jsonRes[\' %s\' ]){' % n ).replace ('${loop}' , '' )
97
+
98
+ return list_loop + code
99
+
100
+
101
+ def add_param_to_code (code , param ):
102
+ (f , t , n ) = param
103
+
104
+ # 先按照基本数据类型方式处理
105
+ properties = ' %s %s;\n ' % (t , n )
106
+ construction = ' %s = jsonRes[\' %s\' ];\n ' % (n , f )
107
+ toString = '"%s": $%s,' % (f , n )
108
+
109
+ pp = code .find ('${properties}' )
110
+ code = code [:pp ] + properties + code [pp :]
111
+
112
+ pc = code .find ('${construction}' )
113
+ code = code [:pc ] + construction + code [pc :]
114
+
115
+ ps = code .find ('${toString}' )
116
+ code = code [:ps ] + toString + code [ps :]
117
+
118
+ # 字符串类型处理,只需要修改toString中的输出方式
119
+
120
+ tcode = check_level_type (t )
121
+
122
+ if tcode == 2 :
123
+ code = code .replace (': $%s' % n , ': ${%s != null?\' \" $%s\" \' :\' null\' }' % (n , n ))
124
+
125
+ # dict类型处理,只需要修改construction中的输出方式
126
+ elif tcode == 4 :
127
+ code = code .replace ('jsonRes[\' %s\' ]' % f , 'new %s(jsonRes[\' %s\' ])' % (t , f ))
128
+
129
+ # list类型处理,只需要修改construction中的输出方式
130
+ elif tcode == 3 :
131
+ list_loop = build_list_construction (f , t , n )
132
+
133
+ code = code .replace ('jsonRes[\' %s\' ];' % f , list_loop )
134
+
135
+ return code
136
+
137
+
138
+ # 用来存储各个code片段,最后合并就是完整的代码
139
+ codes = []
140
+
141
+
142
+ def build_level_code (level_bean ):
143
+ (l , f , t , n ) = level_bean .pop (0 )
144
+ type_code = check_level_type (t )
145
+ # 处理字典的子数据
146
+ if type_code == 4 :
147
+ code = get_top_code_dict (t )
148
+ work_level = level_bean [0 ][0 ]
149
+ while len (level_bean ) > 0 :
150
+ (l , f , t , n ) = level_bean .pop (0 )
151
+ # 数据类型为字典时
152
+ if check_level_type (t ) == 4 :
153
+ # 先把该字典的定义作为顶层存到递归调用的bean顶部
154
+ child_bean = [(l , f , t , n )]
155
+ while len (level_bean ) > 0 and level_bean [0 ][0 ] > work_level :
156
+ child_bean .append (level_bean .pop (0 ))
157
+ build_level_code (child_bean )
158
+ # 数据类型为数组时
159
+ if check_level_type (t ) == 3 :
160
+ generic_type = level_bean [0 ][2 ].replace ('List<' , '' ).replace ('>' , '' )
161
+ # 如果List的里层数据为dict则对其去壳后处理
162
+ if check_level_type (generic_type ) == 4 :
163
+ while check_level_type (level_bean [0 ][2 ]) == 3 :
164
+ work_level = level_bean [0 ][0 ]
165
+ level_bean .pop (0 )
166
+
167
+ child_bean = []
168
+ while len (level_bean ) > 0 and level_bean [0 ][0 ] > work_level :
169
+ child_bean .append (level_bean .pop (0 ))
170
+ build_level_code (child_bean )
171
+
172
+ # 不管如何,到这里的数据都是目前dict的一级子数据,作为参数传入模板中
173
+ code = add_param_to_code (code , (f , t , n ))
174
+ codes .append (code .replace (',${toString}' , '' ).replace ('${construction}' , '' ).replace ('${properties}' , '' ))
175
+
176
+
32
177
def generate_code (work_bean ):
33
- level_bean = None
34
- for (l , f , t , n ) in work_bean :
35
- if l == - 1 :
36
- if t .startswith ('List<' ):
37
- level_bean = []
38
- else :
39
- level_bean = {}
178
+ # 如果顶级容器为list而不是dict,则先在外面包一层dict,并将list的别名传递为dict的类型,list则重命名为'list',
179
+ (l , f , t , n ) = work_bean [0 ]
180
+ if t .startswith ('List<' ):
181
+ work_bean [0 ][3 ] = 'list'
182
+ work_bean [0 ][1 ] = 'json_list'
183
+ work_bean .insert (0 , (- 2 , "" , n , "" ))
184
+
185
+ build_level_code (work_bean )
40
186
41
- level_bean
42
- # todo 怎么搞。。。
187
+ res = ''
188
+ codes . reverse ()
43
189
190
+ for c in codes :
191
+ res += c
192
+
193
+ codes .clear ()
194
+
195
+ # 最终修改,添加jsonStr解析为jsonRes代码
196
+
197
+ bp = res .find ('(jsonRes) {' )
198
+ return 'import \' dart:convert\' ;\n ' + res [:bp ] + '(jsonStr) {\n var jsonRes = JSON.decode(jsonStr);\n ' + res [bp + 11 :]
44
199
45
- # l, f, t, n = work_bean.pop(0)
46
- #
47
- # if l == -1:
48
- # if t.startswith('List<'):
49
- # top = get_top_code_list(t, n)
50
- # else:
51
- # top = get_top_code_dict(t)
52
- # print(top)
53
200
54
201
55
202
def check_and_generate_code (bean ):
56
203
work_bean = []
204
+ global msg_box_ui
205
+ msg_box_ui = bean [0 ][1 ]
57
206
58
207
for f , t , n in bean :
59
208
field_text = f .text ()
60
209
61
210
level = field_text .find ('※' ) // 4
62
- field_text = field_text [field_text .find ("》" ) + 1 : field_text .find (":" )] if ":" in field_text else ''
211
+ field_text = field_text [field_text .find ("》" ) + 1 : field_text .find (":" ) - 1 ] if ":" in field_text else ''
63
212
type_text = t .currentText () if type (t ) is QComboBox else t .toPlainText ()
64
213
name_text = n .text () if type (n ) is QLabel else n .toPlainText ()
65
214
66
215
if type_text .strip () != '' :
67
216
work_bean .append ([level , field_text , type_text , name_text ])
68
217
else :
69
- QMessageBox ().information (f , "警告" , "字段类型未设置" , QMessageBox .Ok )
218
+ QMessageBox ().information (msg_box_ui , "警告" , "字段类型未设置" , QMessageBox .Ok )
70
219
return ''
71
220
221
+ (l , f , t , n ) = work_bean [0 ]
222
+ if t .startswith ('List<' ) and n == '[list]' :
223
+ QMessageBox ().information (msg_box_ui , "警告" , "请为顶层List设置别名,该别名将成为顶级对象类名" , QMessageBox .Ok )
224
+ return ''
225
+
72
226
return generate_code (work_bean )
0 commit comments