# frozen_string_literal: truemoduleRuboCopmoduleCopmoduleLint## This cop emulates the following Ruby warnings in Ruby 2.6.## % cat example.rb# ERB.new('hi', nil, '-', '@output_buffer')# % ruby -rerb example.rb# example.rb:1: warning: Passing safe_level with the 2nd argument of# ERB.new is deprecated. Do not use it, and specify other arguments as# keyword arguments.# example.rb:1: warning: Passing trim_mode with the 3rd argument of# ERB.new is deprecated. Use keyword argument like# ERB.new(str, trim_mode:...) instead.# example.rb:1: warning: Passing eoutvar with the 4th argument of ERB.new# is deprecated. Use keyword argument like ERB.new(str, eoutvar: ...)# instead.## Now non-keyword arguments other than first one are softly deprecated# and will be removed when Ruby 2.5 becomes EOL.# `ERB.new` with non-keyword arguments is deprecated since ERB 2.2.0.# Use `:trim_mode` and `:eoutvar` keyword arguments to `ERB.new`.# This cop identifies places where `ERB.new(str, trim_mode, eoutvar)` can# be replaced by `ERB.new(str, :trim_mode: trim_mode, eoutvar: eoutvar)`.## @example# # Target codes supports Ruby 2.6 and higher only# # bad# ERB.new(str, nil, '-', '@output_buffer')## # good# ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')## # Target codes supports Ruby 2.5 and lower only# # good# ERB.new(str, nil, '-', '@output_buffer')## # Target codes supports Ruby 2.6, 2.5 and lower# # bad# ERB.new(str, nil, '-', '@output_buffer')## # good# # Ruby standard library style# # https://github.com/ruby/ruby/commit/3406c5d# if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+# ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')# else# ERB.new(str, nil, '-', '@output_buffer')# end## # good# # Use `RUBY_VERSION` style# if RUBY_VERSION >= '2.6'# ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')# else# ERB.new(str, nil, '-', '@output_buffer')# end#classErbNewArguments<BaseincludeRangeHelpextendTargetRubyVersionextendAutoCorrectorminimum_target_ruby_version2.6MESSAGES=['Passing safe_level with the 2nd argument of `ERB.new` is '\'deprecated. Do not use it, and specify other arguments as '\'keyword arguments.','Passing trim_mode with the 3rd argument of `ERB.new` is '\'deprecated. Use keyword argument like '\'`ERB.new(str, trim_mode: %<arg_value>s)` instead.','Passing eoutvar with the 4th argument of `ERB.new` is '\'deprecated. Use keyword argument like '\'`ERB.new(str, eoutvar: %<arg_value>s)` instead.'].freezeRESTRICT_ON_SEND=%i[new].freeze# @!method erb_new_with_non_keyword_arguments(node)def_node_matcher:erb_new_with_non_keyword_arguments,<<~PATTERN
(send
(const {nil? cbase} :ERB) :new $...)
PATTERNdefon_send(node)erb_new_with_non_keyword_arguments(node)do|arguments|returnifarguments.empty?||correct_arguments?(arguments)arguments[1..3].each_with_indexdo|argument,i|nextif!argument||argument.hash_type?message=format(MESSAGES[i],arg_value: argument.source)add_offense(argument.source_range,message: message)do|corrector|autocorrect(corrector,node)endendendendprivatedefautocorrect(corrector,node)str_arg=node.arguments[0].sourcekwargs=build_kwargs(node)overridden_kwargs=override_by_legacy_args(kwargs,node)good_arguments=[str_arg,overridden_kwargs].flatten.compact.join(', ')corrector.replace(arguments_range(node),good_arguments)enddefcorrect_arguments?(arguments)arguments.size==1||arguments.size==2&&arguments[1].hash_type?enddefbuild_kwargs(node)return[nil,nil]unlessnode.arguments.last.hash_type?trim_mode_arg,eoutvar_arg=nilnode.arguments.last.pairs.eachdo|pair|casepair.key.sourcewhen'trim_mode'trim_mode_arg="trim_mode: #{pair.value.source}"when'eoutvar'eoutvar_arg="eoutvar: #{pair.value.source}"endend[trim_mode_arg,eoutvar_arg]enddefoverride_by_legacy_args(kwargs,node)arguments=node.argumentsoverridden_kwargs=kwargs.dupoverridden_kwargs[0]="trim_mode: #{arguments[2].source}"ifarguments[2]ifarguments[3]&&!arguments[3].hash_type?overridden_kwargs[1]="eoutvar: #{arguments[3].source}"endoverridden_kwargsenddefarguments_range(node)arguments=node.argumentsrange_between(arguments.first.source_range.begin_pos,arguments.last.source_range.end_pos)endendendendend