# frozen_string_literal: truerequire'opal/rewriters/base'require'opal/rewriters/arguments'moduleOpalmoduleRewriters# Converts## def m( a, b = 1, *c, d, e:, f: 1, **g, &blk )# end## To something like## def m( a, <fake b>, <fake c>, <fake d>, <fake kwargs>)# blk = <extract block># $post_args = arguments[1..-1]# $kwargs = $post_args.pop# a = <enough args> ? $post_args.shift : 1# c = <enough args> ? $post_args[0..-1] : []# d = $post_args.last# e = $kwargs.delete(:e)# f = $kwargs.delete(:f) || 1# g = $kwargs.except(:e, :f)# end#classInlineArgs<Basedefon_def(node)node=super(node)mid,args,body=*nodebody||=s(:nil)# prevent returning initialization statementinitializer=Initializer.new(args,type: :def)inline_args=args.updated(nil,initializer.inline)body=prepend_to_body(body,initializer.initialization)node.updated(nil,[mid,inline_args,body])enddefon_defs(node)node=super(node)recv,mid,args,body=*nodebody||=s(:nil)# prevent returning initialization statementinitializer=Initializer.new(args,type: :defs)inline_args=args.updated(nil,initializer.inline)body=prepend_to_body(body,initializer.initialization)node.updated(nil,[recv,mid,inline_args,body])enddefon_iter(node)node=super(node)args,body=*nodebody||=s(:nil)# prevent returning initialization statementinitializer=Initializer.new(args,type: :iter)inline_args=args.updated(nil,initializer.inline)body=prepend_to_body(body,initializer.initialization)node.updated(nil,[inline_args,body])endclassInitializer<::Opal::Rewriters::Baseattr_reader:inline,:initializationSTEPS=%i[
extract_blockarg
initialize_shadowargs
extract_args
prepare_post_args
prepare_kwargs
extract_optargs
extract_restarg
extract_post_args
extract_kwargs
extract_kwoptargs
extract_kwrestarg
].freezedefinitialize(args,type:)@args=Arguments.new(args.children)@inline=[]@initialization=[]@type=type@underscore_found=falseSTEPS.eachdo|step|send(step)endif@initialization.any?@initialization=s(:begin,*@initialization)else@initialization=nilendenddefextract_blockargif(arg=@args.blockarg)@initialization<<arg.updated(:extract_blockarg)endenddefinitialize_shadowargs@args.shadowargs.eachdo|arg|@initialization<<arg.updated(:initialize_shadowarg)endenddefextract_args@args.args.eachdo|arg|if@type==:iter# block args are not required,# so we neeed to tell compiler that required args# must be initialized with nil-s@initialization<<arg.updated(:initialize_iter_arg)ifarg.children[0]==:_if@underscore_found# for proc { |_, _| _ }.call(1, 2) result must be 1# here we convert all underscore args starting from the 2nd# to a "fake" argarg=s(:fake_arg)end@underscore_found=trueendelse# required inline def argument like 'def m(req)'# no initialization is requiredend@inline<<argendenddefprepare_post_argsif@args.has_post_args?@initialization<<s(:prepare_post_args,@args.args.length)endenddefprepare_kwargsreturnunless@args.has_any_kwargs?if@args.can_inline_kwargs?@inline<<s(:arg,:'$kwargs')else@initialization<<s(:extract_kwargs)@inline<<s(:fake_arg)end@initialization<<s(:ensure_kwargs_are_kwargs)enddefextract_kwargs@args.kwargs.eachdo|arg|@initialization<<arg.updated(:extract_kwarg)endenddefextract_kwoptargs@args.kwoptargs.eachdo|arg|@initialization<<arg.updated(:extract_kwoptarg)endenddefextract_kwrestargif(arg=@args.kwrestarg)@initialization<<arg.updated(:extract_kwrestarg)endenddefextract_post_args# post arguments must be extracted with an offset@args.postargs.eachdo|arg|@initialization<<arg.updated(:extract_post_arg)@inline<<s(:fake_arg)endenddefextract_optargshas_post_args=@args.has_post_args?@args.optargs.eachdo|arg|ifhas_post_args# optional post argument like 'def m(opt = 1, a)'arg_name,default_value=*arg@initialization<<arg.updated(:extract_post_optarg,[arg_name,default_value,args_to_keep])@inline<<s(:fake_arg)else# optional inline argument like 'def m(a, opt = 1)'@inline<<arg.updated(:arg)@initialization<<arg.updated(:extract_optarg)endendenddefextract_restargif(arg=@args.restarg)arg_name=arg.children[0]@initialization<<arg.updated(:extract_restarg,[arg_name,args_to_keep])@inline<<s(:fake_arg)endenddefargs_to_keep@args.postargs.lengthendendendendend