13af6ab5fSopenharmony_ci#!/usr/bin/env python3 23af6ab5fSopenharmony_ci# coding=utf-8 33af6ab5fSopenharmony_ci# 43af6ab5fSopenharmony_ci# Copyright (c) 2024 Huawei Device Co., Ltd. 53af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 63af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License. 73af6ab5fSopenharmony_ci# You may obtain a copy of the License at 83af6ab5fSopenharmony_ci# 93af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 103af6ab5fSopenharmony_ci# 113af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 123af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 133af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and 153af6ab5fSopenharmony_ci# limitations under the License. 163af6ab5fSopenharmony_ci 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci""" 193af6ab5fSopenharmony_ciProvides: 203af6ab5fSopenharmony_ci- parse_type 213af6ab5fSopenharmony_ci- parse_argument 223af6ab5fSopenharmony_ci- parse_arguments 233af6ab5fSopenharmony_ci""" 243af6ab5fSopenharmony_ci 253af6ab5fSopenharmony_cifrom typing import Tuple, List, Any, Dict 263af6ab5fSopenharmony_cifrom log_tools import warning_log 273af6ab5fSopenharmony_cifrom cpp_keywords import modifiers_list 283af6ab5fSopenharmony_cifrom text_tools import ( 293af6ab5fSopenharmony_ci find_first_of_characters, 303af6ab5fSopenharmony_ci find_first_not_restricted_character, 313af6ab5fSopenharmony_ci find_scope_borders, 323af6ab5fSopenharmony_ci smart_find_first_of_characters, 333af6ab5fSopenharmony_ci rfind_first_not_restricted_character, 343af6ab5fSopenharmony_ci smart_split_by, 353af6ab5fSopenharmony_ci rfind_first_of_characters, 363af6ab5fSopenharmony_ci) 373af6ab5fSopenharmony_ci 383af6ab5fSopenharmony_ci 393af6ab5fSopenharmony_cidef parse_type(data: str) -> dict: 403af6ab5fSopenharmony_ci data = data.strip(" \n") 413af6ab5fSopenharmony_ci if len(data) > 100: 423af6ab5fSopenharmony_ci warning_log("Parsing big type!\n---\n" + data + "\n---\n") 433af6ab5fSopenharmony_ci 443af6ab5fSopenharmony_ci if data == "": 453af6ab5fSopenharmony_ci return {} 463af6ab5fSopenharmony_ci 473af6ab5fSopenharmony_ci res: Dict[str, Any] = {} 483af6ab5fSopenharmony_ci current_pos = extract_type_name(data, res) 493af6ab5fSopenharmony_ci 503af6ab5fSopenharmony_ci for modifier in modifiers_list: 513af6ab5fSopenharmony_ci if data.find(modifier, current_pos) != -1: 523af6ab5fSopenharmony_ci if "other_modifiers" not in res: 533af6ab5fSopenharmony_ci res["other_modifiers"] = "" 543af6ab5fSopenharmony_ci 553af6ab5fSopenharmony_ci res["other_modifiers"] = f"{res['other_modifiers']} {modifier}".strip(" ") 563af6ab5fSopenharmony_ci 573af6ab5fSopenharmony_ci # Weakness (<>) 583af6ab5fSopenharmony_ci start_of_parenthes = data.find("(") 593af6ab5fSopenharmony_ci if start_of_parenthes != -1: 603af6ab5fSopenharmony_ci start_of_parenthes, end_of_parenthes = find_scope_borders(data, start_of_parenthes, "(") 613af6ab5fSopenharmony_ci res["cast_from"] = data[start_of_parenthes + 1 : end_of_parenthes] 623af6ab5fSopenharmony_ci current_pos = end_of_parenthes + 1 633af6ab5fSopenharmony_ci 643af6ab5fSopenharmony_ci # Template in arg 653af6ab5fSopenharmony_ci template_open_pos = data.find("<", current_pos) 663af6ab5fSopenharmony_ci if template_open_pos != -1: 673af6ab5fSopenharmony_ci template_open_pos, template_close_pos = find_scope_borders(data, 0, "<") 683af6ab5fSopenharmony_ci 693af6ab5fSopenharmony_ci offset, res["template_args"] = parse_arguments(data[template_open_pos + 1 : template_close_pos], 0, "types") 703af6ab5fSopenharmony_ci current_pos = template_open_pos + 1 + offset + 1 713af6ab5fSopenharmony_ci 723af6ab5fSopenharmony_ci # Ptr 733af6ab5fSopenharmony_ci ptr_start = data.find("*", current_pos) 743af6ab5fSopenharmony_ci if ptr_start != -1: 753af6ab5fSopenharmony_ci 763af6ab5fSopenharmony_ci ptr_end = find_first_not_restricted_character("*", data, ptr_start) 773af6ab5fSopenharmony_ci 783af6ab5fSopenharmony_ci res["ptr_depth"] = ptr_end - ptr_start 793af6ab5fSopenharmony_ci current_pos = ptr_end 803af6ab5fSopenharmony_ci 813af6ab5fSopenharmony_ci # Ref 823af6ab5fSopenharmony_ci ref_start = data.find("&", current_pos) 833af6ab5fSopenharmony_ci if ref_start != -1: 843af6ab5fSopenharmony_ci 853af6ab5fSopenharmony_ci ref_end = find_first_not_restricted_character("&", data, ref_start) 863af6ab5fSopenharmony_ci 873af6ab5fSopenharmony_ci res["ref_depth"] = ref_end - ref_start 883af6ab5fSopenharmony_ci current_pos = ref_end 893af6ab5fSopenharmony_ci 903af6ab5fSopenharmony_ci postfix = data[current_pos:].strip(" \n") 913af6ab5fSopenharmony_ci if postfix != "": 923af6ab5fSopenharmony_ci res["postfix"] = postfix 933af6ab5fSopenharmony_ci 943af6ab5fSopenharmony_ci return res 953af6ab5fSopenharmony_ci 963af6ab5fSopenharmony_ci 973af6ab5fSopenharmony_cidef extract_type_name(data: str, res: Dict[str, Any]) -> int: 983af6ab5fSopenharmony_ci prefix_modifiers = "" 993af6ab5fSopenharmony_ci type_name_start = 0 1003af6ab5fSopenharmony_ci type_name_end = find_first_of_characters(" <([{&*", data, type_name_start) 1013af6ab5fSopenharmony_ci type_name = data[type_name_start:type_name_end].strip(" \n") 1023af6ab5fSopenharmony_ci 1033af6ab5fSopenharmony_ci # Extract type name 1043af6ab5fSopenharmony_ci while type_name in modifiers_list or type_name == "": 1053af6ab5fSopenharmony_ci prefix_modifiers += f" {type_name}" 1063af6ab5fSopenharmony_ci 1073af6ab5fSopenharmony_ci type_name_start = find_first_not_restricted_character(" <*", data, type_name_end) 1083af6ab5fSopenharmony_ci type_name_end = find_first_of_characters(" <(*", data, type_name_start) 1093af6ab5fSopenharmony_ci 1103af6ab5fSopenharmony_ci if type_name_start == len(data): 1113af6ab5fSopenharmony_ci type_name = "" 1123af6ab5fSopenharmony_ci break 1133af6ab5fSopenharmony_ci 1143af6ab5fSopenharmony_ci type_name = data[type_name_start:type_name_end].strip(" \n") 1153af6ab5fSopenharmony_ci 1163af6ab5fSopenharmony_ci # 'varbinder::LocalVariable' -> 'LocalVariable' 1173af6ab5fSopenharmony_ci if type_name.find("::") != -1: 1183af6ab5fSopenharmony_ci namespace = type_name[: type_name.rfind("::")] 1193af6ab5fSopenharmony_ci type_name = type_name[type_name.rfind("::") + 2 :] 1203af6ab5fSopenharmony_ci res["namespace"] = namespace 1213af6ab5fSopenharmony_ci 1223af6ab5fSopenharmony_ci if type_name != "": 1233af6ab5fSopenharmony_ci res["name"] = type_name 1243af6ab5fSopenharmony_ci 1253af6ab5fSopenharmony_ci prefix_modifiers = prefix_modifiers.strip(" ") 1263af6ab5fSopenharmony_ci if prefix_modifiers != "": 1273af6ab5fSopenharmony_ci res["prefix"] = prefix_modifiers 1283af6ab5fSopenharmony_ci 1293af6ab5fSopenharmony_ci return type_name_end 1303af6ab5fSopenharmony_ci 1313af6ab5fSopenharmony_ci 1323af6ab5fSopenharmony_cidef parse_argument(arg: str, mode: str = "args") -> Dict: 1333af6ab5fSopenharmony_ci """ 1343af6ab5fSopenharmony_ci modes: 1353af6ab5fSopenharmony_ci - args: <type> <var_name> 1363af6ab5fSopenharmony_ci - types: <only_type> 1373af6ab5fSopenharmony_ci """ 1383af6ab5fSopenharmony_ci 1393af6ab5fSopenharmony_ci res: Dict[str, Any] = {} 1403af6ab5fSopenharmony_ci arg = arg.strip(" \n") 1413af6ab5fSopenharmony_ci 1423af6ab5fSopenharmony_ci if arg == "": 1433af6ab5fSopenharmony_ci return {} 1443af6ab5fSopenharmony_ci 1453af6ab5fSopenharmony_ci # Default value 1463af6ab5fSopenharmony_ci equally_pos = smart_find_first_of_characters("=", arg, 0) 1473af6ab5fSopenharmony_ci if equally_pos != len(arg): 1483af6ab5fSopenharmony_ci default_value_start = find_first_not_restricted_character(" ", arg, equally_pos + 1) 1493af6ab5fSopenharmony_ci default_value_end = rfind_first_not_restricted_character("\n; ", arg, len(arg) - 1) 1503af6ab5fSopenharmony_ci res["default_value"] = arg[default_value_start : default_value_end + 1] 1513af6ab5fSopenharmony_ci 1523af6ab5fSopenharmony_ci arg = arg[:equally_pos].strip(" \n") 1533af6ab5fSopenharmony_ci 1543af6ab5fSopenharmony_ci # Default constructor 1553af6ab5fSopenharmony_ci if smart_find_first_of_characters("{", arg, 0) != len(arg): 1563af6ab5fSopenharmony_ci start_of_constr, end_of_constr = find_scope_borders(arg) 1573af6ab5fSopenharmony_ci res["default_constructor"] = arg[start_of_constr + 1 : end_of_constr] 1583af6ab5fSopenharmony_ci arg = arg[:start_of_constr].strip(" \n") 1593af6ab5fSopenharmony_ci 1603af6ab5fSopenharmony_ci # Name 1613af6ab5fSopenharmony_ci if mode == "args": 1623af6ab5fSopenharmony_ci name_start = rfind_first_of_characters(" *&>)}", arg, len(arg) - 1) 1633af6ab5fSopenharmony_ci if name_start != len(arg) and name_start != len(arg) - 1: 1643af6ab5fSopenharmony_ci name = arg[name_start + 1 :].strip(" \n") 1653af6ab5fSopenharmony_ci if name != "": 1663af6ab5fSopenharmony_ci res["name"] = name 1673af6ab5fSopenharmony_ci else: 1683af6ab5fSopenharmony_ci raise RuntimeError("Error! Argument without name!") 1693af6ab5fSopenharmony_ci 1703af6ab5fSopenharmony_ci res["type"] = parse_type(arg[: name_start + 1]) 1713af6ab5fSopenharmony_ci else: 1723af6ab5fSopenharmony_ci res["type"] = parse_type(arg) 1733af6ab5fSopenharmony_ci 1743af6ab5fSopenharmony_ci return res 1753af6ab5fSopenharmony_ci 1763af6ab5fSopenharmony_ci 1773af6ab5fSopenharmony_cidef parse_arguments(data: str, start: int = 0, mode: str = "args") -> Tuple[int, List]: 1783af6ab5fSopenharmony_ci """ 1793af6ab5fSopenharmony_ci data: 1803af6ab5fSopenharmony_ci - (some arguments, ...) ... some code ... 1813af6ab5fSopenharmony_ci - arg1, arg2, ..., arg_k 1823af6ab5fSopenharmony_ci mode: 1833af6ab5fSopenharmony_ci - args: TYPE ARG_NAME, ... 1843af6ab5fSopenharmony_ci - types: TYPE, ... 1853af6ab5fSopenharmony_ci """ 1863af6ab5fSopenharmony_ci res = [] 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci start_of_args = 0 1893af6ab5fSopenharmony_ci end_of_args = len(data) 1903af6ab5fSopenharmony_ci 1913af6ab5fSopenharmony_ci if data[start] == "(": 1923af6ab5fSopenharmony_ci start_of_args, end_of_args = find_scope_borders(data, start, "(") 1933af6ab5fSopenharmony_ci start_of_args += 1 1943af6ab5fSopenharmony_ci 1953af6ab5fSopenharmony_ci args = data[start_of_args:end_of_args] 1963af6ab5fSopenharmony_ci args_list = smart_split_by(args, ",") 1973af6ab5fSopenharmony_ci 1983af6ab5fSopenharmony_ci for arg in args_list: 1993af6ab5fSopenharmony_ci parsed_arg = parse_argument(arg, mode) 2003af6ab5fSopenharmony_ci 2013af6ab5fSopenharmony_ci if parsed_arg: 2023af6ab5fSopenharmony_ci res.append(parsed_arg) 2033af6ab5fSopenharmony_ci 2043af6ab5fSopenharmony_ci return end_of_args, res 205