• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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