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