• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2023 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import json
17import subprocess
18import os
19import re
20from collections import OrderedDict
21from clang.cindex import CursorKind
22from coreImpl.diff.diff_processor_permission import compare_permission, RangeChange
23from typedef.diff.diff import TAGS, DiffType, DiffInfo, Scene
24from utils.constants import RegularExpressions
25
26current_file = os.path.dirname(__file__)
27change_data_total = []
28
29
30def get_not_api_kind_list():
31    not_api_kind_list = [
32        'MACRO_DEFINITION',
33        'TRANSLATION_UNIT',
34        'MACRO_INSTANTIATION',
35        'INCLUSION_DIRECTIVE'
36    ]
37    return not_api_kind_list
38
39
40def set_result_common_infor(node_infor, diff_info: DiffInfo):
41    diff_info.set_api_name(node_infor['name'])
42    diff_info.set_api_type(node_infor['kind'])
43    diff_info.set_api_line(node_infor['location']['location_line'])
44    diff_info.set_api_column(node_infor['location']['location_column'])
45    diff_info.set_api_file_path(node_infor['location']['location_path'])
46    diff_info.set_kit_name(node_infor['kit_name'])
47    diff_info.set_sub_system(node_infor['sub_system'])
48    diff_info.set_class_name(node_infor.get('class_name'))
49    diff_info.set_unique_id(node_infor.get('unique_id'))
50
51
52def wrap_diff_info(old_info, new_info, diff_info: DiffInfo):
53    struct_union_enum = [Scene.STRUCT_DECL.value, Scene.ENUM_DECL.value, Scene.UNION_DECL.value,
54                         Scene.TYPEDEF_DECL.value]
55    if old_info is not None:
56        if 'temporary_name' in old_info['name']:
57            old_info['name'] = ''
58        set_result_common_infor(old_info, diff_info)
59        if 'NA' == old_info.get('is_system_api'):
60            diff_info.set_is_system_api(False)
61        else:
62            diff_info.set_is_system_api(True)
63        if 'content' in old_info['node_content']:
64            if old_info['kind'] in struct_union_enum:
65                api_declare = old_info['type']
66            else:
67                api_declare = old_info['node_content']['content']
68
69        else:
70            api_declare = old_info['name']
71        old_content = '类名:{};\nAPI声明:{};\n差异内容:{}\n'.format(diff_info.class_name, api_declare,
72                                                            diff_info.old_differ_content)
73        diff_info.set_old_api_full_text(old_content)
74
75    if new_info is not None:
76        if 'temporary_name' in new_info['name']:
77            new_info['name'] = ''
78        set_result_common_infor(new_info, diff_info)
79        if 'NA' == new_info.get('is_system_api'):
80            diff_info.set_is_system_api(False)
81        else:
82            diff_info.set_is_system_api(True)
83        if 'content' in new_info['node_content']:
84            if new_info['kind'] in struct_union_enum:
85                api_declare = new_info['type']
86            else:
87                api_declare = new_info['node_content']['content']
88        else:
89            api_declare = new_info['name']
90        new_content = '类名:{};\nAPI声明:{};\n差异内容:{}\n'.format(diff_info.class_name, api_declare,
91                                                            diff_info.new_differ_content)
92
93        diff_info.set_new_api_full_text(new_content)
94
95    return diff_info
96
97
98def parse_file_result(result):
99    result_map = {}
100    key = 1
101    for member in result:
102        if member["name"] == '':
103            name = 'temporary_name'
104            member["name"] = '{}{}'.format(name, key)
105            key += 1
106        result_map.setdefault(f'{member["name"]}-{member["kind"]}', member)
107    return result_map
108
109
110def get_member_result_diff(old_target, new_target):
111    old_member_result_map = parse_file_result(old_target)
112    new_member_result_map = parse_file_result(new_target)
113    merged_dict = OrderedDict(list(old_member_result_map.items()) + list(new_member_result_map.items()))
114    all_key_list = merged_dict.keys()
115    return old_member_result_map, new_member_result_map, all_key_list
116
117
118def get_initial_result_obj(diff_type: DiffType, old_differ_content, new_differ_content):
119    result_message_obj = DiffInfo(diff_type, old_differ_content, new_differ_content)
120
121    return result_message_obj
122
123
124def process_function(old, new):
125    diff_info_list = []
126    process_func_return(old, new, diff_info_list)  # 处理返回值
127    process_func_param(old, new, diff_info_list)  # 处理参数
128    return diff_info_list
129
130
131def process_func_return(old, new, diff_info_list):
132    if old['return_type'] != new['return_type']:
133        old_return_content = old['return_type']
134        new_return_content = new['return_type']
135        result_message_obj = get_initial_result_obj(DiffType.FUNCTION_RETURN_CHANGE,
136                                                    old_return_content, new_return_content)
137        diff_info = wrap_diff_info(old, new, result_message_obj)
138        diff_info_list.append(diff_info)
139
140
141def process_func_param_location(old_param_list, new_param_list, old, new):
142    result_list = []
143    old_param_str_list = get_param_name_and_type(old_param_list)
144    new_param_str_list = get_param_name_and_type(new_param_list)
145    old_param_str_content = ' '.join(old_param_str_list)
146    new_param_str_content = ' '.join(new_param_str_list)
147    if old_param_str_content == new_param_str_content:
148        return result_list
149    old_len = len(old_param_list)
150    for i, element in enumerate(old_param_str_list):
151        if element not in new_param_str_list:
152            return result_list
153        if i != new_param_str_list.index(element) and i + 1 <= old_len:
154            old_differ_content = old_param_list[i]['node_content']['content']
155            new_differ_content = new_param_list[i]['node_content']['content']
156            result_obj = wrap_diff_info(old, new, DiffInfo(DiffType.FUNCTION_PARAM_POS_CHANGE,
157                                                           old_differ_content, new_differ_content))
158            result_list.append(result_obj)
159    return result_list
160
161
162def get_param_name_and_type(param_list):
163    param_str_list = []
164    for param in param_list:
165        if 'name' in param and 'type' in param:
166            param_str = '{} {}'.format(param.get('type'), param.get('name'))
167            param_str_list.append(param_str)
168    return param_str_list
169
170
171def process_each_param(old, new, old_len, new_len, diff_info_list):
172    for i in range(max(old_len, new_len)):
173        if (i + 1) > new_len:  # 减少参数
174            old_param_content = old['parm'][i]['node_content']['content']
175            new_param_content = 'NA'
176            result_message_obj = get_initial_result_obj(DiffType.FUNCTION_PARAM_REDUCE,
177                                                        old_param_content, new_param_content)
178            diff_info = wrap_diff_info(old, new, result_message_obj)
179            diff_info_list.append(diff_info)
180
181        elif (i + 1) > old_len:  # 增加参数
182            old_param_content = 'NA'
183            new_param_content = new['parm'][i]['node_content']['content']
184            result_message_obj = get_initial_result_obj(DiffType.FUNCTION_PARAM_ADD,
185                                                        old_param_content, new_param_content)
186            diff_info = wrap_diff_info(old, new, result_message_obj)
187            diff_info_list.append(diff_info)
188
189        else:
190            diff_info_result = process_param_scene(old['parm'], new['parm'], i, old, new)
191            diff_info_list.extend(diff_info_result)
192
193
194def get_param_content(param_infor: list):
195    if not param_infor:
196        param_content = 'NA'
197        return param_content
198    if 1 == len(param_infor):
199        param_content = '({})'.format(param_infor[0]['node_content']['content'])
200        return param_content
201    param_content = '('
202    for element in param_infor:
203        param_content = '{},{}'.format(param_content, element['node_content']['content'])
204    param_content = '{}{}'.format(param_content, ')')
205    return param_content
206
207
208def process_func_param(old, new, diff_info_list):
209    if 'parm' in old and 'parm' in new:
210        old_len = len(old['parm'])
211        new_len = len(new['parm'])
212        result_obj_list = []
213        if old_len == new_len:
214            result_obj_list = process_func_param_location(old['parm'], new['parm'], old, new)
215            diff_info_list.extend(result_obj_list)
216        if not result_obj_list:
217            process_each_param(old, new, old_len, new_len, diff_info_list)
218
219    elif 'parm' not in old and 'parm' in new:  # 旧无新有
220        old_param_content = 'NA'
221        new_param_content = get_param_content(new['parm'])
222        if new_param_content != 'NA':
223            result_message_obj = get_initial_result_obj(DiffType.FUNCTION_PARAM_ADD,
224                                                        old_param_content, new_param_content)
225            diff_info = wrap_diff_info(old, new, result_message_obj)
226            diff_info_list.append(diff_info)
227
228    elif 'parm' in old and 'parm' not in new:  # 旧有新无
229        old_param_content = get_param_content(old['parm'])
230        new_param_content = 'NA'
231        if old_param_content != 'NA':
232            result_message_obj = get_initial_result_obj(DiffType.FUNCTION_PARAM_REDUCE,
233                                                        old_param_content, new_param_content)
234            diff_info = wrap_diff_info(old, new, result_message_obj)
235            diff_info_list.append(diff_info)
236
237
238def process_param_scene(old_param, new_param, index, parent_old, parent_new):
239    diff_info_list = []
240    if old_param[index]['type'] != new_param[index]['type']:
241        old_param_type_content = old_param[index]['type']
242        new_param_type_content = new_param[index]['type']
243        result_message_obj = get_initial_result_obj(DiffType.FUNCTION_PARAM_TYPE_CHANGE,
244                                                    old_param_type_content, new_param_type_content)
245        diff_info = wrap_diff_info(parent_old, parent_new, result_message_obj)
246        diff_info_list.append(diff_info)
247
248    if old_param[index]['name'] != new_param[index]['name']:
249        old_param_name_content = old_param[index]['name']
250        new_param_name_content = new_param[index]['name']
251        result_message_obj = get_initial_result_obj(DiffType.FUNCTION_PARAM_NAME_CHANGE,
252                                                    old_param_name_content, new_param_name_content)
253        diff_info = wrap_diff_info(parent_old, parent_new, result_message_obj)
254        diff_info_list.append(diff_info)
255
256    return diff_info_list
257
258
259def process_define(old, new):
260    diff_define_list = []
261    process_define_name(old, new, diff_define_list)  # 处理宏名
262    process_define_text(old, new, diff_define_list)  # 处理宏文本
263    return diff_define_list
264
265
266def process_define_name(old, new, diff_define_list):
267    if old['name'] != new['name']:
268        old_define_name = old['name']
269        new_define_name = new['name']
270        result_message_obj = get_initial_result_obj(DiffType.DEFINE_NAME_CHANGE,
271                                                    old_define_name, new_define_name)
272        diff_info = wrap_diff_info(old, new, result_message_obj)
273        diff_define_list.append(diff_info)
274
275
276def process_define_text(old, new, diff_define_list):
277    if 'text' not in old and 'text' in new:  # 旧无新有
278        old_define_text = 'NA'
279        new_define_text = new['text']
280        result_message_obj = get_initial_result_obj(DiffType.DEFINE_TEXT_CHANGE,
281                                                    old_define_text, new_define_text)
282        diff_info = wrap_diff_info(old, new, result_message_obj)
283        diff_define_list.append(diff_info)
284    elif 'text' in old and 'text' not in new:  # 旧有新无
285        old_define_text = old['text']
286        new_define_text = 'NA'
287        result_message_obj = get_initial_result_obj(DiffType.DEFINE_TEXT_CHANGE,
288                                                    old_define_text, new_define_text)
289        diff_info = wrap_diff_info(old, new, result_message_obj)
290        diff_define_list.append(diff_info)
291    elif 'text' in old and 'text' in new:
292        if old['text'] != new['text']:
293            old_define_text = old['text']
294            new_define_text = new['text']
295            result_message_obj = get_initial_result_obj(DiffType.DEFINE_TEXT_CHANGE,
296                                                        old_define_text, new_define_text)
297            diff_info = wrap_diff_info(old, new, result_message_obj)
298            diff_define_list.append(diff_info)
299
300
301def process_struct(old, new):
302    diff_struct_list = []
303    process_struct_name(old, new, diff_struct_list)  # 处理结构体名
304    process_struct_member(old, new, diff_struct_list)  # 处理结构体成员
305    return diff_struct_list
306
307
308def process_struct_name(old, new, diff_struct_list):
309    if old['name'] != new['name']:
310        old_struct_name = old['name']
311        new_struct_name = new['name']
312        result_message_obj = get_initial_result_obj(DiffType.STRUCT_NAME_CHANGE,
313                                                    old_struct_name, new_struct_name)
314        diff_info = wrap_diff_info(old, new, result_message_obj)
315        diff_struct_list.append(diff_info)
316
317
318def get_member_content(member_infor: list):
319    if not member_infor:
320        member_content = 'NA'
321        return member_content
322    if member_infor[0]['type'] == 'FIELD_DECL':
323        end_float = ';'
324    else:
325        end_float = ','
326    if 1 == len(member_infor):
327        member_content = '{}'.format(member_infor[0]['node_content']['content'])
328        return member_content
329    member_content = ''
330    for element in member_infor:
331        member_content = '{}{}{}'.format(member_content, end_float, element['node_content']['content'])
332    return member_content
333
334
335def process_struct_member(old, new, diff_struct_list):
336    if 'members' in old and 'members' in new:  # 都有
337        old_member_result, new_member_result, all_key_result = get_member_result_diff(old['members'],
338                                                                                      new['members'])
339        for key in all_key_result:
340            if old_member_result.get(key) is None:
341                old_member_content = 'NA'
342                new_member_content = new_member_result.get(key)['node_content']['content']
343                result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_ADD,
344                                                            old_member_content, new_member_content)
345                diff_info = wrap_diff_info(old_member_result.get(key), new_member_result.get(key),
346                                           result_message_obj)
347                diff_struct_list.append(diff_info)
348            elif new_member_result.get(key) is None:
349                old_member_content = old_member_result.get(key)['node_content']['content']
350                new_member_content = 'NA'
351                result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_REDUCE,
352                                                            old_member_content, new_member_content)
353                diff_info = wrap_diff_info(old_member_result.get(key), new_member_result.get(key),
354                                           result_message_obj)
355                diff_struct_list.append(diff_info)
356            else:
357                process_struct_member_scene(old_member_result.get(key),
358                                            new_member_result.get(key), diff_struct_list)
359
360    elif 'members' not in old and 'members' in new:  # 旧无新有
361        old_member_content = 'NA'
362        new_member_content = get_member_content(new['members'])
363        if new_member_content != 'NA':
364            result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_ADD,
365                                                        old_member_content, new_member_content)
366            diff_info = wrap_diff_info(old, new, result_message_obj)
367            diff_struct_list.append(diff_info)
368
369    elif 'members' in old and 'members' not in new:  # 旧有新无
370        old_member_content = get_member_content(old['members'])
371        new_member_content = 'NA'
372        if old_member_content != 'NA':
373            result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_REDUCE,
374                                                        old_member_content, new_member_content)
375            diff_info = wrap_diff_info(old, new, result_message_obj)
376            diff_struct_list.append(diff_info)
377
378
379def process_struct_member_scene(old_member, new_member, diff_struct_list):
380    special_data = []  # 存储嵌套的体系
381    if (old_member['kind'] == Scene.STRUCT_DECL.value) and \
382            (new_member['kind'] == Scene.STRUCT_DECL.value):  # 结构体套结构体
383        special_data = process_struct(old_member, new_member)
384
385    elif (old_member['kind'] == Scene.UNION_DECL.value) and \
386            (new_member['kind'] == Scene.UNION_DECL.value):  # 结构体套联合体
387        special_data = process_union(old_member, new_member)
388
389    elif (old_member['kind'] == Scene.ENUM_DECL.value) and \
390            (new_member['kind'] == Scene.ENUM_DECL.value):  # 结构体套枚举
391        special_data = process_enum(old_member, new_member)
392    diff_struct_list.extend(special_data)
393
394    if (not (old_member['location']['location_path'] in old_member['type'])) and \
395            (not (new_member['location']['location_path'] in new_member['type'])):
396        if old_member['type'] != new_member['type']:
397            old_member_type = old_member['type']
398            new_member_type = new_member['type']
399            result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_TYPE_CHANGE,
400                                                        old_member_type, new_member_type)
401            diff_info = wrap_diff_info(old_member, new_member,
402                                       result_message_obj)
403            diff_struct_list.append(diff_info)
404
405    if old_member['name'] != new_member['name']:
406        old_member_name = old_member['name']
407        new_member_name = new_member['name']
408        result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_NAME_CHANGE,
409                                                    old_member_name, new_member_name)
410        diff_info = wrap_diff_info(old_member, new_member,
411                                   result_message_obj)
412        diff_struct_list.append(diff_info)
413
414
415def process_union(old, new):
416    diff_union_list = []
417    process_union_name(old, new, diff_union_list)  # 处理联合体名
418    process_union_member(old, new, diff_union_list)  # 处理联合体成员
419    return diff_union_list
420
421
422def process_union_name(old, new, diff_union_list):
423    if old['name'] != new['name']:
424        old_union_name = old['name']
425        new_union_name = new['name']
426        result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_NAME_CHANGE,
427                                                    old_union_name, new_union_name)
428        diff_info = wrap_diff_info(old, new, result_message_obj)
429        diff_union_list.append(diff_info)
430
431
432def process_union_member(old, new, diff_union_list):
433    if 'members' in old and 'members' in new:  # 都有
434        old_member_result, new_member_result, all_key_result = get_member_result_diff(old['members'],
435                                                                                      new['members'])
436        for key in all_key_result:
437            if old_member_result.get(key) is None:
438                old_member_content = 'NA'
439                new_member_content = new_member_result.get(key)['node_content']['content']
440                result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_NAME_CHANGE,
441                                                            old_member_content, new_member_content)
442
443                diff_info = wrap_diff_info(old_member_result.get(key), new_member_result.get(key),
444                                           result_message_obj)
445                diff_union_list.append(diff_info)
446            elif new_member_result.get(key) is None:
447                old_member_content = old_member_result.get(key)['node_content']['content']
448                new_member_content = 'NA'
449                result_message_obj = get_initial_result_obj(DiffType.STRUCT_MEMBER_NAME_CHANGE,
450                                                            old_member_content, new_member_content)
451
452                diff_info = wrap_diff_info(old_member_result.get(key), new_member_result.get(key),
453                                           result_message_obj)
454                diff_union_list.append(diff_info)
455            else:
456                process_union_member_scene(old_member_result.get(key),
457                                           new_member_result.get(key), diff_union_list)
458
459    elif 'members' not in old and 'members' in new:  # 旧无新有
460        old_member_content = 'NA'
461        new_member_content = get_member_content(new['members'])
462        if new_member_content != 'NA':
463            diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.UNION_MEMBER_ADD,
464                                                          old_member_content, new_member_content))
465            diff_union_list.append(diff_info)
466
467    elif 'members' in old and 'members' not in new:  # 旧有新无
468        old_member_content = get_member_content(old['members'])
469        new_member_content = 'NA'
470        if old_member_content != 'NA':
471            diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.UNION_MEMBER_REDUCE,
472                                                          old_member_content, new_member_content))
473            diff_union_list.append(diff_info)
474
475
476def process_union_member_scene(old_member, new_member, diff_union_list):
477    special_data = []  # 存储嵌套的体系
478    if (old_member['kind'] == Scene.STRUCT_DECL.value) and \
479            (new_member['kind'] == Scene.STRUCT_DECL.value):  # 联合体套结构体
480        special_data = process_struct(old_member, new_member)
481
482    elif (old_member['kind'] == Scene.UNION_DECL.value) and \
483            (new_member['kind'] == Scene.UNION_DECL.value):  # 联合体套联合体
484        special_data = process_union(old_member, new_member)
485
486    elif (old_member['kind'] == Scene.ENUM_DECL.value) and \
487            (new_member['kind'] == Scene.ENUM_DECL.value):  # 联合体套枚举
488        special_data = process_enum(old_member, new_member)
489    diff_union_list.extend(special_data)
490
491    if (not (old_member['location']['location_path'] in old_member['type'])) and \
492            (not (new_member['location']['location_path'] in new_member['type'])):
493        if old_member['type'] != new_member['type']:
494            old_member_type = old_member['type']
495            new_member_type = new_member['type']
496            diff_info = wrap_diff_info(old_member, new_member, DiffInfo(DiffType.UNION_MEMBER_TYPE_CHANGE,
497                                                                        old_member_type, new_member_type))
498            diff_union_list.append(diff_info)
499
500    if old_member['name'] != new_member['name']:
501        old_member_name = old_member['name']
502        new_member_name = new_member['name']
503        diff_info = wrap_diff_info(old_member, new_member, DiffInfo(DiffType.UNION_MEMBER_NAME_CHANGE,
504                                                                    old_member_name, new_member_name))
505        diff_union_list.append(diff_info)
506
507
508def process_enum(old, new):
509    diff_enum_list = []
510    process_enum_name(old, new, diff_enum_list)  # 处理枚举名
511    process_enum_member(old, new, diff_enum_list)  # 处理枚举成员
512    return diff_enum_list
513
514
515def process_enum_name(old, new, diff_enum_list):
516    if old['name'] != new['name']:
517        old_enum_name = old['name']
518        new_enum_name = new['name']
519        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.ENUM_NAME_CHANGE, old_enum_name, new_enum_name))
520        diff_enum_list.append(diff_info)
521
522
523def process_enum_member(old, new, diff_enum_list):
524    if 'members' in old and 'members' in new:  # 都有
525        old_member_result, new_member_result, all_key_result = get_member_result_diff(old['members'],
526                                                                                      new['members'])
527        for key in all_key_result:
528            if old_member_result.get(key) is None:
529                old_member_content = 'NA'
530                new_member_content = new_member_result.get(key)['node_content']['content']
531                diff_info = wrap_diff_info(old_member_result.get(key), new_member_result.get(key),
532                                           DiffInfo(DiffType.ENUM_MEMBER_ADD, old_member_content,
533                                                    new_member_content))
534                diff_enum_list.append(diff_info)
535            elif new_member_result.get(key) is None:
536                old_member_content = old_member_result.get(key)['node_content']['content']
537                new_member_content = 'NA'
538                diff_info = wrap_diff_info(old_member_result.get(key), new_member_result.get(key),
539                                           DiffInfo(DiffType.ENUM_MEMBER_REDUCE, old_member_content,
540                                                    new_member_content))
541                diff_enum_list.append(diff_info)
542            else:
543                process_enum_member_scene(old_member_result.get(key),
544                                          new_member_result.get(key), diff_enum_list)
545
546    elif 'members' not in old and 'members' in new:  # 旧无新有
547        old_member_content = 'NA'
548        new_member_content = get_member_content(new['members'])
549        if new_member_content != 'NA':
550            diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.ENUM_MEMBER_ADD,
551                                                          old_member_content, new_member_content))
552            diff_enum_list.append(diff_info)
553
554    elif 'members' in old and 'members' not in new:  # 旧有新无
555        old_member_content = get_member_content(new['members'])
556        new_member_content = 'NA'
557        if old_member_content != 'NA':
558            diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.ENUM_MEMBER_REDUCE,
559                                                          old_member_content, new_member_content))
560            diff_enum_list.append(diff_info)
561
562
563def process_enum_member_scene(old_member, new_member, diff_union_list):
564    if old_member['value'] != new_member['value']:
565        old_enum_value = old_member['value']
566        new_enum_value = new_member['value']
567        diff_info = wrap_diff_info(old_member, new_member,
568                                   DiffInfo(DiffType.ENUM_MEMBER_VALUE_CHANGE, old_enum_value, new_enum_value))
569        diff_union_list.append(diff_info)
570
571    if old_member['name'] != new_member['name']:
572        old_member_name = old_member['name']
573        new_member_name = new_member['name']
574        diff_info = wrap_diff_info(old_member, new_member,
575                                   DiffInfo(DiffType.ENUM_MEMBER_NAME_CHANGE, old_member_name, new_member_name))
576        diff_union_list.append(diff_info)
577
578
579def process_variable_const(old, new):
580    diff_var_or_con = []
581    if 'is_const' in old:
582        if old['is_const']:  # 处理常量
583            if 'is_const' in new and new['is_const']:
584                process_constant_type(old, new, diff_var_or_con)  # 处理常量类型
585            elif 'is_const' in new and (not new['is_const']):  # 处理常量变变量
586                process_const_change_variable(old, new, diff_var_or_con)
587            process_constant_name(old, new, diff_var_or_con)  # 处理常量名
588            process_constant_value(old, new, diff_var_or_con)  # 处理常量值
589
590        else:  # 处理变量
591            if 'is_const' in new and new['is_const']:
592                process_variable_change_const(old, new, diff_var_or_con)  # 处理变量变常量
593            elif 'is_const' in new and (not new['is_const']):
594                process_variable_type(old, new, diff_var_or_con)  # 处理变量类型
595            process_variable_name(old, new, diff_var_or_con)  # 处理变量名
596            process_variable_value(old, new, diff_var_or_con)  # 处理变量值
597
598    return diff_var_or_con
599
600
601def process_const_change_variable(old, new, diff_variable_list):
602    if 'is_const' in new and (not new['is_const']):
603        old_const_type = old['type']
604        new_const_type = new['type']
605        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.CONSTANT_CHANGE_TO_VARIABLE,
606                                                      old_const_type, new_const_type))
607        diff_variable_list.append(diff_info)
608
609
610def process_variable_change_const(old, new, diff_variable_list):
611    if 'is_const' in new and new['is_const']:
612        old_variable_type = old['type']
613        new_variable_type = new['type']
614        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.VARIABLE_CHANGE_TO_CONSTANT,
615                                                      old_variable_type, new_variable_type))
616        diff_variable_list.append(diff_info)
617
618
619def process_variable_name(old, new, diff_variable_list):
620    if old['name'] != new['name']:
621        old_variable_name = old['name']
622        new_variable_name = new['name']
623        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.VARIABLE_NAME_CHANGE,
624                                                      old_variable_name, new_variable_name))
625        diff_variable_list.append(diff_info)
626
627
628def process_variable_type(old, new, diff_variable_list):
629    if old['type'] != new['type']:
630        old_variable_type = old['type']
631        new_variable_type = new['type']
632        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.VARIABLE_TYPE_CHANGE,
633                                                      old_variable_type, new_variable_type))
634        diff_variable_list.append(diff_info)
635
636
637def process_variable_value(old, new, diff_variable_list):
638    if 'children' in old and 'children' in new:
639        if len(old['children']) and len(new['children']) \
640                and old['children'][0]['node_content']['content'] != new['children'][0]['node_content']['content']:
641            old_variable_value = old['children'][0]['node_content']['content']
642            new_variable_value = new['children'][0]['node_content']['content']
643            diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.VARIABLE_VALUE_CHANGE,
644                                                          old_variable_value, new_variable_value))
645            diff_variable_list.append(diff_info)
646
647    elif 'children' not in old and 'children' in new and len(new['children']):
648        old_variable_value = 'NA'
649        new_variable_value = new['children'][0]['node_content']['content']
650        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.VARIABLE_VALUE_CHANGE,
651                                                      old_variable_value, new_variable_value))
652        diff_variable_list.append(diff_info)
653
654    elif 'children' in old and 'children' not in new and len(old['children']):
655        old_variable_value = old['children'][0]['node_content']['content']
656        new_variable_value = 'NA'
657        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.VARIABLE_VALUE_CHANGE,
658                                                      old_variable_value, new_variable_value))
659        diff_variable_list.append(diff_info)
660
661
662def process_constant_to_variable(old, new, diff_constant_list):
663    if not new['is_const']:
664        old_const_type = old['type']
665        new_const_type = new['type']
666        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.CONSTANT_CHANGE_TO_VARIABLE,
667                                                      old_const_type, new_const_type))
668        diff_constant_list.append(diff_info)
669
670
671def process_constant_name(old, new, diff_constant_list):
672    if old['name'] != new['name']:
673        old_const_name = old['name']
674        new_const_name = new['name']
675        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.CONSTANT_NAME_CHANGE, old_const_name, new_const_name))
676        diff_constant_list.append(diff_info)
677
678
679def process_constant_type(old, new, diff_constant_list):
680    if old['type'] != new['type']:
681        old_const_type = old['type']
682        new_const_type = new['type']
683        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.CONSTANT_TYPE_CHANGE, old_const_type, new_const_type))
684        diff_constant_list.append(diff_info)
685
686
687def process_constant_value(old, new, diff_constant_list):
688    if 'children' in old and 'children' in new:
689        if len(old['children']) and len(new['children']) \
690                and old['children'][0]['node_content']['content'] != new['children'][0]['node_content']['content']:
691            old_const_value = old['children'][0]['node_content']['content']
692            new_const_value = new['children'][0]['node_content']['content']
693            diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.CONSTANT_VALUE_CHANGE,
694                                                          old_const_value, new_const_value))
695            diff_constant_list.append(diff_info)
696
697    elif 'children' not in old and 'children' in new and len(new['children']):
698        old_none = None
699        old_const_value = 'NA'
700        new_const_value = new['children'][0]['node_content']['content']
701        diff_info = wrap_diff_info(old_none, new, DiffInfo(DiffType.CONSTANT_VALUE_CHANGE,
702                                                           old_const_value, new_const_value))
703        diff_constant_list.append(diff_info)
704
705    elif 'children' in old and 'children' not in new and len(old['children']):
706        new_none = None
707        old_const_value = old['children'][0]['node_content']['content']
708        new_const_value = 'NA'
709        diff_info = wrap_diff_info(old, new_none, DiffInfo(DiffType.CONSTANT_VALUE_CHANGE, old_const_value,
710                                                           new_const_value))
711        diff_constant_list.append(diff_info)
712
713
714def process_typedef(old, new):
715    diff_typedef_list = []
716    process_typedef_name(old, new, diff_typedef_list)  # 处理命名
717
718    if 'children' in old and 'children' in new:  # 处理子节点
719        process_typedef_child(old['children'], new['children'], diff_typedef_list)
720
721    return diff_typedef_list
722
723
724def process_typedef_name(old, new, diff_typedef_list):
725    if old['name'] != new['name']:
726        old_typedef_name = old['name']
727        new_typedef_name = new['name']
728        diff_info = wrap_diff_info(old, new, DiffInfo(DiffType.TYPEDEF_NAME_TYPE_CHANGE,
729                                                      old_typedef_name, new_typedef_name))
730        diff_typedef_list.append(diff_info)
731
732
733def process_typedef_child(old_child, new_child, diff_typedef_list):
734    special_data = []  # 存储嵌套的体系
735    for i, _ in enumerate(old_child):
736        if old_child[i]['name'] == '' and new_child[i]['name'] == '':
737            if old_child[i]['kind'] == Scene.STRUCT_DECL.value and \
738                    new_child[i]['kind'] == Scene.STRUCT_DECL.value:
739                special_data = process_struct(old_child[i], new_child[i])
740
741            elif old_child[i]['kind'] == Scene.UNION_DECL.value and \
742                    new_child[i]['kind'] == Scene.UNION_DECL.value:
743                special_data = process_union(old_child[i], new_child[i])
744
745            elif old_child[i]['kind'] == Scene.ENUM_DECL.value and \
746                    new_child[i]['kind'] == Scene.ENUM_DECL.value:
747                special_data = process_enum(old_child[i], new_child[i])
748
749            diff_typedef_list.extend(special_data)
750
751
752process_data = {
753    Scene.FUNCTION_DECL.value: process_function,
754    Scene.MACRO_DEFINITION.value: process_define,
755    Scene.STRUCT_DECL.value: process_struct,
756    Scene.UNION_DECL.value: process_union,
757    Scene.ENUM_DECL.value: process_enum,
758    Scene.VAR_DECL.value: process_variable_const,
759    Scene.TYPEDEF_DECL.value: process_typedef
760}
761
762
763def collect_change_data_total(data: dict, diff_info_list):
764    for element in diff_info_list:
765        element.set_api_node_name(data['name'])
766        element.set_current_api_unique_id(data['unique_id'])
767    change_data_total.append(diff_info_list)
768
769
770def set_is_api_change_result(result_data, key_extern):
771    for element in result_data:
772        if key_extern:
773            element.set_is_api_change(True)
774
775
776def process_add_node(add_infor, key_extern, struct_union_enum):
777    diff_info_list = []
778    old_infor = None
779    if add_infor['kind'] == Scene.TRANSLATION_UNIT.value:
780        return diff_info_list
781    if 'is_extern' in add_infor and add_infor['is_extern']:
782        key_extern = True
783    diff_type = DiffType.ADD_API
784    old_api_content = 'NA'
785    if add_infor['kind'] in struct_union_enum:
786        new_api_content = add_infor['type']
787    else:
788        new_api_content = add_infor['node_content']['content']
789    diff_info_list.append(wrap_diff_info(old_infor, add_infor, DiffInfo(diff_type,
790                                                                        old_api_content, new_api_content)))
791    if diff_type == DiffType.ADD_API:
792        set_is_api_change_result(diff_info_list, key_extern)
793        collect_change_data_total(add_infor, diff_info_list)
794
795    return diff_info_list
796
797
798def process_reduce_node(reduce_infor, key_extern, struct_union_enum):
799    diff_info_list = []
800    new_infor = None
801    if reduce_infor['kind'] == Scene.TRANSLATION_UNIT.value:
802        return diff_info_list
803    if 'is_extern' in reduce_infor and reduce_infor['is_extern']:
804        key_extern = True
805    diff_type = DiffType.REDUCE_API
806    new_api_content = 'NA'
807    if reduce_infor['kind'] in struct_union_enum:
808        old_api_content = reduce_infor['type']
809    else:
810        old_api_content = reduce_infor['node_content']['content']
811    diff_info_list.append(wrap_diff_info(reduce_infor, new_infor, DiffInfo(diff_type,
812                                                                           old_api_content, new_api_content)))
813    set_is_api_change_result(diff_info_list, key_extern)
814    collect_change_data_total(reduce_infor, diff_info_list)
815
816    return diff_info_list
817
818
819def judgment_entrance(old, new, data_type=0):
820    """
821    Args:
822        old: ***
823        new: ***
824        data_type(int): 数据处理类型。1-文件新增或删除;0-其他
825    """
826    diff_info_list = []
827    struct_union_enum = [Scene.STRUCT_DECL.value, Scene.UNION_DECL.value,
828                         Scene.ENUM_DECL.value, Scene.TYPEDEF_DECL.value]
829    key_extern = False
830    if old is None and new is None:
831        return diff_info_list
832    if old is None:
833        diff_info_list.extend(process_add_node(new, key_extern, struct_union_enum))
834        return diff_info_list
835    if new is None:
836        diff_info_list.extend(process_reduce_node(old, key_extern, struct_union_enum))
837        return diff_info_list
838    kind = new['kind']
839    if 'is_extern' in old and old['is_extern']:
840        key_extern = True
841    diff_info_list.extend(process_comment_str(old, new))
842    if kind in process_data:
843        diff_info_list.extend(process_data[kind](old, new))
844    if diff_info_list:
845        set_is_api_change_result(diff_info_list, key_extern)
846        collect_change_data_total(new, diff_info_list)
847    return diff_info_list
848
849
850def process_tag_addtogroup(old_tag, new_tag, old_info, new_info):
851    diff_info_list = []
852    if old_tag is None:
853        diff_info_list.append(
854            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_ADDTOGROUP_NA_TO_HAVE,
855                                                        'NA', new_tag['name'])))
856        return diff_info_list
857    if new_tag is None:
858        diff_info_list.append(
859            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_ADDTOGROUP_HAVE_TO_NA,
860                                                        old_tag['name'], 'NA')))
861        return diff_info_list
862    if old_tag['name'] != new_tag['name']:
863        diff_info_list.append(wrap_diff_info(old_info, new_info,
864                                             DiffInfo(DiffType.DOC_TAG_ADDTOGROUP_A_TO_B, old_tag['name'],
865                                                      new_tag['name'])))
866    return diff_info_list
867
868
869def process_tag_brief(old_tag, new_tag, old_info, new_info):
870    diff_info_list = []
871    if old_tag is None:
872        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_BRIEF_NA_TO_HAVE,
873                                                                          'NA',
874                                                                          f'{new_tag["name"]} '
875                                                                          f'{new_tag["description"]}')))
876        return diff_info_list
877    if new_tag is None:
878        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_BRIEF_HAVE_TO_NA,
879                                                                          f'{old_tag["name"]} '
880                                                                          f'{old_tag["description"]}',
881                                                                          'NA')))
882        return diff_info_list
883    old_brief = f'{old_tag["name"]} {old_tag["description"]}'
884    new_brief = f'{new_tag["name"]} {new_tag["description"]}'
885    if old_brief != new_brief:
886        diff_info_list.append(
887            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_BRIEF_A_TO_B, old_brief, new_brief)))
888    return diff_info_list
889
890
891def process_tag_deprecated(old_tag, new_tag, old_info, new_info):
892    diff_info_list = []
893    if old_tag is None:
894        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_DEPRECATED_NA_TO_HAVE,
895                                                                          'NA',
896                                                                          f'{new_tag["name"]} '
897                                                                          f'{new_tag["description"]}')))
898        return diff_info_list
899    if new_tag is None:
900        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_DEPRECATED_HAVE_TO_NA,
901                                                                          f'{old_tag["name"]} '
902                                                                          f'{old_tag["description"]}',
903                                                                          'NA')))
904        return diff_info_list
905    old_deprecated = f'{old_tag["name"]} {old_tag["description"]}'
906    new_deprecated = f'{new_tag["name"]} {new_tag["description"]}'
907    if old_deprecated != new_deprecated:
908        diff_info_list.append(wrap_diff_info(old_info, new_info,
909                                             DiffInfo(DiffType.DOC_TAG_DEPRECATED_A_TO_B, old_deprecated,
910                                                      new_deprecated)))
911    return diff_info_list
912
913
914def process_tag_file(old_tag, new_tag, old_info, new_info):
915    diff_info_list = []
916    if old_tag is None:
917        diff_info_list.append(
918            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_FILE_NA_TO_HAVE, 'NA', new_tag['name'])))
919        return diff_info_list
920    if new_tag is None:
921        diff_info_list.append(
922            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_FILE_HAVE_TO_NA, old_tag['name'], 'NA')))
923        return diff_info_list
924    if old_tag['name'] != new_tag['name']:
925        diff_info_list.append(wrap_diff_info(old_info, new_info,
926                                             DiffInfo(DiffType.DOC_TAG_FILE_A_TO_B, old_tag['name'], new_tag['name'])))
927    return diff_info_list
928
929
930def process_tag_library(old_tag, new_tag, old_info, new_info):
931    diff_info_list = []
932    if old_tag is None:
933        diff_info_list.append(
934            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_LIBRARY_NA_TO_HAVE, 'NA', new_tag['name'])))
935        return diff_info_list
936    if new_tag is None:
937        diff_info_list.append(
938            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_LIBRARY_HAVE_TO_NA, old_tag['name'], "NA")))
939        return diff_info_list
940    if old_tag['name'] != new_tag['name']:
941        diff_info_list.append(wrap_diff_info(old_info, new_info,
942                                             DiffInfo(DiffType.DOC_TAG_LIBRARY_A_TO_B, old_tag['name'],
943                                                      new_tag['name'])))
944    return diff_info_list
945
946
947def process_tag_param(old_tag, new_tag, old_info, new_info):
948    diff_info_list = []
949    if old_tag is None:
950        diff_info_list.append(
951            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_PARAM_NA_TO_HAVE, 'NA', new_tag['name'])))
952        return diff_info_list
953    if new_tag is None:
954        diff_info_list.append(
955            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_PARAM_HAVE_TO_NA, old_tag["name"], 'NA')))
956        return diff_info_list
957    if old_tag["name"] != new_tag['name']:
958        diff_info_list.append(wrap_diff_info(old_info, new_info,
959                                             DiffInfo(DiffType.DOC_TAG_PARAM_NAME_A_TO_B, old_tag["name"],
960                                                      new_tag['name'])))
961    if old_tag["description"] != new_tag['description']:
962        diff_info_list.append(wrap_diff_info(old_info, new_info,
963                                             DiffInfo(DiffType.DOC_TAG_PARAM_A_TO_B, old_tag["description"],
964                                                      new_tag['description'])))
965    return diff_info_list
966
967
968def process_tag_permission(old_tag, new_tag, old_info, new_info):
969    diff_info_list = []
970    if old_tag is None:
971        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_PERMISSION_NA_TO_HAVE,
972                                                                          'NA',
973                                                                          f'{new_tag["name"]} '
974                                                                          f'{new_tag["description"]}')))
975        return diff_info_list
976    if new_tag is None:
977        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_PERMISSION_HAVE_TO_NA,
978                                                                          f'{old_tag["name"]} '
979                                                                          f'{old_tag["description"]}',
980                                                                          'NA')))
981        return diff_info_list
982    old_permission = f'{old_tag["name"]} {old_tag["description"]}'
983    new_permission = f'{new_tag["name"]} {new_tag["description"]}'
984    if old_permission != new_permission:
985        compare_value = compare_permission(old_permission, new_permission)
986        if compare_value.state_range == RangeChange.DOWN.value:
987            diff_info_list.append(wrap_diff_info(old_info, new_info,
988                                                 DiffInfo(DiffType.DOC_TAG_PERMISSION_RANGE_SMALLER, old_permission,
989                                                          new_permission)))
990        elif compare_value.state_range == RangeChange.UP.value:
991            diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(
992                DiffType.DOC_TAG_PERMISSION_RANGE_BIGGER, old_permission, new_permission)))
993        elif compare_value.state_range == RangeChange.CHANGE.value:
994            diff_info_list.append(wrap_diff_info(old_info, new_info,
995                                                 DiffInfo(DiffType.DOC_TAG_PERMISSION_RANGE_CHANGE, old_permission,
996                                                          new_permission)))
997    return diff_info_list
998
999
1000def process_tag_return(old_tag, new_tag, old_info, new_info):
1001    diff_info_list = []
1002    return diff_info_list
1003
1004
1005def process_tag_since(old_tag, new_tag, old_info, new_info):
1006    diff_info_list = []
1007    if old_tag is None:
1008        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_SINCE_NA_TO_HAVE,
1009                                                                          'NA',
1010                                                                          f'{new_tag["name"]} '
1011                                                                          f'{new_tag["description"]}')))
1012        return diff_info_list
1013    if new_tag is None:
1014        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_SINCE_HAVE_TO_NA,
1015                                                                          f'{old_tag["name"]} '
1016                                                                          f'{old_tag["description"]}',
1017                                                                          'NA')))
1018        return diff_info_list
1019    old_since = f'{old_tag["name"]} {old_tag["description"]}'
1020    new_since = f'{new_tag["name"]} {new_tag["description"]}'
1021    if old_since != new_since:
1022        diff_info_list.append(
1023            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_SINCE_A_TO_B, old_since, new_since)))
1024    return diff_info_list
1025
1026
1027def process_tag_syscap(old_tag, new_tag, old_info, new_info):
1028    diff_info_list = []
1029    if old_tag is None:
1030        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_SYSCAP_NA_TO_HAVE,
1031                                                                          'NA',
1032                                                                          f'{new_tag["name"]} '
1033                                                                          f'{new_tag["description"]}')))
1034        return diff_info_list
1035    if new_tag is None:
1036        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_SYSCAP_HAVE_TO_NA,
1037                                                                          f'{old_tag["name"]} '
1038                                                                          f'{old_tag["description"]}',
1039                                                                          'NA')))
1040        return diff_info_list
1041    old_syscap = f'{old_tag["name"]} {old_tag["description"]}'
1042    new_syscap = f'{new_tag["name"]} {new_tag["description"]}'
1043    if old_syscap != new_syscap:
1044        diff_info_list.append(
1045            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_SYSCAP_A_TO_B, old_syscap, new_syscap)))
1046    return diff_info_list
1047
1048
1049def process_tag_left_brace(old_tag, new_tag, old_info, new_info):
1050    diff_info_list = []
1051    if old_tag is None:
1052        diff_info_list.append(
1053            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_LEFT_BRACE_NA_TO_HAVE, 'NA', new_tag["name"])))
1054        return diff_info_list
1055    if new_tag is None:
1056        diff_info_list.append(
1057            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.DOC_TAG_LEFT_BRACE_HAVE_TO_NA, old_tag['name'], 'NA')))
1058        return diff_info_list
1059    return diff_info_list
1060
1061
1062def process_tag_right_brace(old_tag, new_tag, old_info, new_info):
1063    diff_info_list = []
1064    if old_tag is None:
1065        diff_info_list.append(wrap_diff_info(old_info, new_info,
1066                                             DiffInfo(DiffType.DOC_TAG_RIGHT_BRACE_NA_TO_HAVE, 'NA', new_tag["name"])))
1067        return diff_info_list
1068    if new_tag is None:
1069        diff_info_list.append(wrap_diff_info(old_info, new_info,
1070                                             DiffInfo(DiffType.DOC_TAG_RIGHT_BRACE_HAVE_TO_NA, old_tag['name'], 'NA')))
1071        return diff_info_list
1072    return diff_info_list
1073
1074
1075process_tag_function = {
1076    TAGS['ADD_TO_GROUP'].value: process_tag_addtogroup,
1077    TAGS['BRIEF'].value: process_tag_brief,
1078    TAGS['DEPRECATED'].value: process_tag_deprecated,
1079    TAGS['FILE'].value: process_tag_file,
1080    TAGS['LIBRARY'].value: process_tag_library,
1081    TAGS['PARAM'].value: process_tag_param,
1082    TAGS['PERMISSION'].value: process_tag_permission,
1083    TAGS['RETURN'].value: process_tag_return,
1084    TAGS['SINCE'].value: process_tag_since,
1085    TAGS['SYSCAP'].value: process_tag_syscap,
1086    TAGS['LEFT_BRACE'].value: process_tag_left_brace,
1087    TAGS['RIGHT_BRACE'].value: process_tag_right_brace,
1088}
1089
1090
1091def process_comment(comment: str):
1092    '''
1093    处理comment数据,通过node调用comment-parser解析doc注释
1094    '''
1095    result_json = []
1096    if comment == "none_comment":
1097        return result_json
1098    result = subprocess.check_output(
1099        ['node', os.path.abspath(os.path.join(current_file, "../comment_parser.js")), comment])  # 解析comment
1100    result_json: list = json.loads(result.decode('utf-8'))
1101    return result_json
1102
1103
1104def get_tag_dict_from_list(tag_list):
1105    tag_dict = dict()
1106    for tag in tag_list:
1107        if tag['tag'] in tag_dict.keys():
1108            tag_dict[tag['tag']].append(tag)
1109        else:
1110            tag_dict[tag['tag']] = [tag]
1111    return tag_dict
1112
1113
1114def process_doc(old_doc, new_doc, old_info, new_info):
1115    diff_info_list = []
1116    old_tag_list = old_doc['tags']
1117    new_tag_list = new_doc['tags']
1118    old_tag_dict = get_tag_dict_from_list(old_tag_list)
1119    new_tag_dict = get_tag_dict_from_list(new_tag_list)
1120    for item in old_tag_dict.keys() | new_tag_dict.keys():
1121        if item not in process_tag_function.keys():
1122            continue
1123        old_tag = []
1124        new_tag = []
1125        if item in old_tag_dict.keys():
1126            old_tag = old_tag_dict.get(item)
1127        if item in new_tag_dict.keys():
1128            new_tag = new_tag_dict.get(item)
1129        max_length = max(len(old_tag), len(new_tag))
1130        while len(old_tag) < max_length:
1131            old_tag += [None] * (max_length - len(old_tag))
1132        while len(new_tag) < max_length:
1133            new_tag += [None] * (max_length - len(new_tag))
1134        tag_process = process_tag_function[item]
1135        index = 0
1136        while index < max_length:
1137            diff_info_list.extend(tag_process(old_tag[index], new_tag[index], old_info, new_info))
1138            index += 1
1139
1140    return diff_info_list
1141
1142
1143def process_doc_list(old_doc_list: list, new_doc_list: list, old_info, new_info):
1144    diff_info_list = []
1145    old_length = len(old_doc_list)
1146    new_length = len(new_doc_list)
1147    index = 0
1148    while index < max(old_length, new_length):
1149        if index >= old_length != new_length:
1150            diff_info_list.append(wrap_diff_info(old_info, new_info,
1151                                                 DiffInfo(DiffType.ADD_DOC, old_doc_list[index], new_doc_list[index])))
1152            break
1153        if index >= new_length != old_length:
1154            diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.REDUCE_DOC, old_doc_list[index],
1155                                                                              new_doc_list[index])))
1156            break
1157        diff_info_list.extend(process_doc(old_doc_list[index], new_doc_list[index], old_info, new_info))
1158        index += 1
1159
1160    return diff_info_list
1161
1162
1163def get_eligible_labels_doc(doc_element):
1164    addtogroup_doc_list_right = []
1165    file_doc_list_right = []
1166    if 'tags' in doc_element:
1167        for element in doc_element['tags']:
1168            if element.get('tag') and 'addtogroup' == element.get('tag'):
1169                addtogroup_doc_list_right.append(doc_element)
1170                break
1171            elif element.get('tag') and 'file' == element.get('tag'):
1172                file_doc_list_right.append(doc_element)
1173                break
1174    return addtogroup_doc_list_right, file_doc_list_right
1175
1176
1177def get_addtogroup_and_file_doc(doc_list: list):
1178    addtogroup_doc_list = []
1179    file_doc_list = []
1180    for doc_element in doc_list:
1181        result_of_addtogroup_list, result_of_file_list = get_eligible_labels_doc(doc_element)
1182        addtogroup_doc_list.extend(result_of_addtogroup_list)
1183        file_doc_list.extend(result_of_file_list)
1184
1185    return addtogroup_doc_list, file_doc_list
1186
1187
1188def filtrate_comments(comment: str):  # 获取每个头文件的最开始注释
1189    file_comment = ''
1190    if comment:
1191        pattern = RegularExpressions.START_COMMENT.value
1192        matches = re.finditer(pattern, comment, re.DOTALL | re.MULTILINE)
1193        for mat in matches:
1194            file_comment = '{}{}\n'.format(file_comment, mat.group())
1195    return file_comment
1196
1197
1198def process_addtogroup_and_file_list(old_list, new_list, old_info, new_info, num_key):
1199    old_len = len(old_list)
1200    new_len = len(new_list)
1201    result_list = []
1202    # addtogroup tag
1203    if 1 == num_key:
1204        if old_len > new_len:
1205            old_file_comment = filtrate_comments(old_info['comment'])
1206            new_file_comment = 'NA'
1207            result_list.append(wrap_diff_info(old_info, new_info,
1208                                              DiffInfo(DiffType.DOC_TAG_ADDTOGROUP_DECREASE, old_file_comment,
1209                                                       new_file_comment)))
1210        elif old_len < new_len:
1211            old_file_comment = 'NA'
1212            new_file_comment = filtrate_comments(new_info['comment'])
1213            result_list.append(wrap_diff_info(old_info, new_info,
1214                                              DiffInfo(DiffType.DOC_TAG_ADDTOGROUP_INCREASE, old_file_comment,
1215                                                       new_file_comment)))
1216        else:
1217            result_list.extend(process_doc_list(old_list, new_list, old_info, new_info))
1218    # file tag
1219    elif 0 == num_key:
1220        if old_len > new_len:
1221            old_file_comment = filtrate_comments(old_info['comment'])
1222            new_file_comment = 'NA'
1223            result_list.append(wrap_diff_info(old_info, new_info,
1224                                              DiffInfo(DiffType.DOC_TAG_FILE_DECREASE, old_file_comment,
1225                                                       new_file_comment)))
1226        elif old_len < new_len:
1227            old_file_comment = 'NA'
1228            new_file_comment = filtrate_comments(new_info['comment'])
1229            result_list.append(wrap_diff_info(old_info, new_info,
1230                                              DiffInfo(DiffType.DOC_TAG_FILE_INCREASE, old_file_comment,
1231                                                       new_file_comment)))
1232        else:
1233            result_list.extend(process_doc_list(old_list, new_list, old_info, new_info))
1234    return result_list
1235
1236
1237def process_comment_str(old_info, new_info):
1238    diff_info_list = []
1239    if old_info['comment'] == new_info['comment']:
1240        return diff_info_list
1241    if old_info['comment'] == 'none_comment':
1242        diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.ADD_DOC, "NA", new_info['comment'])))
1243        return diff_info_list
1244    if new_info['comment'] == 'none_comment':
1245        diff_info_list.append(
1246            wrap_diff_info(old_info, new_info, DiffInfo(DiffType.REDUCE_DOC, old_info['comment'], "NA")))
1247        return diff_info_list
1248    old_doc_list = process_comment(old_info['comment'])
1249    new_doc_list = process_comment(new_info['comment'])
1250    if new_info['kind'] == CursorKind.TRANSLATION_UNIT.name:
1251        old_addtogroup_doc_list, old_file_doc_list = get_addtogroup_and_file_doc(old_doc_list)
1252        new_addtogroup_doc_list, new_file_doc_list = get_addtogroup_and_file_doc(new_doc_list)
1253        diff_info_list.extend(process_addtogroup_and_file_list(old_addtogroup_doc_list, new_addtogroup_doc_list,
1254                                                               old_info, new_info, 1))
1255        diff_info_list.extend(process_addtogroup_and_file_list(old_file_doc_list, new_file_doc_list,
1256                                                               old_info, new_info, 0))
1257    else:
1258        if len(old_doc_list) > len(new_doc_list):
1259            diff_info_list.append(wrap_diff_info(old_info, new_info, DiffInfo(DiffType.REDUCE_DOC, old_info['comment'],
1260                                                                              new_info['comment'])))
1261        elif len(old_doc_list) < len(new_doc_list):
1262            diff_info_list.append(wrap_diff_info(old_info, new_info,
1263                                                 DiffInfo(DiffType.ADD_DOC, old_info['comment'], new_info['comment'])))
1264        else:
1265            diff_info_list.extend(process_doc_list(
1266                [old_doc_list[len(old_doc_list) - 1]], [new_doc_list[len(new_doc_list) - 1]],
1267                old_info, new_info))
1268    return diff_info_list
1269