Extend Lint/UnusedBlockArgument rule with corrections

This commit is contained in:
Sijawusz Pur Rahnama 2022-12-19 15:40:59 +01:00
parent f26cd7f823
commit 3586b4242f
2 changed files with 65 additions and 35 deletions

View file

@ -5,105 +5,118 @@ module Ameba::Rule::Lint
describe UnusedBlockArgument do describe UnusedBlockArgument do
it "doesn't report if it is an instance var argument" do it "doesn't report if it is an instance var argument" do
s = Source.new %( expect_no_issues subject, <<-CRYSTAL
class A class A
def initialize(&@callback) def initialize(&@callback)
end end
end end
) CRYSTAL
subject.catch(s).should be_valid
end end
it "doesn't report if anonymous" do it "doesn't report if anonymous" do
s = Source.new %( expect_no_issues subject, <<-CRYSTAL
def method(a, b, c, &) def method(a, b, c, &)
end end
) CRYSTAL
subject.catch(s).should be_valid
end end
it "doesn't report if argument name starts with a `_`" do it "doesn't report if argument name starts with a `_`" do
s = Source.new %( expect_no_issues subject, <<-CRYSTAL
def method(a, b, c, &_block) def method(a, b, c, &_block)
end end
) CRYSTAL
subject.catch(s).should be_valid
end end
it "doesn't report if it is a block and used" do it "doesn't report if it is a block and used" do
s = Source.new %( expect_no_issues subject, <<-CRYSTAL
def method(a, b, c, &block) def method(a, b, c, &block)
block.call block.call
end end
) CRYSTAL
subject.catch(s).should be_valid
end end
it "reports if block arg is not used" do it "reports if block arg is not used" do
s = Source.new %( source = expect_issue subject, <<-CRYSTAL
def method(a, b, c, &block) def method(a, b, c, &block)
# ^ error: Unused block argument `block`. [...]
end end
) CRYSTAL
subject.catch(s).should_not be_valid
expect_correction source, <<-CRYSTAL
def method(a, b, c, &_block)
end
CRYSTAL
end end
it "reports if unused and there is yield" do it "reports if unused and there is yield" do
s = Source.new %( source = expect_issue subject, <<-CRYSTAL
def method(a, b, c, &block) def method(a, b, c, &block)
# ^ error: Use `&` as an argument name to indicate that it won't be referenced.
3.times do |i| 3.times do |i|
i.try do i.try do
yield i yield i
end end
end end
end end
) CRYSTAL
subject.catch(s).should_not be_valid
expect_correction source, <<-CRYSTAL
def method(a, b, c, &)
3.times do |i|
i.try do
yield i
end
end
end
CRYSTAL
end end
it "doesn't report if anonymous and there is yield" do it "doesn't report if anonymous and there is yield" do
s = Source.new %( expect_no_issues subject, <<-CRYSTAL
def method(a, b, c, &) def method(a, b, c, &)
yield 1 yield 1
end end
) CRYSTAL
subject.catch(s).should be_valid
end end
it "doesn't report if variable is referenced implicitly" do it "doesn't report if variable is referenced implicitly" do
s = Source.new %( expect_no_issues subject, <<-CRYSTAL
class Bar < Foo class Bar < Foo
def method(a, b, c, &block) def method(a, b, c, &block)
super super
end end
end end
) CRYSTAL
subject.catch(s).should be_valid
end end
context "super" do context "super" do
it "reports if variable is not referenced implicitly by super" do it "reports if variable is not referenced implicitly by super" do
s = Source.new %( source = expect_issue subject, <<-CRYSTAL
class Bar < Foo class Bar < Foo
def method(a, b, c, &block) def method(a, b, c, &block)
# ^ error: Unused block argument `block`. [...]
super a, b, c super a, b, c
end end
end end
) CRYSTAL
subject.catch(s).should_not be_valid
s.issues.first.message.should eq "Unused block argument `block`. If it's necessary, " \ expect_correction source, <<-CRYSTAL
"use `_block` as an argument name to indicate " \ class Bar < Foo
"that it won't be used." def method(a, b, c, &_block)
super a, b, c
end
end
CRYSTAL
end end
end end
context "macro" do context "macro" do
it "doesn't report if it is a used macro block argument" do it "doesn't report if it is a used macro block argument" do
s = Source.new %( expect_no_issues subject, <<-CRYSTAL
macro my_macro(&block) macro my_macro(&block)
{% block %} {% block %}
end end
) CRYSTAL
subject.catch(s).should be_valid
end end
end end
end end

View file

@ -31,6 +31,8 @@ module Ameba::Rule::Lint
# Enabled: true # Enabled: true
# ``` # ```
class UnusedBlockArgument < Base class UnusedBlockArgument < Base
include AST::Util
properties do properties do
description "Disallows unused block arguments" description "Disallows unused block arguments"
end end
@ -51,12 +53,27 @@ module Ameba::Rule::Lint
return if block_arg.anonymous? return if block_arg.anonymous?
return if scope.references?(block_arg.variable) return if scope.references?(block_arg.variable)
location = block_arg.node.location
end_location = location.try &.adjust(column_number: block_arg.name.size - 1)
if scope.yields? if scope.yields?
if location && end_location
issue_for block_arg.node, MSG_YIELDED do |corrector|
corrector.remove(location, end_location)
end
else
issue_for block_arg.node, MSG_YIELDED issue_for block_arg.node, MSG_YIELDED
end
else else
return if block_arg.ignored? return if block_arg.ignored?
if location && end_location
issue_for block_arg.node, MSG_UNUSED % block_arg.name do |corrector|
corrector.insert_before(location, '_')
end
else
issue_for block_arg.node, MSG_UNUSED % block_arg.name issue_for block_arg.node, MSG_UNUSED % block_arg.name
end end
end end
end end
end end
end