# frozen_string_literal: true require 'opal/nodes/base' require 'opal/nodes/args/arg' require 'opal/nodes/args/arity_check' require 'opal/nodes/args/ensure_kwargs_are_kwargs' require 'opal/nodes/args/extract_block_arg' require 'opal/nodes/args/extract_kwarg' require 'opal/nodes/args/extract_kwargs' require 'opal/nodes/args/extract_kwoptarg' require 'opal/nodes/args/extract_kwrestarg' require 'opal/nodes/args/extract_optarg' require 'opal/nodes/args/extract_post_arg' require 'opal/nodes/args/extract_post_optarg' require 'opal/nodes/args/extract_restarg' require 'opal/nodes/args/fake_arg' require 'opal/nodes/args/initialize_iterarg' require 'opal/nodes/args/initialize_shadowarg' require 'opal/nodes/args/parameters' require 'opal/nodes/args/prepare_post_args' module Opal module Nodes class ArgsNode < Base handle :args # ruby allows for args with the same name, if the arg starts with a '_', like: # def funny_method_name(_, _) # puts _ # end # but javascript in strict mode does not allow for args with the same name # ruby assigns the value of the first arg given # funny_method_name(1, 2) => 1 # 1. check for args starting with '_' and check if they appear multiple times # 2. leave the first appearance as it is and rename the other ones # compiler result: # function $$funny_method_name(_, __$2) def compile same_arg_counter = {} children.each_with_index do |arg, idx| if multiple_underscore?(arg) same_arg_counter[arg] ||= 0 same_arg_counter[arg] += 1 if same_arg_counter[arg] > 1 arg = s(arg.type, :"#{arg.children[0]}_$#{same_arg_counter[arg]}") end end push ', ' if idx != 0 push process(arg) end end def multiple_underscore?(arg) arg.type == :arg && arg.children.count == 1 && arg.children.first.to_s.start_with?('_') && children.count(arg) > 1 end end end end