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