1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2024 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 16from utils.util import (get_start_characters, get_remaining_characters, json_file_data, label_type_conversion, 17 get_check_labels, generate_excel, get_position_information, 18 set_label_to_result, get_js_doc_info) 19from utils.constants import (mutex_label_dist, contrast_function, label_name_dist, one_to_many_function, 20 label_comparison_dist) 21from typedef.detection import Output, ErrorMessage, ErrorType 22from coreImpl.process_three_type import process_tag_dict 23from typedef.process_three_type import get_judgment_node_type_dict 24 25 26result_list = [] 27check_label_list = [] 28 29 30def judgement_dict_data(result, result_key): 31 my_dict = dict() 32 for dict_data in result[result_key]: # 代表对应文件的解析数据 33 judgment_node_type = get_judgment_node_type_dict() 34 # 互斥标签 35 if 'jsDocInfos' in dict_data: 36 if len(dict_data['jsDocInfos']) > 0: 37 get_mutex_label(dict_data) 38 # 枚举类标签检测 39 if dict_data['apiType'] == 'Enum': 40 enum_label_detection(dict_data) 41 elif 'apiType' in dict_data and dict_data['apiType'] in judgment_node_type: 42 message_list = process_tag_dict(dict_data, check_label_list) 43 if message_list: 44 result_list.extend(message_list) 45 get_data_info(dict_data, my_dict) 46 dict_keys = dict_data.keys() 47 if 'childApis' in dict_keys: # 递归处理child 48 judgement_dict_data(dict_data, 'childApis') 49 # 校验成对函数漏标 50 paired_function_omission_label(my_dict) 51 52 53def get_data_info(dict_data, my_dict): 54 if 'jsDocInfos' in dict_data: 55 if get_js_doc_info(dict_data['jsDocInfos']) is not None: 56 if not label_type_conversion(get_js_doc_info(dict_data['jsDocInfos'])['deprecatedVersion']): 57 my_dict[dict_data['definedText']] = dict_data 58 59 60def enum_label_detection(parent_enum_info: dict): 61 if 'jsDocInfos' not in parent_enum_info: 62 return 63 parent_js_doc_info = get_js_doc_info(parent_enum_info['jsDocInfos']) 64 if parent_js_doc_info is None: 65 return 66 children_list = parent_enum_info['childApis'] 67 for check_label in check_label_list: 68 check_enum(children_list, parent_enum_info, check_label, parent_js_doc_info) 69 70 71def check_enum(children_list, parent_enum_info, check_label, parent_js_doc_info): 72 count = 0 73 for child_info in children_list: 74 child_doc_info = get_js_doc_info(child_info['jsDocInfos']) 75 if child_doc_info is None: 76 continue 77 if child_doc_info[label_comparison_dist.get(check_label)]: 78 count = count + 1 79 if count == 0: 80 # 父有子无 81 if parent_js_doc_info[label_comparison_dist.get(check_label)]: 82 result = Output(parent_enum_info['filePath'], ErrorType.ENUM_VALUE_LABEL.value, 83 parent_enum_info['definedText'], 84 get_position_information(parent_enum_info['pos']), 85 set_label_to_result(ErrorMessage.ENUM_VALUE_LABEL.value, 86 parent_enum_info['apiName'], 87 label_name_dist.get(label_comparison_dist.get(check_label)))) 88 result_list.append(result) 89 else: 90 # 子有父无 91 if not parent_js_doc_info[label_comparison_dist.get(check_label)]: 92 result = Output(parent_enum_info['filePath'], ErrorType.ENUM_LABEL.value, parent_enum_info['definedText'], 93 get_position_information(parent_enum_info['pos']), 94 set_label_to_result(ErrorMessage.ENUM_LABEL.value, 95 parent_enum_info['apiName'], 96 label_name_dist.get(label_comparison_dist.get(check_label)))) 97 result_list.append(result) 98 99 100# 成对出现的函数漏标 101def paired_function_omission_label(my_dict: dict): 102 filter_duplicates_dist = [] # 存储结果,防止重复 103 for defined_text in my_dict: 104 if is_pairing_function(defined_text, my_dict): 105 pairing(defined_text, my_dict, filter_duplicates_dist) 106 107 108def is_pairing_function(defined_text, my_dict: dict): 109 target_api_info = my_dict[defined_text] 110 api_type = target_api_info['apiType'] 111 if api_type != 'Method': 112 return False 113 start = get_start_characters(target_api_info['apiName']) 114 return start in contrast_function.keys() 115 116 117def pairing(defined_text, my_dict, filter_duplicates_dist): 118 function_name = my_dict[defined_text]['apiName'] 119 start = get_start_characters(function_name) 120 api_name_list = [] 121 # 4个中的其中之一 122 if start in one_to_many_function: 123 dismantle_one_to_many(my_dict, start, function_name, api_name_list) 124 else: 125 dismantle_ordinary(start, my_dict, function_name, api_name_list) 126 127 # 找到对应的函数 128 if len(api_name_list) != 0: 129 function_target_data = my_dict[defined_text] 130 for api_name in api_name_list: 131 api_info = my_dict[api_name] 132 handling_missing_labels(function_target_data, api_info, filter_duplicates_dist) 133 134 135def dismantle_one_to_many(my_dict: dict, start, function_name, api_name_list): 136 for defined_text in my_dict: 137 api_name = my_dict[defined_text]['apiName'] 138 if get_start_characters(api_name) in one_to_many_function: 139 if (get_remaining_characters(get_start_characters(api_name), api_name) 140 == get_remaining_characters(start, function_name) and function_name != api_name): 141 api_name_list.append(defined_text) 142 143 144def dismantle_ordinary(start, my_dict: dict, function_name, api_name_list): 145 relative_function = contrast_function.get(start) 146 for defined_text in my_dict: 147 api_name = my_dict[defined_text]['apiName'] 148 if get_start_characters(api_name) == relative_function: 149 if (get_remaining_characters(relative_function, api_name) 150 == get_remaining_characters(start, function_name)): 151 api_name_list.append(defined_text) 152 153 154# 处理成对函数漏标问题 155def handling_missing_labels(function_target_data: dict, function_relative_data: dict, filter_duplicates_dist): 156 # 目标函数与相对函数Doc信息都为空,直接返回不做判断 157 if 'jsDocInfos' not in function_target_data and 'jsDocInfos' not in function_relative_data: 158 return 159 # 目标函数Doc信息为空,相对函数标记的标签全部为目标函数漏标 160 if 'jsDocInfos' not in function_target_data: 161 relative_doc_info = get_js_doc_info(function_relative_data['jsDocInfos']) 162 if relative_doc_info is None: 163 return 164 # 判断相对函数中标记的标签 165 one_function_is_empty(function_relative_data, filter_duplicates_dist) 166 return 167 # 相对函数Doc信息为空,目标函数标记的标签全部为相对函数漏标 168 if 'jsDocInfos' not in function_relative_data: 169 relative_doc_info = get_js_doc_info(function_target_data['jsDocInfos']) 170 if relative_doc_info is None: 171 return 172 # 判断相对函数中标记的标签 173 one_function_is_empty(function_target_data, filter_duplicates_dist) 174 return 175 176 # 目标函数和相对函数Doc信息都不为空 177 target_doc_info = get_js_doc_info(function_target_data['jsDocInfos']) 178 relative_doc_info = get_js_doc_info(function_relative_data['jsDocInfos']) 179 target_label_info = get_check_labels(target_doc_info, check_label_list) 180 relative_label_info = get_check_labels(relative_doc_info, check_label_list) 181 diff = target_label_info.keys() & relative_label_info 182 diff_vals = [k for k in diff if target_label_info[k] != relative_label_info[k]] 183 if len(diff_vals) == 0: 184 return 185 for val in diff_vals: 186 if target_label_info.get(val): 187 get_label_exclusivity_results(function_relative_data, filter_duplicates_dist, val) 188 else: 189 get_label_exclusivity_results(function_target_data, filter_duplicates_dist, val) 190 191 192def one_function_is_empty(function_info: dict, filter_duplicates_dist): 193 doc_info = get_js_doc_info(function_info['jsDocInfos']) 194 if doc_info is None: 195 return 196 # 判断需要校验的标签 197 for check_label in check_label_list: 198 if doc_info[label_comparison_dist.get(check_label)]: 199 get_label_exclusivity_results(function_info, filter_duplicates_dist, label_comparison_dist.get(check_label)) 200 201 202def get_label_exclusivity_results(relative_data: dict, filter_duplicates_dist, val): 203 defined_text = relative_data['definedText'] + val 204 if defined_text not in filter_duplicates_dist: 205 result = Output(relative_data['filePath'], ErrorType.RELATIVE_LABEL.value, relative_data['definedText'], 206 get_position_information(relative_data['pos']), 207 set_label_to_result(ErrorMessage.RELATIVE_LABEL.value, 208 relative_data['apiName'], label_name_dist.get(val))) 209 result_list.append(result) 210 filter_duplicates_dist.append(relative_data['definedText'] + val) 211 212 213# 互斥标签排查 214def get_mutex_label(api_info: dict): 215 doc_info = get_js_doc_info(api_info['jsDocInfos']) 216 if doc_info is None: 217 return 218 for label in mutex_label_dist: 219 mutex_label_list = mutex_label_dist.get(label) 220 is_label_consistent(doc_info, label, mutex_label_list, api_info) 221 222 223def is_label_consistent(doc_info: dict, label, mutex_label_list, api_info): 224 is_dimension = label_type_conversion(doc_info[label]) 225 if not is_dimension: 226 return 227 for mutex_label in mutex_label_list: 228 if label_type_conversion(doc_info[mutex_label]): 229 result = Output(api_info['filePath'], ErrorType.MUTEX_LABEL.value, api_info['definedText'], 230 get_position_information(api_info['pos']), 231 set_label_to_result(ErrorMessage.MUTEX_LABEL.value, label_name_dist.get(label), 232 label_name_dist.get(mutex_label))) 233 result_list.append(result) 234 235 236# 按装订区域中的绿色按钮以运行脚本。 237def detection_label(check_labels, result_json_path, output_path): 238 split_labels(check_labels) 239 data = json_file_data(result_json_path) 240 for key in data: # 代表每个ts文件 241 judgement_dict_data(data, key) 242 if len(result_list) == 0: 243 print('The file check is passed.') 244 else: 245 print('File check failed,{} questions in total.Please check the table.'.format(len(result_list))) 246 generate_excel(result_list, output_path) 247 248 249def split_labels(labels: str): 250 if labels == 'all': 251 check_label_list.extend(label_comparison_dist.keys()) 252 else: 253 check_label_list.extend(labels.split('-')) 254