diff --git a/changelog/fix_hardcoded_block_parameter_name.md b/changelog/fix_hardcoded_block_parameter_name.md new file mode 100644 index 00000000000..21fc52241e8 --- /dev/null +++ b/changelog/fix_hardcoded_block_parameter_name.md @@ -0,0 +1 @@ +* [#10064](https://github.com/rubocop/rubocop/pull/10064): Fix `Style/ExplicitBlockArgument` corrector assuming any existing block argument was named `block`. ([@byroot][]) diff --git a/lib/rubocop/cop/style/explicit_block_argument.rb b/lib/rubocop/cop/style/explicit_block_argument.rb index eede1284f8d..366d61a7eff 100644 --- a/lib/rubocop/cop/style/explicit_block_argument.rb +++ b/lib/rubocop/cop/style/explicit_block_argument.rb @@ -67,17 +67,27 @@ def on_yield(node) # so this can cause crashes in haml_lint return unless def_node + block_name = extract_block_name(def_node) + add_offense(block_node) do |corrector| corrector.remove(block_body_range(block_node, send_node)) - add_block_argument(send_node, corrector) - add_block_argument(def_node, corrector) if @def_nodes.add?(def_node) + add_block_argument(send_node, corrector, block_name) + add_block_argument(def_node, corrector, block_name) if @def_nodes.add?(def_node) end end end private + def extract_block_name(def_node) + if def_node.block_argument? + def_node.arguments.last.name + else + 'block' + end + end + def yielding_arguments?(block_args, yield_args) yield_args = yield_args.dup.fill( nil, @@ -91,15 +101,15 @@ def yielding_arguments?(block_args, yield_args) end end - def add_block_argument(node, corrector) + def add_block_argument(node, corrector, block_name) if node.arguments? - insert_argument(node, corrector) + insert_argument(node, corrector, block_name) elsif empty_arguments?(node) - corrector.replace(node.arguments, '(&block)') + corrector.replace(node.arguments, "(&#{block_name})") elsif call_like?(node) - correct_call_node(node, corrector) + correct_call_node(node, corrector, block_name) else - corrector.insert_after(node.loc.name, '(&block)') + corrector.insert_after(node.loc.name, "(&#{block_name})") end end @@ -112,16 +122,16 @@ def call_like?(node) node.call_type? || node.zsuper_type? || node.super_type? end - def insert_argument(node, corrector) + def insert_argument(node, corrector, block_name) last_arg = node.arguments.last arg_range = range_with_surrounding_comma(last_arg.source_range, :right) - replacement = ' &block' + replacement = " &#{block_name}" replacement = ",#{replacement}" unless arg_range.source.end_with?(',') corrector.insert_after(arg_range, replacement) unless last_arg.blockarg_type? end - def correct_call_node(node, corrector) - corrector.insert_after(node, '(&block)') + def correct_call_node(node, corrector, block_name) + corrector.insert_after(node, "(&#{block_name})") return unless node.parenthesized? args_begin = Util.args_begin(node) diff --git a/spec/rubocop/cop/style/explicit_block_argument_spec.rb b/spec/rubocop/cop/style/explicit_block_argument_spec.rb index 52c20e7576b..4bceb9bdc17 100644 --- a/spec/rubocop/cop/style/explicit_block_argument_spec.rb +++ b/spec/rubocop/cop/style/explicit_block_argument_spec.rb @@ -41,15 +41,15 @@ def m it 'correctly corrects when method already has an explicit block argument' do expect_offense(<<~RUBY) - def m(&block) + def m(&blk) items.something { |i| yield i } ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Consider using explicit block argument in the surrounding method's signature over `yield`. end RUBY expect_correction(<<~RUBY) - def m(&block) - items.something(&block) + def m(&blk) + items.something(&blk) end RUBY end