13af6ab5fSopenharmony_ci# Copyright (c) 2024 Huawei Device Co., Ltd. 23af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 33af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License. 43af6ab5fSopenharmony_ci# You may obtain a copy of the License at 53af6ab5fSopenharmony_ci# 63af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 73af6ab5fSopenharmony_ci# 83af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 93af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 103af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 113af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and 123af6ab5fSopenharmony_ci# limitations under the License. 133af6ab5fSopenharmony_ci 143af6ab5fSopenharmony_cirequire 'set' 153af6ab5fSopenharmony_cirequire 'delegate' 163af6ab5fSopenharmony_cirequire_relative 'enums.rb' 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_cimodule Es2pandaLibApi 193af6ab5fSopenharmony_ci class Arg 203af6ab5fSopenharmony_ci @primitive_types = nil 213af6ab5fSopenharmony_ci 223af6ab5fSopenharmony_ci # Containers 233af6ab5fSopenharmony_ci @es2panda_arg = nil 243af6ab5fSopenharmony_ci @lib_args = nil 253af6ab5fSopenharmony_ci @lib_cast = nil 263af6ab5fSopenharmony_ci @return_args = nil 273af6ab5fSopenharmony_ci @is_ast_node = false 283af6ab5fSopenharmony_ci @is_ast_node_add_children = false 293af6ab5fSopenharmony_ci @is_ast_type = false 303af6ab5fSopenharmony_ci @is_var_type = false 313af6ab5fSopenharmony_ci @is_enum_type = false 323af6ab5fSopenharmony_ci @is_scope_type = false 333af6ab5fSopenharmony_ci @is_code_gen = false 343af6ab5fSopenharmony_ci 353af6ab5fSopenharmony_ci # Flags 363af6ab5fSopenharmony_ci @need_var_cast = false 373af6ab5fSopenharmony_ci 383af6ab5fSopenharmony_ci def check_ptr_depth(change_type, ptr_depth) 393af6ab5fSopenharmony_ci !((change_type.es2panda_arg['min_ptr_depth'] && ptr_depth < change_type.es2panda_arg['min_ptr_depth']) || 403af6ab5fSopenharmony_ci (change_type.es2panda_arg['max_ptr_depth'] && ptr_depth > change_type.es2panda_arg['max_ptr_depth'])) 413af6ab5fSopenharmony_ci end 423af6ab5fSopenharmony_ci 433af6ab5fSopenharmony_ci def delete_ref(type) 443af6ab5fSopenharmony_ci type['ref_depth'] = 0 if type.respond_to?('ref_depth') 453af6ab5fSopenharmony_ci end 463af6ab5fSopenharmony_ci 473af6ab5fSopenharmony_ci def initialize(arg_info) 483af6ab5fSopenharmony_ci @primitive_types = [ 493af6ab5fSopenharmony_ci 'char', 503af6ab5fSopenharmony_ci 'char16_t', 513af6ab5fSopenharmony_ci 'short', 523af6ab5fSopenharmony_ci 'int', 533af6ab5fSopenharmony_ci 'long', 543af6ab5fSopenharmony_ci 'long long', 553af6ab5fSopenharmony_ci 'float', 563af6ab5fSopenharmony_ci 'double', 573af6ab5fSopenharmony_ci 'long double', 583af6ab5fSopenharmony_ci 'bool', 593af6ab5fSopenharmony_ci 'void', 603af6ab5fSopenharmony_ci 'size_t', 613af6ab5fSopenharmony_ci 'uint32_t', 623af6ab5fSopenharmony_ci 'int32_t', 633af6ab5fSopenharmony_ci 'int64_t', 643af6ab5fSopenharmony_ci 'es2panda_AstNode', 653af6ab5fSopenharmony_ci 'es2panda_Type', 663af6ab5fSopenharmony_ci 'es2panda_Scope' 673af6ab5fSopenharmony_ci ] 683af6ab5fSopenharmony_ci @es2panda_arg = arg_info 693af6ab5fSopenharmony_ci 703af6ab5fSopenharmony_ci found_change_type_link = Es2pandaLibApi.change_types.find do |x| 713af6ab5fSopenharmony_ci x.es2panda_arg.type.respond_to?('name') && x.es2panda_arg.type.name == @es2panda_arg['type']['name'] && 723af6ab5fSopenharmony_ci (!x.es2panda_arg.type.respond_to?('namespace') || 733af6ab5fSopenharmony_ci x.es2panda_arg.type.namespace == @es2panda_arg['type'].namespace) && 743af6ab5fSopenharmony_ci (!x.es2panda_arg.type.respond_to?('current_class') || 753af6ab5fSopenharmony_ci x.es2panda_arg.type['current_class'] == @es2panda_arg['type']['current_class']) && 763af6ab5fSopenharmony_ci check_ptr_depth(x, @es2panda_arg['type']['ptr_depth'] || 0) 773af6ab5fSopenharmony_ci end 783af6ab5fSopenharmony_ci 793af6ab5fSopenharmony_ci unless found_change_type_link 803af6ab5fSopenharmony_ci @is_ast_node = Es2pandaLibApi.ast_nodes.include?(@es2panda_arg['type'].name) && 813af6ab5fSopenharmony_ci (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'ir') 823af6ab5fSopenharmony_ci @is_ast_node_add_children = Es2pandaLibApi.ast_node_additional_children.include?(@es2panda_arg['type'].name) && 833af6ab5fSopenharmony_ci (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'ir') 843af6ab5fSopenharmony_ci @is_ast_type = Es2pandaLibApi.ast_types.include?(@es2panda_arg['type'].name) && 853af6ab5fSopenharmony_ci (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'checker') 863af6ab5fSopenharmony_ci @is_var_type = Es2pandaLibApi.ast_variables.any? { |variable| variable[1] == @es2panda_arg['type'].name } && 873af6ab5fSopenharmony_ci (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'varbinder') 883af6ab5fSopenharmony_ci @is_enum_type = Es2pandaLibApi.enums.include?(@es2panda_arg['type'].name) 893af6ab5fSopenharmony_ci @is_scope_type = Es2pandaLibApi.scopes.include?(@es2panda_arg['type'].name) && 903af6ab5fSopenharmony_ci (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'varbinder') 913af6ab5fSopenharmony_ci @is_code_gen = Es2pandaLibApi.code_gen_children.include?(@es2panda_arg['type'].name) && 923af6ab5fSopenharmony_ci (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'compiler') 933af6ab5fSopenharmony_ci 943af6ab5fSopenharmony_ci if @is_ast_type 953af6ab5fSopenharmony_ci found_change_type_link = Es2pandaLibApi.change_types.find do |x| 963af6ab5fSopenharmony_ci x.es2panda_arg.type == '|AstType|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) 973af6ab5fSopenharmony_ci end 983af6ab5fSopenharmony_ci end 993af6ab5fSopenharmony_ci 1003af6ab5fSopenharmony_ci if @is_ast_node 1013af6ab5fSopenharmony_ci found_change_type_link = Es2pandaLibApi.change_types.find do |x| 1023af6ab5fSopenharmony_ci x.es2panda_arg.type == '|AstNode|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) 1033af6ab5fSopenharmony_ci end 1043af6ab5fSopenharmony_ci end 1053af6ab5fSopenharmony_ci 1063af6ab5fSopenharmony_ci if @is_ast_node_add_children 1073af6ab5fSopenharmony_ci found_change_type_link = Es2pandaLibApi.change_types.find do |x| 1083af6ab5fSopenharmony_ci x.es2panda_arg.type == 1093af6ab5fSopenharmony_ci '|AstNodeAdditionalChildren|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) 1103af6ab5fSopenharmony_ci end 1113af6ab5fSopenharmony_ci end 1123af6ab5fSopenharmony_ci 1133af6ab5fSopenharmony_ci if @is_var_type 1143af6ab5fSopenharmony_ci found_change_type_link = Es2pandaLibApi.change_types.find do |x| 1153af6ab5fSopenharmony_ci x.es2panda_arg.type == '|Variable|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) 1163af6ab5fSopenharmony_ci end 1173af6ab5fSopenharmony_ci end 1183af6ab5fSopenharmony_ci 1193af6ab5fSopenharmony_ci if @is_enum_type 1203af6ab5fSopenharmony_ci found_change_type_link = Es2pandaLibApi.change_types.find do |x| 1213af6ab5fSopenharmony_ci x.es2panda_arg.type == '|Enum|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) 1223af6ab5fSopenharmony_ci end 1233af6ab5fSopenharmony_ci end 1243af6ab5fSopenharmony_ci 1253af6ab5fSopenharmony_ci if @is_scope_type 1263af6ab5fSopenharmony_ci found_change_type_link = Es2pandaLibApi.change_types.find do |x| 1273af6ab5fSopenharmony_ci x.es2panda_arg.type == '|Scope|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) 1283af6ab5fSopenharmony_ci end 1293af6ab5fSopenharmony_ci end 1303af6ab5fSopenharmony_ci 1313af6ab5fSopenharmony_ci if @is_code_gen 1323af6ab5fSopenharmony_ci found_change_type_link = Es2pandaLibApi.change_types.find do |x| 1333af6ab5fSopenharmony_ci x.es2panda_arg.type == '|CodeGen|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) 1343af6ab5fSopenharmony_ci end 1353af6ab5fSopenharmony_ci end 1363af6ab5fSopenharmony_ci end 1373af6ab5fSopenharmony_ci 1383af6ab5fSopenharmony_ci unless found_change_type_link || @primitive_types.include?(@es2panda_arg['type'].name) 1393af6ab5fSopenharmony_ci raise "Unsupported type: '" + @es2panda_arg['type'].name + "' ptr depth: " + 1403af6ab5fSopenharmony_ci (@es2panda_arg['type'].ptr_depth || 0).to_s 1413af6ab5fSopenharmony_ci end 1423af6ab5fSopenharmony_ci 1433af6ab5fSopenharmony_ci ptr_depth = @es2panda_arg['type']['ptr_depth'] || 0 1443af6ab5fSopenharmony_ci 1453af6ab5fSopenharmony_ci if found_change_type_link && !check_ptr_depth(found_change_type_link, ptr_depth) 1463af6ab5fSopenharmony_ci raise 'invalid ptr_depth: ' + ptr_depth.to_s + ', type: ' + @es2panda_arg['type'].name 1473af6ab5fSopenharmony_ci end 1483af6ab5fSopenharmony_ci 1493af6ab5fSopenharmony_ci if found_change_type_link && @es2panda_arg['name'] == 'returnType' && 1503af6ab5fSopenharmony_ci !found_change_type_link.cast.respond_to?('reverse_cast') 1513af6ab5fSopenharmony_ci raise 'Unsupported return type: ' + @es2panda_arg['type'].name + ' ptr depth: ' + 1523af6ab5fSopenharmony_ci (@es2panda_arg['type'].ptr_depth || 0).to_s 1533af6ab5fSopenharmony_ci end 1543af6ab5fSopenharmony_ci 1553af6ab5fSopenharmony_ci if found_change_type_link 1563af6ab5fSopenharmony_ci found_change_type = Marshal.load(Marshal.dump(found_change_type_link)) 1573af6ab5fSopenharmony_ci 1583af6ab5fSopenharmony_ci placeholders = find_placeholders(found_change_type.es2panda_arg) 1593af6ab5fSopenharmony_ci 1603af6ab5fSopenharmony_ci replacements = placeholders.map do |path, placeholder| 1613af6ab5fSopenharmony_ci value = get_value_by_path(@es2panda_arg, path) 1623af6ab5fSopenharmony_ci [placeholder, value] 1633af6ab5fSopenharmony_ci end 1643af6ab5fSopenharmony_ci 1653af6ab5fSopenharmony_ci found_change_type.es2panda_arg = Marshal.load(Marshal.dump(@es2panda_arg)) 1663af6ab5fSopenharmony_ci found_change_type = deep_replace(found_change_type, replacements) 1673af6ab5fSopenharmony_ci 1683af6ab5fSopenharmony_ci clever_replacements = [] 1693af6ab5fSopenharmony_ci template_args = [] 1703af6ab5fSopenharmony_ci 1713af6ab5fSopenharmony_ci if found_change_type&.new_args&.length && found_change_type.new_args.length > 1 && 1723af6ab5fSopenharmony_ci @es2panda_arg['type'].respond_to?('template_args') 1733af6ab5fSopenharmony_ci accessor = (@es2panda_arg['type']['ptr_depth'] || 0).zero? ? '.' : '->' 1743af6ab5fSopenharmony_ci clever_replacements += [['|accessor|', accessor]] 1753af6ab5fSopenharmony_ci 1763af6ab5fSopenharmony_ci @es2panda_arg['type']['template_args'].each_with_index do |template_arg_raw, i| 1773af6ab5fSopenharmony_ci template_arg = Arg.new({ 'name' => @es2panda_arg['name'] + "Element#{i + 1}", 1783af6ab5fSopenharmony_ci 'type' => template_arg_raw['type'] }) 1793af6ab5fSopenharmony_ci raise 'Unsupported double+ nested complex types: ' + @es2panda_arg.to_s if template_arg.lib_args.length > 1 1803af6ab5fSopenharmony_ci 1813af6ab5fSopenharmony_ci template_args += [template_arg] 1823af6ab5fSopenharmony_ci end 1833af6ab5fSopenharmony_ci 1843af6ab5fSopenharmony_ci found_change_type&.new_args&.map! do |arg| 1853af6ab5fSopenharmony_ci tmp = Arg.new(arg) 1863af6ab5fSopenharmony_ci raise 'Unsupported double+ nested complex types: ' + arg_info.to_s if tmp.lib_args.length > 1 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci tmp.lib_args[0]['increase_ptr_depth'] = arg['increase_ptr_depth'] if (arg['increase_ptr_depth'] || 0) != 0 1893af6ab5fSopenharmony_ci tmp.lib_args[0] 1903af6ab5fSopenharmony_ci end 1913af6ab5fSopenharmony_ci 1923af6ab5fSopenharmony_ci found_change_type&.return_args&.map! do |arg| 1933af6ab5fSopenharmony_ci tmp = Arg.new(arg) 1943af6ab5fSopenharmony_ci raise 'Unsupported double+ nested complex types: ' + arg_info if tmp.lib_args.length > 1 1953af6ab5fSopenharmony_ci 1963af6ab5fSopenharmony_ci tmp.lib_args[0]['increase_ptr_depth'] = arg['increase_ptr_depth'] if (arg['increase_ptr_depth'] || 0) != 0 1973af6ab5fSopenharmony_ci tmp.lib_args[0] 1983af6ab5fSopenharmony_ci end 1993af6ab5fSopenharmony_ci correct_depths(found_change_type) 2003af6ab5fSopenharmony_ci 2013af6ab5fSopenharmony_ci template_args.each_with_index do |template_arg, i| 2023af6ab5fSopenharmony_ci clever_replacements += [["|template_nested_expression_#{i + 1}|", 2033af6ab5fSopenharmony_ci template_arg.lib_cast['expression'] + "\n"]] 2043af6ab5fSopenharmony_ci clever_replacements += [["|reverse_template_nested_expression_#{i + 1}_start|", 2053af6ab5fSopenharmony_ci template_arg.lib_cast['reverse_cast']&.start&.gsub('?const?', '') || '']] 2063af6ab5fSopenharmony_ci clever_replacements += [["|reverse_template_nested_expression_#{i + 1}_end|", 2073af6ab5fSopenharmony_ci (template_arg.lib_cast['reverse_cast']&.end || '')]] 2083af6ab5fSopenharmony_ci found_change_type.new_args[i]['local_var_name'] = template_arg.lib_cast['var_name'] 2093af6ab5fSopenharmony_ci end 2103af6ab5fSopenharmony_ci 2113af6ab5fSopenharmony_ci @es2panda_arg['type']['ref_depth'] == 2 && 2123af6ab5fSopenharmony_ci found_change_type.cast['var_name'] = 'std::move(' + found_change_type.cast['var_name'] + ')' 2133af6ab5fSopenharmony_ci end 2143af6ab5fSopenharmony_ci 2153af6ab5fSopenharmony_ci clever_placeholders = find_placeholders(found_change_type) 2163af6ab5fSopenharmony_ci clever_replacements += clever_placeholders.map do |_path, placeholder| 2173af6ab5fSopenharmony_ci if placeholder.include?('.') 2183af6ab5fSopenharmony_ci value = get_placeholder_value(found_change_type, placeholder) 2193af6ab5fSopenharmony_ci [placeholder, value] 2203af6ab5fSopenharmony_ci else 2213af6ab5fSopenharmony_ci is_known_replacement = clever_replacements.any? do |sub_array| 2223af6ab5fSopenharmony_ci sub_array[0] =~ /_nested_expression_|\|accessor\|/ 2233af6ab5fSopenharmony_ci end 2243af6ab5fSopenharmony_ci raise 'Unknown placeholder: ' + placeholder + "\n" unless is_known_replacement 2253af6ab5fSopenharmony_ci end 2263af6ab5fSopenharmony_ci end 2273af6ab5fSopenharmony_ci 2283af6ab5fSopenharmony_ci found_change_type = deep_replace(found_change_type, clever_replacements) 2293af6ab5fSopenharmony_ci 2303af6ab5fSopenharmony_ci @lib_args = found_change_type&.new_args 2313af6ab5fSopenharmony_ci @lib_cast = found_change_type&.cast 2323af6ab5fSopenharmony_ci @return_args = found_change_type&.return_args || nil 2333af6ab5fSopenharmony_ci 2343af6ab5fSopenharmony_ci end 2353af6ab5fSopenharmony_ci 2363af6ab5fSopenharmony_ci if @lib_args.nil? 2373af6ab5fSopenharmony_ci @lib_args = [] 2383af6ab5fSopenharmony_ci @lib_args << @es2panda_arg 2393af6ab5fSopenharmony_ci end 2403af6ab5fSopenharmony_ci 2413af6ab5fSopenharmony_ci @lib_args.each do |arg| 2423af6ab5fSopenharmony_ci delete_ref(arg['type']) 2433af6ab5fSopenharmony_ci end 2443af6ab5fSopenharmony_ci 2453af6ab5fSopenharmony_ci if @lib_cast.nil? 2463af6ab5fSopenharmony_ci @lib_cast = {} 2473af6ab5fSopenharmony_ci @lib_cast['var_name'] = @es2panda_arg['name'] 2483af6ab5fSopenharmony_ci else 2493af6ab5fSopenharmony_ci @need_var_cast = true 2503af6ab5fSopenharmony_ci end 2513af6ab5fSopenharmony_ci end 2523af6ab5fSopenharmony_ci 2533af6ab5fSopenharmony_ci def find_placeholders(data, path = []) 2543af6ab5fSopenharmony_ci placeholders = [] 2553af6ab5fSopenharmony_ci if data.is_a?(OpenStruct) 2563af6ab5fSopenharmony_ci data.each_pair do |key, value| 2573af6ab5fSopenharmony_ci placeholders += find_placeholders(value, path + [key.to_s]) 2583af6ab5fSopenharmony_ci end 2593af6ab5fSopenharmony_ci elsif data.is_a?(Array) 2603af6ab5fSopenharmony_ci data.each_with_index do |value, index| 2613af6ab5fSopenharmony_ci placeholders += find_placeholders(value, path + [index]) 2623af6ab5fSopenharmony_ci end 2633af6ab5fSopenharmony_ci elsif data.is_a?(String) 2643af6ab5fSopenharmony_ci data.scan(/\|(.+?)\|/) do |match| 2653af6ab5fSopenharmony_ci placeholders << [path.join('.'), '|' + match[0] + '|'] 2663af6ab5fSopenharmony_ci end 2673af6ab5fSopenharmony_ci end 2683af6ab5fSopenharmony_ci placeholders 2693af6ab5fSopenharmony_ci end 2703af6ab5fSopenharmony_ci 2713af6ab5fSopenharmony_ci def get_value_by_path(data, path) 2723af6ab5fSopenharmony_ci path.split('.').reduce(data) do |current, key| 2733af6ab5fSopenharmony_ci current.is_a?(Array) ? current[key.to_i] : current[key] 2743af6ab5fSopenharmony_ci end 2753af6ab5fSopenharmony_ci end 2763af6ab5fSopenharmony_ci 2773af6ab5fSopenharmony_ci def get_placeholder_value(found_change_type, placeholder) 2783af6ab5fSopenharmony_ci path_to_value = placeholder.gsub('|', '').gsub('_int', '').gsub(' - 1', '') 2793af6ab5fSopenharmony_ci value = get_value_by_path(found_change_type, path_to_value) || 0 2803af6ab5fSopenharmony_ci if value.is_a?(Integer) 2813af6ab5fSopenharmony_ci if placeholder.end_with?('ptr_depth|') 2823af6ab5fSopenharmony_ci value = '*' * value 2833af6ab5fSopenharmony_ci elsif placeholder.end_with?('ref_depth|') 2843af6ab5fSopenharmony_ci value = '&' * value 2853af6ab5fSopenharmony_ci elsif placeholder.end_with?('ptr_depth_int|') 2863af6ab5fSopenharmony_ci value = value 2873af6ab5fSopenharmony_ci elsif placeholder.end_with?('ptr_depth - 1|') 2883af6ab5fSopenharmony_ci value = '*' * (value - 1) 2893af6ab5fSopenharmony_ci elsif placeholder.end_with?('namespace|') 2903af6ab5fSopenharmony_ci value = '' 2913af6ab5fSopenharmony_ci else 2923af6ab5fSopenharmony_ci raise 'Unknown integer found for placeholer: ' + placeholder + ', res: ' + value.to_s + "\n" 2933af6ab5fSopenharmony_ci end 2943af6ab5fSopenharmony_ci end 2953af6ab5fSopenharmony_ci value 2963af6ab5fSopenharmony_ci end 2973af6ab5fSopenharmony_ci 2983af6ab5fSopenharmony_ci # replacements = [[from1, to1], [from2, to2], ...] 2993af6ab5fSopenharmony_ci def deep_replace(data, replacements) 3003af6ab5fSopenharmony_ci if data.is_a?(OpenStruct) 3013af6ab5fSopenharmony_ci data.each_pair do |key, value| 3023af6ab5fSopenharmony_ci data[key] = deep_replace(value, replacements) 3033af6ab5fSopenharmony_ci end 3043af6ab5fSopenharmony_ci elsif data.is_a?(Array) 3053af6ab5fSopenharmony_ci data.map! { |value| deep_replace(value, replacements) } 3063af6ab5fSopenharmony_ci elsif data.is_a?(String) 3073af6ab5fSopenharmony_ci found_replacement = replacements.find { |first, _| first == data } 3083af6ab5fSopenharmony_ci if found_replacement 3093af6ab5fSopenharmony_ci data = if found_replacement[1].is_a?(String) 3103af6ab5fSopenharmony_ci found_replacement[1] 3113af6ab5fSopenharmony_ci else 3123af6ab5fSopenharmony_ci found_replacement[1].dup 3133af6ab5fSopenharmony_ci end 3143af6ab5fSopenharmony_ci else 3153af6ab5fSopenharmony_ci replacements.each { |from, to| data.gsub!(from, to) if to.is_a?(String) } 3163af6ab5fSopenharmony_ci end 3173af6ab5fSopenharmony_ci end 3183af6ab5fSopenharmony_ci data 3193af6ab5fSopenharmony_ci end 3203af6ab5fSopenharmony_ci 3213af6ab5fSopenharmony_ci def correct_depths(data) 3223af6ab5fSopenharmony_ci if data.is_a?(OpenStruct) 3233af6ab5fSopenharmony_ci if data.respond_to?(:increase_ptr_depth) 3243af6ab5fSopenharmony_ci ptr_depth = data.type.ptr_depth || 0 3253af6ab5fSopenharmony_ci ptr_depth += data.increase_ptr_depth.to_i 3263af6ab5fSopenharmony_ci data.type['ptr_depth'] = ptr_depth 3273af6ab5fSopenharmony_ci data.delete_field(:increase_ptr_depth) 3283af6ab5fSopenharmony_ci else 3293af6ab5fSopenharmony_ci data.each_pair do |key, value| 3303af6ab5fSopenharmony_ci data[key] = correct_depths(value) 3313af6ab5fSopenharmony_ci end 3323af6ab5fSopenharmony_ci end 3333af6ab5fSopenharmony_ci elsif data.is_a?(Array) 3343af6ab5fSopenharmony_ci data.map! { |value| correct_depths(value) } 3353af6ab5fSopenharmony_ci end 3363af6ab5fSopenharmony_ci data 3373af6ab5fSopenharmony_ci end 3383af6ab5fSopenharmony_ci 3393af6ab5fSopenharmony_ci attr_reader :es2panda_arg 3403af6ab5fSopenharmony_ci 3413af6ab5fSopenharmony_ci attr_reader :lib_args 3423af6ab5fSopenharmony_ci 3433af6ab5fSopenharmony_ci attr_reader :lib_cast 3443af6ab5fSopenharmony_ci 3453af6ab5fSopenharmony_ci attr_reader :return_args 3463af6ab5fSopenharmony_ci 3473af6ab5fSopenharmony_ci def lib_args_to_str 3483af6ab5fSopenharmony_ci @lib_args.map do |lib_arg| 3493af6ab5fSopenharmony_ci Arg.arg_to_str(lib_arg) 3503af6ab5fSopenharmony_ci end&.join(', ') 3513af6ab5fSopenharmony_ci end 3523af6ab5fSopenharmony_ci 3533af6ab5fSopenharmony_ci def self.arg_value(arg) 3543af6ab5fSopenharmony_ci ptr_depth = arg['type']['ptr_depth'] || 0 3553af6ab5fSopenharmony_ci '*' * ptr_depth + arg['name'] 3563af6ab5fSopenharmony_ci end 3573af6ab5fSopenharmony_ci 3583af6ab5fSopenharmony_ci def self.arg_to_str(arg) 3593af6ab5fSopenharmony_ci type_to_str(arg['type']) + arg['name'] 3603af6ab5fSopenharmony_ci end 3613af6ab5fSopenharmony_ci 3623af6ab5fSopenharmony_ci def self.type_to_str(type) 3633af6ab5fSopenharmony_ci res = type['name'] 3643af6ab5fSopenharmony_ci ptr_depth = type['ptr_depth'] || 0 3653af6ab5fSopenharmony_ci ref_depth = type['ref_depth'] || 0 3663af6ab5fSopenharmony_ci res + ' ' + '*' * ptr_depth + '&' * ref_depth 3673af6ab5fSopenharmony_ci end 3683af6ab5fSopenharmony_ci 3693af6ab5fSopenharmony_ci attr_reader :is_change_type 3703af6ab5fSopenharmony_ci 3713af6ab5fSopenharmony_ci def updater_allowed 3723af6ab5fSopenharmony_ci @is_ast_type || @is_ast_node || @is_ast_node_add_children || @is_var_type || @is_enum_type || 3733af6ab5fSopenharmony_ci @is_scope_type || @is_code_gen 3743af6ab5fSopenharmony_ci end 3753af6ab5fSopenharmony_ci end 3763af6ab5fSopenharmony_ci 3773af6ab5fSopenharmony_ci class Type 3783af6ab5fSopenharmony_ci @raw_type = nil 3793af6ab5fSopenharmony_ci @lib_type = nil 3803af6ab5fSopenharmony_ci @return_args = nil 3813af6ab5fSopenharmony_ci @cast = nil 3823af6ab5fSopenharmony_ci 3833af6ab5fSopenharmony_ci def initialize(type_info) 3843af6ab5fSopenharmony_ci @raw_type = type_info 3853af6ab5fSopenharmony_ci tmp_arg = Arg.new({ 'name' => 'returnType', 'type' => @raw_type }) 3863af6ab5fSopenharmony_ci 3873af6ab5fSopenharmony_ci @return_args = tmp_arg.return_args if tmp_arg.lib_args.length != 1 3883af6ab5fSopenharmony_ci @lib_type = tmp_arg.lib_args[0]['type'] 3893af6ab5fSopenharmony_ci @cast = tmp_arg.lib_cast 3903af6ab5fSopenharmony_ci end 3913af6ab5fSopenharmony_ci 3923af6ab5fSopenharmony_ci def lib_type_to_str 3933af6ab5fSopenharmony_ci Arg.type_to_str(@lib_type) 3943af6ab5fSopenharmony_ci end 3953af6ab5fSopenharmony_ci 3963af6ab5fSopenharmony_ci def arena_item_type 3973af6ab5fSopenharmony_ci type = Marshal.load(Marshal.dump(@lib_type)) 3983af6ab5fSopenharmony_ci type['ptr_depth'] -= 1 3993af6ab5fSopenharmony_ci tmp_arg = Arg.new({ 'name' => '', 'type' => type }) 4003af6ab5fSopenharmony_ci Arg.type_to_str(tmp_arg.lib_args[0]['type']) 4013af6ab5fSopenharmony_ci end 4023af6ab5fSopenharmony_ci 4033af6ab5fSopenharmony_ci def call_cast 4043af6ab5fSopenharmony_ci if @cast 4053af6ab5fSopenharmony_ci @cast['call_cast'] 4063af6ab5fSopenharmony_ci else 4073af6ab5fSopenharmony_ci '' 4083af6ab5fSopenharmony_ci end 4093af6ab5fSopenharmony_ci end 4103af6ab5fSopenharmony_ci 4113af6ab5fSopenharmony_ci def constructor_cast 4123af6ab5fSopenharmony_ci if @cast 4133af6ab5fSopenharmony_ci @cast['constructor_cast'] 4143af6ab5fSopenharmony_ci else 4153af6ab5fSopenharmony_ci '' 4163af6ab5fSopenharmony_ci end 4173af6ab5fSopenharmony_ci end 4183af6ab5fSopenharmony_ci 4193af6ab5fSopenharmony_ci def cast 4203af6ab5fSopenharmony_ci if @cast 4213af6ab5fSopenharmony_ci @cast['reverse_cast'] 4223af6ab5fSopenharmony_ci else 4233af6ab5fSopenharmony_ci '' 4243af6ab5fSopenharmony_ci end 4253af6ab5fSopenharmony_ci end 4263af6ab5fSopenharmony_ci 4273af6ab5fSopenharmony_ci def return_args_to_str 4283af6ab5fSopenharmony_ci res = '' 4293af6ab5fSopenharmony_ci @return_args&.map do |arg| 4303af6ab5fSopenharmony_ci res += ', ' + Arg.arg_to_str(arg) 4313af6ab5fSopenharmony_ci end 4323af6ab5fSopenharmony_ci res 4333af6ab5fSopenharmony_ci end 4343af6ab5fSopenharmony_ci 4353af6ab5fSopenharmony_ci attr_reader :raw_type 4363af6ab5fSopenharmony_ci attr_reader :lib_type 4373af6ab5fSopenharmony_ci end 4383af6ab5fSopenharmony_ci 4393af6ab5fSopenharmony_ci class ClassData < SimpleDelegator 4403af6ab5fSopenharmony_ci def class_name 4413af6ab5fSopenharmony_ci Es2pandaLibApi.classes.find { |_name, data| data == self }[0] 4423af6ab5fSopenharmony_ci end 4433af6ab5fSopenharmony_ci 4443af6ab5fSopenharmony_ci def call_cast 4453af6ab5fSopenharmony_ci name = class_name 4463af6ab5fSopenharmony_ci class_type = Type.new(OpenStruct.new({ 'name' => name, 'ptr_depth' => 1 })) 4473af6ab5fSopenharmony_ci class_type.call_cast 4483af6ab5fSopenharmony_ci end 4493af6ab5fSopenharmony_ci 4503af6ab5fSopenharmony_ci def constructor_type 4513af6ab5fSopenharmony_ci name = class_name 4523af6ab5fSopenharmony_ci Type.new(OpenStruct.new({ 'name' => name, 'ptr_depth' => 1 })) 4533af6ab5fSopenharmony_ci end 4543af6ab5fSopenharmony_ci 4553af6ab5fSopenharmony_ci def constructor_cast 4563af6ab5fSopenharmony_ci name = class_name 4573af6ab5fSopenharmony_ci class_type = Type.new(OpenStruct.new({ 'name' => name, 'ptr_depth' => 1 })) 4583af6ab5fSopenharmony_ci class_type.constructor_cast 4593af6ab5fSopenharmony_ci end 4603af6ab5fSopenharmony_ci 4613af6ab5fSopenharmony_ci def updater_allowed 4623af6ab5fSopenharmony_ci name = class_name 4633af6ab5fSopenharmony_ci class_arg = Arg.new(OpenStruct.new({ 'name' => 'empty', 4643af6ab5fSopenharmony_ci 'type' => OpenStruct.new({ 'name' => name, 'ptr_depth' => 1 }) })) 4653af6ab5fSopenharmony_ci class_arg.updater_allowed 4663af6ab5fSopenharmony_ci end 4673af6ab5fSopenharmony_ci 4683af6ab5fSopenharmony_ci def usings_map 4693af6ab5fSopenharmony_ci dig(:usings)&.map { |using| [using['name'], using['type']] }.to_h || {} 4703af6ab5fSopenharmony_ci end 4713af6ab5fSopenharmony_ci 4723af6ab5fSopenharmony_ci def replace_with_usings(type, usings) 4733af6ab5fSopenharmony_ci if usings[type&.name] 4743af6ab5fSopenharmony_ci new_type = usings[type.name] 4753af6ab5fSopenharmony_ci new_type['ref_depth'] = type['ref_depth'] || 0 4763af6ab5fSopenharmony_ci new_type['ptr_depth'] = type['ptr_depth'] || 0 4773af6ab5fSopenharmony_ci return new_type 4783af6ab5fSopenharmony_ci end 4793af6ab5fSopenharmony_ci type 4803af6ab5fSopenharmony_ci end 4813af6ab5fSopenharmony_ci 4823af6ab5fSopenharmony_ci def error_catch_log(mode, function, err) 4833af6ab5fSopenharmony_ci if mode == 'constructor' 4843af6ab5fSopenharmony_ci Es2pandaLibApi.log('error', "Error: '#{err.message}'\nConstructor: #{function.name}\nRaw:\n---\n"\ 4853af6ab5fSopenharmony_ci "#{function.raw_declaration}\n---\n\n") 4863af6ab5fSopenharmony_ci Es2pandaLibApi.log('backtrace', err.backtrace.join("\n"), "\n") 4873af6ab5fSopenharmony_ci Es2pandaLibApi.stat_add_unsupported_type(err.message) if err.message.include?('Unsupported type') 4883af6ab5fSopenharmony_ci Es2pandaLibApi.stat_add_constructor(0) 4893af6ab5fSopenharmony_ci Es2pandaLibApi.stat_add_class(0, function.name) 4903af6ab5fSopenharmony_ci elsif mode == 'method' 4913af6ab5fSopenharmony_ci Es2pandaLibApi.log('error', "Error: '#{err.message}'\nClass: #{function.name}\nRaw:\n---\n"\ 4923af6ab5fSopenharmony_ci "#{function.raw_declaration}\n---\n\n") 4933af6ab5fSopenharmony_ci Es2pandaLibApi.log('backtrace', err.backtrace.join("\n"), "\n\n") 4943af6ab5fSopenharmony_ci Es2pandaLibApi.stat_add_unsupported_type(err.message) if err.message.include?('Unsupported type') 4953af6ab5fSopenharmony_ci Es2pandaLibApi.stat_add_method(0) 4963af6ab5fSopenharmony_ci else 4973af6ab5fSopenharmony_ci raise 'Unreachable' 4983af6ab5fSopenharmony_ci end 4993af6ab5fSopenharmony_ci end 5003af6ab5fSopenharmony_ci 5013af6ab5fSopenharmony_ci def class_constructors 5023af6ab5fSopenharmony_ci res = [] 5033af6ab5fSopenharmony_ci usings = usings_map 5043af6ab5fSopenharmony_ci dig(:constructors)&.each do |constructor| 5053af6ab5fSopenharmony_ci if check_no_gen_constructor(constructor) 5063af6ab5fSopenharmony_ci args = [] 5073af6ab5fSopenharmony_ci begin 5083af6ab5fSopenharmony_ci constructor_cast 5093af6ab5fSopenharmony_ci constructor.args&.each do |arg| 5103af6ab5fSopenharmony_ci arg['type'] = replace_with_usings(arg['type'], usings) 5113af6ab5fSopenharmony_ci arg['type']['current_class'] = constructor.name 5123af6ab5fSopenharmony_ci args << Arg.new(arg) 5133af6ab5fSopenharmony_ci end 5143af6ab5fSopenharmony_ci rescue StandardError => e 5153af6ab5fSopenharmony_ci error_catch_log('constructor', constructor, e) 5163af6ab5fSopenharmony_ci else 5173af6ab5fSopenharmony_ci Es2pandaLibApi.stat_add_constructor(1) 5183af6ab5fSopenharmony_ci Es2pandaLibApi.stat_add_class(1, class_name) 5193af6ab5fSopenharmony_ci 5203af6ab5fSopenharmony_ci Es2pandaLibApi.log('info', "Supported constructor for class '#{class_name}'\n") 5213af6ab5fSopenharmony_ci 5223af6ab5fSopenharmony_ci res << { 'args' => args, 'raw_decl' => constructor.raw_declaration } 5233af6ab5fSopenharmony_ci end 5243af6ab5fSopenharmony_ci else 5253af6ab5fSopenharmony_ci Es2pandaLibApi.log('info', "Banned constructor for class '#{class_name}'\n") 5263af6ab5fSopenharmony_ci end 5273af6ab5fSopenharmony_ci end 5283af6ab5fSopenharmony_ci res 5293af6ab5fSopenharmony_ci end 5303af6ab5fSopenharmony_ci 5313af6ab5fSopenharmony_ci def check_no_gen_constructor(constructor) 5323af6ab5fSopenharmony_ci res = false 5333af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_constructor_info['postfix_contains']&.each do |postfix| 5343af6ab5fSopenharmony_ci res ||= constructor.postfix&.include?(postfix) 5353af6ab5fSopenharmony_ci end 5363af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_constructor_info['name_starts_with']&.each do |name_starts_with| 5373af6ab5fSopenharmony_ci res ||= constructor.name&.start_with?(name_starts_with) 5383af6ab5fSopenharmony_ci end 5393af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_constructor_info['arg_type']&.each do |arg_type| 5403af6ab5fSopenharmony_ci constructor.args&.each do |arg| 5413af6ab5fSopenharmony_ci res ||= Es2pandaLibApi.check_fit(arg.type, arg_type) 5423af6ab5fSopenharmony_ci end 5433af6ab5fSopenharmony_ci end 5443af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_constructor_info['call_class']&.each do |call_class| 5453af6ab5fSopenharmony_ci res ||= (call_class['name'] == class_name) 5463af6ab5fSopenharmony_ci end 5473af6ab5fSopenharmony_ci !res 5483af6ab5fSopenharmony_ci end 5493af6ab5fSopenharmony_ci 5503af6ab5fSopenharmony_ci def check_no_gen_method(method) 5513af6ab5fSopenharmony_ci res = false # = Will be generated 5523af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_method_info['postfix_contains']&.each do |postfix| 5533af6ab5fSopenharmony_ci res ||= method.postfix&.include?(postfix) 5543af6ab5fSopenharmony_ci end 5553af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_method_info['name_starts_with']&.each do |name_starts_with| 5563af6ab5fSopenharmony_ci res ||= method.name&.start_with?(name_starts_with) 5573af6ab5fSopenharmony_ci end 5583af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_method_info['arg_type']&.each do |arg_type| 5593af6ab5fSopenharmony_ci method.args&.each do |arg| 5603af6ab5fSopenharmony_ci res ||= Es2pandaLibApi.check_fit(arg.type, arg_type) 5613af6ab5fSopenharmony_ci end 5623af6ab5fSopenharmony_ci end 5633af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_method_info['return_type']&.each do |return_type| 5643af6ab5fSopenharmony_ci res ||= begin 5653af6ab5fSopenharmony_ci method.return_type['name'] == return_type['name'] && (!return_type.respond_to?('namespace') || 5663af6ab5fSopenharmony_ci return_type['namespace'] == method.return_type['namespace']) 5673af6ab5fSopenharmony_ci end 5683af6ab5fSopenharmony_ci end 5693af6ab5fSopenharmony_ci Es2pandaLibApi.no_gen_method_info['call_class']&.each do |call_class| 5703af6ab5fSopenharmony_ci res ||= (call_class['name'] == class_name) 5713af6ab5fSopenharmony_ci end 5723af6ab5fSopenharmony_ci !res 5733af6ab5fSopenharmony_ci end 5743af6ab5fSopenharmony_ci 5753af6ab5fSopenharmony_ci def get_return_expr(return_type, call_cast, const, method, args) 5763af6ab5fSopenharmony_ci return_expr = '' 5773af6ab5fSopenharmony_ci 5783af6ab5fSopenharmony_ci if return_type.raw_type['name'] != 'void' && return_type.raw_type['name'] != 'ArenaVector' && 5793af6ab5fSopenharmony_ci return_type.raw_type['name'] != 'ArenaSet' && return_type.raw_type['name'] != 'pair' && 5803af6ab5fSopenharmony_ci return_type.raw_type['name'] != 'vector' 5813af6ab5fSopenharmony_ci return_expr += 'auto res = ' 5823af6ab5fSopenharmony_ci end 5833af6ab5fSopenharmony_ci 5843af6ab5fSopenharmony_ci return_expr += return_type.cast['start']&.gsub('?const?', const) if return_type.cast 5853af6ab5fSopenharmony_ci 5863af6ab5fSopenharmony_ci return_expr += '(' + call_cast['start']&.gsub('?const?', const) + method['name'] + '(' 5873af6ab5fSopenharmony_ci return_expr += args&.map do |arg| 5883af6ab5fSopenharmony_ci arg.lib_cast['var_name'] if arg.lib_cast 5893af6ab5fSopenharmony_ci end&.join(', ') 5903af6ab5fSopenharmony_ci return_expr += ')' + (call_cast['end']&.gsub('?const?', const) || '') + ')' 5913af6ab5fSopenharmony_ci 5923af6ab5fSopenharmony_ci return_expr += return_type.cast['end'] || '' if return_type.cast 5933af6ab5fSopenharmony_ci 5943af6ab5fSopenharmony_ci return_expr += if return_type.raw_type['name'] == 'void' 5953af6ab5fSopenharmony_ci ';' 5963af6ab5fSopenharmony_ci elsif const == '' 5973af6ab5fSopenharmony_ci ";\n\treturn res;" 5983af6ab5fSopenharmony_ci else 5993af6ab5fSopenharmony_ci ";\n\treturn const_cast<const " + return_type.lib_type_to_str + '>(res);' 6003af6ab5fSopenharmony_ci end 6013af6ab5fSopenharmony_ci return_expr 6023af6ab5fSopenharmony_ci end 6033af6ab5fSopenharmony_ci 6043af6ab5fSopenharmony_ci def get_new_method_name(function_overload, name, const) 6053af6ab5fSopenharmony_ci function_name = name + (const != '' ? 'Const' : '') 6063af6ab5fSopenharmony_ci overload_name = function_name 6073af6ab5fSopenharmony_ci 6083af6ab5fSopenharmony_ci if function_overload.include?(function_name) 6093af6ab5fSopenharmony_ci overload_name += function_overload[function_name].to_s 6103af6ab5fSopenharmony_ci function_overload[function_name] += 1 6113af6ab5fSopenharmony_ci else 6123af6ab5fSopenharmony_ci function_overload[function_name] = 1 6133af6ab5fSopenharmony_ci end 6143af6ab5fSopenharmony_ci overload_name 6153af6ab5fSopenharmony_ci end 6163af6ab5fSopenharmony_ci 6173af6ab5fSopenharmony_ci def get_const_modifier(return_type) 6183af6ab5fSopenharmony_ci if return_type&.raw_type&.prefix&.include?('const') && return_type&.lib_type&.respond_to?('ptr_depth') && 6193af6ab5fSopenharmony_ci return_type&.lib_type&.ptr_depth&.positive? 6203af6ab5fSopenharmony_ci 'const' 6213af6ab5fSopenharmony_ci else 6223af6ab5fSopenharmony_ci '' 6233af6ab5fSopenharmony_ci end 6243af6ab5fSopenharmony_ci end 6253af6ab5fSopenharmony_ci 6263af6ab5fSopenharmony_ci def class_methods 6273af6ab5fSopenharmony_ci res = [] 6283af6ab5fSopenharmony_ci function_overload = {} 6293af6ab5fSopenharmony_ci usings = usings_map 6303af6ab5fSopenharmony_ci dig(:methods)&.each do |method| 6313af6ab5fSopenharmony_ci if check_no_gen_method(method) 6323af6ab5fSopenharmony_ci begin 6333af6ab5fSopenharmony_ci return_type = Type.new(replace_with_usings(method.return_type, usings)) 6343af6ab5fSopenharmony_ci const = get_const_modifier(return_type) 6353af6ab5fSopenharmony_ci 6363af6ab5fSopenharmony_ci args = [] 6373af6ab5fSopenharmony_ci method.args&.each do |arg| 6383af6ab5fSopenharmony_ci arg['type'] = replace_with_usings(arg['type'], usings) 6393af6ab5fSopenharmony_ci args << Arg.new(arg) 6403af6ab5fSopenharmony_ci end 6413af6ab5fSopenharmony_ci 6423af6ab5fSopenharmony_ci return_expr = get_return_expr(return_type, call_cast, const, method, args) 6433af6ab5fSopenharmony_ci rescue StandardError => e 6443af6ab5fSopenharmony_ci error_catch_log('method', method, e) 6453af6ab5fSopenharmony_ci else 6463af6ab5fSopenharmony_ci Es2pandaLibApi.stat_add_method(1) 6473af6ab5fSopenharmony_ci Es2pandaLibApi.log('info', 'supported method: ', method.name, ' class: ', class_name, "\n") 6483af6ab5fSopenharmony_ci 6493af6ab5fSopenharmony_ci res << { 'name' => method.name, 'const' => const, 'return_arg_to_str' => return_type.return_args_to_str, 6503af6ab5fSopenharmony_ci 'overload_name' => get_new_method_name(function_overload, method.name, const), 'args' => args, 6513af6ab5fSopenharmony_ci 'return_type' => return_type, 'return_expr' => return_expr, 'raw_decl' => method.raw_declaration } 6523af6ab5fSopenharmony_ci end 6533af6ab5fSopenharmony_ci else 6543af6ab5fSopenharmony_ci Es2pandaLibApi.log('info', "Banned method\n") 6553af6ab5fSopenharmony_ci end 6563af6ab5fSopenharmony_ci end 6573af6ab5fSopenharmony_ci res 6583af6ab5fSopenharmony_ci end 6593af6ab5fSopenharmony_ci end 6603af6ab5fSopenharmony_ci 6613af6ab5fSopenharmony_ci @ast_nodes = Set.new(%w[AstNode Expression Statement TypeNode]) 6623af6ab5fSopenharmony_ci @ast_types = Set.new(['Type']) 6633af6ab5fSopenharmony_ci @scopes = Set.new(['Scope']) 6643af6ab5fSopenharmony_ci @classes = {} 6653af6ab5fSopenharmony_ci @includes = Set.new 6663af6ab5fSopenharmony_ci @change_types = [] 6673af6ab5fSopenharmony_ci @enums = Set.new(['AstNodeType']) 6683af6ab5fSopenharmony_ci 6693af6ab5fSopenharmony_ci @all_methods = 0.0 6703af6ab5fSopenharmony_ci @all_constructors = 0.0 6713af6ab5fSopenharmony_ci @all_classes = Set.new 6723af6ab5fSopenharmony_ci @classes_with_supported_constructor = Set.new 6733af6ab5fSopenharmony_ci @unsupported_types = {} 6743af6ab5fSopenharmony_ci 6753af6ab5fSopenharmony_ci @supported_methods = 0.0 6763af6ab5fSopenharmony_ci @supported_constructors = 0.0 6773af6ab5fSopenharmony_ci 6783af6ab5fSopenharmony_ci def log(debug_level, *args) 6793af6ab5fSopenharmony_ci info_log = false 6803af6ab5fSopenharmony_ci debug_log = false 6813af6ab5fSopenharmony_ci error_log = true 6823af6ab5fSopenharmony_ci backtrace_log = true 6833af6ab5fSopenharmony_ci stat_log = true 6843af6ab5fSopenharmony_ci 6853af6ab5fSopenharmony_ci if debug_level == 'info' && info_log 6863af6ab5fSopenharmony_ci print args.join('').to_s 6873af6ab5fSopenharmony_ci elsif debug_level == 'debug' && debug_log 6883af6ab5fSopenharmony_ci print args.join('').to_s 6893af6ab5fSopenharmony_ci elsif debug_level == 'error' && error_log 6903af6ab5fSopenharmony_ci print args.join('').to_s 6913af6ab5fSopenharmony_ci elsif debug_level == 'backtrace' && backtrace_log 6923af6ab5fSopenharmony_ci print args.join('').to_s 6933af6ab5fSopenharmony_ci elsif debug_level == 'stat' && stat_log 6943af6ab5fSopenharmony_ci print args.join('').to_s 6953af6ab5fSopenharmony_ci end 6963af6ab5fSopenharmony_ci end 6973af6ab5fSopenharmony_ci 6983af6ab5fSopenharmony_ci def no_gen_constructor_info 6993af6ab5fSopenharmony_ci { 'name_starts_with' => 7003af6ab5fSopenharmony_ci %w[AstNode ClassElement TypedStatement Annotated Scope Type], 7013af6ab5fSopenharmony_ci 'postfix_contains' => 7023af6ab5fSopenharmony_ci ['= delete', 'override'], 7033af6ab5fSopenharmony_ci 'arg_type' => 7043af6ab5fSopenharmony_ci [{ 'name' => 'Tag' }, 7053af6ab5fSopenharmony_ci { 'name' => 'Number', 'namespace' => 'lexer' }, 7063af6ab5fSopenharmony_ci { 'name' => 'Property', 'namespace' => 'AstDumper' }, 7073af6ab5fSopenharmony_ci { 'name' => 'TSChecker', 'namespace' => 'checker' }, 7083af6ab5fSopenharmony_ci { 'name' => 'ArenaVector', 'template_args' => [{ 'type' => { 'name' => 'pair' } }] }, 7093af6ab5fSopenharmony_ci { 'name' => 'initializer_list' }], 7103af6ab5fSopenharmony_ci 'call_class' => 7113af6ab5fSopenharmony_ci [{ 'name' => 'AstNode' }, { 'name' => 'ClassElement' }, { 'name' => 'TypedStatement' }, { 'name' => 'Annotated' }, 7123af6ab5fSopenharmony_ci { 'name' => 'Scope' }, { 'name' => 'Type' }] } 7133af6ab5fSopenharmony_ci end 7143af6ab5fSopenharmony_ci 7153af6ab5fSopenharmony_ci def no_gen_method_info 7163af6ab5fSopenharmony_ci { 'name_starts_with' => 7173af6ab5fSopenharmony_ci ['~', 'HasFloatingPoint', 'AddChildLambda', 'operator=', 'NumericConditionalCheck', 'CompileComputed'], 7183af6ab5fSopenharmony_ci 'postfix_contains' => 7193af6ab5fSopenharmony_ci ['= delete', 'override'], 7203af6ab5fSopenharmony_ci 'return_type' => 7213af6ab5fSopenharmony_ci [{ 'name' => 'ETSChecker' }, { 'name' => 'ArenaAllocator' }, 7223af6ab5fSopenharmony_ci { 'name' => 'Allocator' }, { 'name' => 'Program' }, { 'name' => 'Tag' }, 7233af6ab5fSopenharmony_ci { 'name' => 'Number', 'namespace' => 'lexer' }, { 'name' => 'Property', 'namespace' => 'AstDumper' }, 7243af6ab5fSopenharmony_ci { 'name' => 'TSChecker', 'namespace' => 'checker' }], 7253af6ab5fSopenharmony_ci 'arg_type' => 7263af6ab5fSopenharmony_ci [{ 'name' => 'Tag' }, { 'name' => 'Number', 'namespace' => 'lexer' }, 7273af6ab5fSopenharmony_ci { 'name' => 'Property', 'namespace' => 'AstDumper' }, { 'name' => 'TSChecker', 'namespace' => 'checker' }, 7283af6ab5fSopenharmony_ci { 'name' => 'ArenaVector', 'template_args' => [{ 'type' => { 'name' => 'pair' } }] }, 7293af6ab5fSopenharmony_ci { 'name' => 'initializer_list' }], 7303af6ab5fSopenharmony_ci 'call_class' => 7313af6ab5fSopenharmony_ci [{ 'name' => 'Annotated' }] } 7323af6ab5fSopenharmony_ci end 7333af6ab5fSopenharmony_ci 7343af6ab5fSopenharmony_ci def check_fit(data, pattern) 7353af6ab5fSopenharmony_ci return true if data.nil? || pattern.nil? 7363af6ab5fSopenharmony_ci 7373af6ab5fSopenharmony_ci if pattern.is_a?(OpenStruct) || pattern.is_a?(Hash) 7383af6ab5fSopenharmony_ci pattern.each_pair do |key, value| 7393af6ab5fSopenharmony_ci return false unless check_fit(data[key], value) 7403af6ab5fSopenharmony_ci end 7413af6ab5fSopenharmony_ci elsif pattern.is_a?(Array) 7423af6ab5fSopenharmony_ci pattern.each_with_index do |value, i| 7433af6ab5fSopenharmony_ci return false unless check_fit(data[i], value) 7443af6ab5fSopenharmony_ci end 7453af6ab5fSopenharmony_ci elsif pattern.is_a?(String) || pattern.is_a?(Integer) 7463af6ab5fSopenharmony_ci return false if data != pattern 7473af6ab5fSopenharmony_ci end 7483af6ab5fSopenharmony_ci 7493af6ab5fSopenharmony_ci true 7503af6ab5fSopenharmony_ci end 7513af6ab5fSopenharmony_ci 7523af6ab5fSopenharmony_ci def stat_add_method(support) 7533af6ab5fSopenharmony_ci @all_methods += 1 7543af6ab5fSopenharmony_ci @supported_methods += support 7553af6ab5fSopenharmony_ci end 7563af6ab5fSopenharmony_ci 7573af6ab5fSopenharmony_ci def stat_add_constructor(support) 7583af6ab5fSopenharmony_ci @all_constructors += 1 7593af6ab5fSopenharmony_ci @supported_constructors += support 7603af6ab5fSopenharmony_ci end 7613af6ab5fSopenharmony_ci 7623af6ab5fSopenharmony_ci def stat_add_class(support, class_name) 7633af6ab5fSopenharmony_ci @all_classes << class_name 7643af6ab5fSopenharmony_ci @classes_with_supported_constructor << class_name if support != 0 7653af6ab5fSopenharmony_ci end 7663af6ab5fSopenharmony_ci 7673af6ab5fSopenharmony_ci def stat_add_unsupported_type(err_msg) 7683af6ab5fSopenharmony_ci @unsupported_types[err_msg] ||= 0 7693af6ab5fSopenharmony_ci @unsupported_types[err_msg] += 1 7703af6ab5fSopenharmony_ci end 7713af6ab5fSopenharmony_ci 7723af6ab5fSopenharmony_ci def print_stats 7733af6ab5fSopenharmony_ci Es2pandaLibApi.log('stat', "--------------\n") 7743af6ab5fSopenharmony_ci Es2pandaLibApi.log('stat', 'Supported methods: ', @supported_methods, ' / ', @all_methods, ' ( ', 7753af6ab5fSopenharmony_ci @supported_methods / @all_methods * 100, " % )\n") 7763af6ab5fSopenharmony_ci Es2pandaLibApi.log('stat', 'Supported constructors: ', @supported_constructors, ' / ', @all_constructors, ' ( ', 7773af6ab5fSopenharmony_ci @supported_constructors / @all_constructors * 100, " % )\n") 7783af6ab5fSopenharmony_ci Es2pandaLibApi.log('stat', "Classes with supported constructor: #{@classes_with_supported_constructor.size} / "\ 7793af6ab5fSopenharmony_ci "#{@all_classes.size} ( #{@classes_with_supported_constructor.size.to_f / @all_classes.size * 100} % )\n") 7803af6ab5fSopenharmony_ci Es2pandaLibApi.log('stat', "--------------\n") 7813af6ab5fSopenharmony_ci 7823af6ab5fSopenharmony_ci return if @unsupported_types.empty? 7833af6ab5fSopenharmony_ci 7843af6ab5fSopenharmony_ci Es2pandaLibApi.log('stat', "Unsupported types for constructor: \n") 7853af6ab5fSopenharmony_ci sorted_items = @unsupported_types.sort_by { |_key, value| -value } 7863af6ab5fSopenharmony_ci sorted_items.each do |key, value| 7873af6ab5fSopenharmony_ci Es2pandaLibApi.log('stat', "#{key}: #{value}\n") 7883af6ab5fSopenharmony_ci end 7893af6ab5fSopenharmony_ci end 7903af6ab5fSopenharmony_ci 7913af6ab5fSopenharmony_ci def ast_nodes 7923af6ab5fSopenharmony_ci @ast_nodes 7933af6ab5fSopenharmony_ci end 7943af6ab5fSopenharmony_ci 7953af6ab5fSopenharmony_ci def ast_types 7963af6ab5fSopenharmony_ci @ast_types 7973af6ab5fSopenharmony_ci end 7983af6ab5fSopenharmony_ci 7993af6ab5fSopenharmony_ci def scopes 8003af6ab5fSopenharmony_ci @scopes 8013af6ab5fSopenharmony_ci end 8023af6ab5fSopenharmony_ci 8033af6ab5fSopenharmony_ci def ast_variables 8043af6ab5fSopenharmony_ci [%w[NO Variable], 8053af6ab5fSopenharmony_ci %w[LOCAL LocalVariable], 8063af6ab5fSopenharmony_ci %w[GLOBAL GlobalVariable], 8073af6ab5fSopenharmony_ci %w[MODULE ModuleVariable], 8083af6ab5fSopenharmony_ci %w[ENUM EnumVariable]] 8093af6ab5fSopenharmony_ci end 8103af6ab5fSopenharmony_ci 8113af6ab5fSopenharmony_ci def ast_node_additional_children 8123af6ab5fSopenharmony_ci %w[ 8133af6ab5fSopenharmony_ci TypedStatement 8143af6ab5fSopenharmony_ci ClassElement 8153af6ab5fSopenharmony_ci AnnotatedExpression 8163af6ab5fSopenharmony_ci Literal 8173af6ab5fSopenharmony_ci LoopStatement 8183af6ab5fSopenharmony_ci MaybeOptionalExpression 8193af6ab5fSopenharmony_ci Property 8203af6ab5fSopenharmony_ci ] 8213af6ab5fSopenharmony_ci end 8223af6ab5fSopenharmony_ci 8233af6ab5fSopenharmony_ci def code_gen_children 8243af6ab5fSopenharmony_ci %w[ 8253af6ab5fSopenharmony_ci CodeGen 8263af6ab5fSopenharmony_ci PandaGen 8273af6ab5fSopenharmony_ci ETSGen 8283af6ab5fSopenharmony_ci ] 8293af6ab5fSopenharmony_ci end 8303af6ab5fSopenharmony_ci 8313af6ab5fSopenharmony_ci def classes 8323af6ab5fSopenharmony_ci @classes 8333af6ab5fSopenharmony_ci end 8343af6ab5fSopenharmony_ci 8353af6ab5fSopenharmony_ci def includes 8363af6ab5fSopenharmony_ci @includes 8373af6ab5fSopenharmony_ci end 8383af6ab5fSopenharmony_ci 8393af6ab5fSopenharmony_ci def change_types 8403af6ab5fSopenharmony_ci @change_types 8413af6ab5fSopenharmony_ci end 8423af6ab5fSopenharmony_ci 8433af6ab5fSopenharmony_ci def enums 8443af6ab5fSopenharmony_ci @enums 8453af6ab5fSopenharmony_ci end 8463af6ab5fSopenharmony_ci 8473af6ab5fSopenharmony_ci def wrap_data(data) 8483af6ab5fSopenharmony_ci return unless data 8493af6ab5fSopenharmony_ci 8503af6ab5fSopenharmony_ci data.macros&.each do |macros| 8513af6ab5fSopenharmony_ci case macros.name 8523af6ab5fSopenharmony_ci when 'AST_NODE_MAPPING' 8533af6ab5fSopenharmony_ci @ast_nodes.merge(Set.new(macros.values&.map { |x| x[1] })) 8543af6ab5fSopenharmony_ci when 'AST_NODE_REINTERPRET_MAPPING' 8553af6ab5fSopenharmony_ci @ast_nodes.merge(Set.new(macros.values&.map { |x| x[2..3] }&.flatten)) 8563af6ab5fSopenharmony_ci when 'TYPE_MAPPING' 8573af6ab5fSopenharmony_ci @ast_types.merge(Set.new(macros.values&.map { |x| x[1] }&.flatten)) 8583af6ab5fSopenharmony_ci end 8593af6ab5fSopenharmony_ci end 8603af6ab5fSopenharmony_ci 8613af6ab5fSopenharmony_ci data.varbinder&.macros&.each do |macros| 8623af6ab5fSopenharmony_ci case macros.name 8633af6ab5fSopenharmony_ci when 'SCOPE_TYPES' 8643af6ab5fSopenharmony_ci @scopes.merge(Set.new(macros.values&.map { |x| x[1] })) 8653af6ab5fSopenharmony_ci end 8663af6ab5fSopenharmony_ci end 8673af6ab5fSopenharmony_ci 8683af6ab5fSopenharmony_ci data.ast_node_reinterpret_mapping&.each do |mapping| 8693af6ab5fSopenharmony_ci @ast_nodes << mapping[2] 8703af6ab5fSopenharmony_ci @ast_nodes << mapping[3] 8713af6ab5fSopenharmony_ci end 8723af6ab5fSopenharmony_ci 8733af6ab5fSopenharmony_ci data.paths&.each do |include| 8743af6ab5fSopenharmony_ci @includes << include 8753af6ab5fSopenharmony_ci end 8763af6ab5fSopenharmony_ci 8773af6ab5fSopenharmony_ci data.change_types&.each do |change_type| 8783af6ab5fSopenharmony_ci @change_types << change_type 8793af6ab5fSopenharmony_ci end 8803af6ab5fSopenharmony_ci 8813af6ab5fSopenharmony_ci data['ir']&.class_definitions&.each do |class_definition| 8823af6ab5fSopenharmony_ci @classes[class_definition.name] = ClassData.new(class_definition&.public) 8833af6ab5fSopenharmony_ci end 8843af6ab5fSopenharmony_ci 8853af6ab5fSopenharmony_ci data.enums&.each do |enum| 8863af6ab5fSopenharmony_ci @enums << enum.name 8873af6ab5fSopenharmony_ci end 8883af6ab5fSopenharmony_ci 8893af6ab5fSopenharmony_ci Enums.wrap_data(data) 8903af6ab5fSopenharmony_ci end 8913af6ab5fSopenharmony_ci 8923af6ab5fSopenharmony_ci module_function :wrap_data, :classes, :ast_nodes, :includes, :change_types, :enums, :ast_types, 8933af6ab5fSopenharmony_ci :stat_add_constructor, :stat_add_method, :print_stats, :no_gen_method_info, :no_gen_constructor_info, 8943af6ab5fSopenharmony_ci :stat_add_class, :stat_add_unsupported_type, :ast_node_additional_children, :scopes, :ast_variables, 8953af6ab5fSopenharmony_ci :code_gen_children, :check_fit, :log 8963af6ab5fSopenharmony_ciend 8973af6ab5fSopenharmony_ci 8983af6ab5fSopenharmony_cidef Gen.on_require(data) 8993af6ab5fSopenharmony_ci Es2pandaLibApi.wrap_data(data) 9003af6ab5fSopenharmony_ciend 901