diff --git a/build-tools/capi_parser/src/coreImpl/comment_parser.js b/build-tools/capi_parser/src/coreImpl/comment_parser.js new file mode 100644 index 0000000000000000000000000000000000000000..0a26c334d72ca14b0b57ab343425e7974fdc1eb6 --- /dev/null +++ b/build-tools/capi_parser/src/coreImpl/comment_parser.js @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const { parse } = require('comment-parser'); +const SECOND_PARAM = 2; + +/** + * 解析节点的JSDoc信息,可能包含多段。 + * + * @param {string[]} jsdocText + * @returns {Array} + */ +function parseJSDocs(jsdocText) { + const result = parse(jsdocText); + return result; +} +const commentStr = process.argv[SECOND_PARAM]; +const value = parseJSDocs(commentStr); +console.log(JSON.stringify(value)); diff --git a/build-tools/capi_parser/src/coreImpl/diff/diff_processor_permission.py b/build-tools/capi_parser/src/coreImpl/diff/diff_processor_permission.py new file mode 100644 index 0000000000000000000000000000000000000000..14d813dd07be9b7e45702e8b2be8b166b66b8a89 --- /dev/null +++ b/build-tools/capi_parser/src/coreImpl/diff/diff_processor_permission.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# coding=utf-8 +############################################## +# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +############################################## +import re +import enum + + +class RangeChange(enum.Enum): + DOWN = 'down' + UP = 'up' + NO = 'no' + CHANGE = 'change' + + +class CalculateValue: + pass_data = [] + fail_data = [] + + +class DiffProcessorPermission: + # 转义规则 + splitchar = { + 'and': {'splitchar': 'and', 'transferchar': 'and'}, + 'or': {'splitchar': 'or', 'transferchar': 'or'}, + 'eq': {'splitchar': '=', 'transferchar': '=='}, + 'LE': {'splitchar': '->', 'transferchar': '<='}, + 'RE': {'splitchar': '<-', 'transferchar': '>='}, + 'not': {'splitchar': '-', 'transferchar': '!'}, + 'lcurve': {'splitchar': '\\(', 'transferchar': '('}, + 'rcurve': {'splitchar': '\\)', 'transferchar': ')'}, + } + variable_list = [] # 命题集合 + + def find_variable_list(self, string): # return all variable_list in the string. + for char in self.splitchar: + string = re.sub(re.compile(self.splitchar[char]['splitchar']), '', string) + str_set = set(string.split(' ')) + str_set.remove('') + variable_list = list(str_set) + variable_list.sort() + return tuple(variable_list) + + def formatten(self, string): + for char in self.splitchar: + string = re.sub(re.compile(self.splitchar[char]['splitchar']), self.splitchar[char]['transferchar'], string) + return string + + def get_bool_in_list(self, number_list, bin_len): + state_list = [bin(i) for i in number_list] + state_list = [x[2:] for x in state_list] + state_list = ['0' * (bin_len - len(x)) + x for x in state_list] + state_list = [tuple([bool(eval(y)) for y in x]) for x in state_list] + return tuple(state_list) + + def calculate(self, string: str, variable_length: int, state_list): + state_value = {i: None for i in range(2 ** variable_length)} + for state_index in range(2 ** variable_length): + modify_string = string + for variable_index in range(variable_length): + modify_string = modify_string.replace( + self.variable_list[variable_index], str(state_list[state_index][variable_index])) + state_value[state_index] = eval(modify_string) + return state_value + + def process_value(self, state_value): + calculate = CalculateValue() + for state in state_value: + if state_value[state]: + calculate.pass_data.append(state) + else: + calculate.fail_data.append(state) + return calculate + + def calculate_paradigm(self, string): + self.variable_list = self.find_variable_list(string) + string = self.formatten(string) + variable_length = len(self.variable_list) + state_list = self.get_bool_in_list(range(2 ** variable_length), variable_length) + state_value = self.calculate(string, variable_length, state_list) + calculate = self.process_value(state_value) + return calculate + + def calculate_paradigm_up(self, old_str, new_str, falg_bool=True): + char = '' + if falg_bool: + char = self.splitchar['LE']['splitchar'] + else: + char = self.splitchar['RE']['splitchar'] + merge_str = f'({old_str}) {char} ({new_str})' + return self.calculate_paradigm(merge_str) + + +class CalculateRsesult: + variable_list = [] + state_down = [] + state_up = [] + state_range = '' + + +def compare_permission(old_str, new_str): + permissor_tool = DiffProcessorPermission() + up_state = permissor_tool.calculate_paradigm_up(old_str, new_str, True) + down_state = permissor_tool.calculate_paradigm_up(old_str, new_str, False) + variable_list = permissor_tool.variable_list + calculate_rsesult = CalculateRsesult() + calculate_rsesult.variable_list = variable_list + if len(down_state.fail_data) > 0: + calculate_rsesult.state_up = permissor_tool.get_bool_in_list(down_state.fail_data, len(variable_list)) + calculate_rsesult.state_range = RangeChange.UP.value + if len(up_state.fail_data) > 0: + calculate_rsesult.state_down = permissor_tool.get_bool_in_list(up_state.fail_data, len(variable_list)) + if calculate_rsesult.state_range == '': + calculate_rsesult.state_range = RangeChange.DOWN.value + else: + calculate_rsesult.state_range = RangeChange.CHANGE.value + return calculate_rsesult diff --git a/build-tools/capi_parser/src/typedef/diff/diff.py b/build-tools/capi_parser/src/typedef/diff/diff.py new file mode 100644 index 0000000000000000000000000000000000000000..8b94d8beb97731e2f5990ce83d35d2e322b69ba6 --- /dev/null +++ b/build-tools/capi_parser/src/typedef/diff/diff.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import enum + + +class Scene(enum.Enum): + FUNCTION_DECL = 'FUNCTION_DECL' + MACRO_DEFINITION = 'MACRO_DEFINITION' + STRUCT_DECL = 'STRUCT_DECL' + UNION_DECL = 'UNION_DECL' + ENUM_DECL = 'ENUM_DECL' + VAR_DECL = 'VAR_DECL' + TYPEDEF_DECL = 'TYPEDEF_DECL' + + +class TAGS(enum.Enum): + ADD_TO_GROUP = 'addtogroup' + BRIEF = 'brief' + DEPRECATED = 'deprecated' + FILE = 'file' + LIBRARY = 'library' + PARAM = 'param' + PERMISSION = 'permission' + RETURN = 'return' + SINCE = 'since' + SYSCAP = 'syscap' + LEFT_BRACE = '{' + RIGHT_BRACE = '}' + + +class DiffType(enum.Enum): + DEFAULT = '' + ADD_API = '新增api' + REDUCE_API = '删除api' + ADD_DOC = '新增doc' + REDUCE_DOC = '删除doc' + ADD_DOC_TAG = '添加doc标签' + REDUCE_DOC_TAG = '删除doc标签' + FUNCTION_PARAM_POS_CHANGE = '修改函数参数位置' # 我觉得可以理解为函数参数类型改变 + + DEFINE_NAME_CHANGE = '宏名改变' + DEFINE_TEXT_CHANGE = '宏文本改变' + + FUNCTION_NAME_CHANGE = '函数名改变' + FUNCTION_RETURN_CHANGE = '函数返回类型改变' + FUNCTION_PARAM_NAME_CHANGE = '函数参数名改变' # 这个我觉得不考虑 + FUNCTION_PARAM_TYPE_CHANGE = '函数参数类型改变' + FUNCTION_PARAM_ADD = '添加函数参数' + FUNCTION_PARAM_REDUCE = '删除函数参数' + + STRUCT_NAME_CHANGE = '结构体名改变' + STRUCT_MEMBER_NAME_CHANGE = '结构体成员名改变' + STRUCT_MEMBER_TYPE_CHANGE = '结构体成员类型改变' + STRUCT_MEMBER_ADD = '添加结构体成员' + STRUCT_MEMBER_REDUCE = '删除结构体成员' + + UNION_NAME_CHANGE = '联合体名改变' + UNION_MEMBER_NAME_CHANGE = '联合体成员名改变' + UNION_MEMBER_TYPE_CHANGE = '联合体成员类型改变' + UNION_MEMBER_ADD = '添加联合体成员' + UNION_MEMBER_REDUCE = '删除联合体成员' + + ENUM_NAME_CHANGE = '枚举名改变' + ENUM_MEMBER_NAME_CHANGE = '枚举成员名改变' + ENUM_MEMBER_VALUE_CHANGE = '枚举成员值改变' + ENUM_MEMBER_ADD = '添加枚举成员' + ENUM_MEMBER_REDUCE = '删除枚举成员' + + VARIABLE_NAME_CHANGE = '变量名改变' + VARIABLE_TYPE_CHANGE = '变量类型改变' + VARIABLE_VALUE_CHANGE = '变量值的改变' + + CONSTANT_NAME_CHANGE = '常量名改变' + CONSTANT_TYPE_CHANGE = '常量类型改变' + CONSTANT_VALUE_CHANGE = '常量值的改变' + + TYPEDEF_NAME_TYPE_CHANGE = '重命名类型和命名改变' + + DOC_TAG_ADDTOGROUP_NA_TO_HAVE = '新增addtogroup标签' + DOC_TAG_ADDTOGROUP_HAVE_TO_NA = '删除addtogroup标签' + DOC_TAG_ADDTOGROUP_A_TO_B = '修改addtogroup标签' + DOC_TAG_BRIEF_NA_TO_HAVE = '新增brief标签' + DOC_TAG_BRIEF_HAVE_TO_NA = '删除brief标签' + DOC_TAG_BRIEF_A_TO_B = '修改brief标签' + DOC_TAG_DEPRECATED_NA_TO_HAVE = '接口变更为废弃' + DOC_TAG_DEPRECATED_HAVE_TO_NA = '废弃接口变更为不废弃' + DOC_TAG_DEPRECATED_A_TO_B = '接口废弃版本发生变化' + DOC_TAG_FILE_NA_TO_HAVE = '新增file标签' + DOC_TAG_FILE_HAVE_TO_NA = '删除file标签' + DOC_TAG_FILE_A_TO_B = '修改file标签' + DOC_TAG_LIBRARY_NA_TO_HAVE = '新增library' + DOC_TAG_LIBRARY_HAVE_TO_NA = '删除library' + DOC_TAG_LIBRARY_A_TO_B = '变更library' + DOC_TAG_PARAM_NA_TO_HAVE = '新增param标签' + DOC_TAG_PARAM_HAVE_TO_NA = '删除param标签' + DOC_TAG_PARAM_NAME_A_TO_B = '修改param标签描述信息' + DOC_TAG_PARAM_A_TO_B = '修改param标签描述信息' + DOC_TAG_PERMISSION_NA_TO_HAVE = '权限从无到有' + DOC_TAG_PERMISSION_HAVE_TO_NA = '权限从有到无' + DOC_TAG_PERMISSION_RANGE_BIGGER = '增加or或减少and权限' + DOC_TAG_PERMISSION_RANGE_SMALLER = '减少or或增加and权限' + DOC_TAG_PERMISSION_RANGE_CHANGE = '权限发送改变无法判断范围变化' + DOC_TAG_SINCE_NA_TO_HAVE = '新增since标签' + DOC_TAG_SINCE_HAVE_TO_NA = '删除since标签' + DOC_TAG_SINCE_A_TO_B = '修改since标签' + DOC_TAG_SYSCAP_NA_TO_HAVE = '从没有syscap到有syscap' + DOC_TAG_SYSCAP_HAVE_TO_NA = '从有syscap到没有syscap' + DOC_TAG_SYSCAP_A_TO_B = 'syscap发生改变' + DOC_TAG_LEFT_BRACE_NA_TO_HAVE = '新增左括号' + DOC_TAG_LEFT_BRACE_HAVE_TO_NA = '删除左括号' + DOC_TAG_RIGHT_BRACE_NA_TO_HAVE = '新增右括号' + DOC_TAG_RIGHT_BRACE_HAVE_TO_NA = '删除右括号' + + +compatible_list = [DiffType.FUNCTION_PARAM_NAME_CHANGE] + + +class DiffInfo: + api_name: str = '' + api_type: str = '' + diff_type: DiffType = DiffType.DEFAULT + diff_message: str = '' + old_api_full_text: str = '' + new_api_full_text: str = '' + is_compatible = False + + def __init__(self, diff_type: DiffType): + self.diff_type = diff_type + self.diff_message = diff_type.value + self.set_diff_type(diff_type) + + def set_api_name(self, api_name): + self.api_name = api_name + + def get_api_name(self): + return self.api_name + + def set_api_type(self, api_type): + self.api_type = api_type + + def get_api_type(self): + return self.api_type + + def set_diff_type(self, diff_type): + if diff_type in compatible_list: + self.is_compatible = True + self.diff_type = diff_type + + def get_diff_type(self): + return self.diff_type + + def set_diff_message(self, diff_message): + self.diff_message = diff_message + + def get_diff_message(self): + return self.diff_message + + def set_old_api_full_text(self, old_api_full_text): + self.old_api_full_text = old_api_full_text + + def get_old_api_full_text(self): + return self.old_api_full_text + + def set_new_api_full_text(self, new_api_full_text): + self.new_api_full_text = new_api_full_text + + def get_new_api_full_text(self): + return self.new_api_full_text + + def set_is_compatible(self, is_compatible): + self.is_compatible = is_compatible + + def get_is_compatible(self): + return self.is_compatible + + +class OutputJson: + api_name: str = '' + api_type: str = '' + diff_type: str = '' + diff_message: str = '' + old_api_full_text: str = '' + new_api_full_text: str = '' + is_compatible = False + + def __init__(self, diff_info): + self.api_name = diff_info.api_name + self.api_type = diff_info.api_type + self.diff_type = diff_info.diff_type.name + self.diff_message = diff_info.diff_message + self.old_api_full_text = diff_info.old_api_full_text + self.new_api_full_text = diff_info.new_api_full_text + self.is_compatible = diff_info.is_compatible