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