mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Fix couple of edge-cases in VerboseBlock rule
This commit is contained in:
parent
5faf8da81c
commit
eed094b928
2 changed files with 41 additions and 3 deletions
|
@ -14,6 +14,18 @@ module Ameba::Rule::Style
|
|||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
it "passes if the block argument is used within the body" do
|
||||
source = Source.new %(
|
||||
(1..3).map { |i| i * i }
|
||||
(1..3).map { |j| j * j.to_i64 }
|
||||
(1..3).map { |k| k.to_i64 * k }
|
||||
(1..3).map { |l| l.to_i64 * l.to_i64 }
|
||||
(1..3).map { |m| m.to_s[start: m.to_i64, count: 3]? }
|
||||
(1..3).map { |n| n.to_s.split.map { |z| n.to_i * z.to_i }.join }
|
||||
)
|
||||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
it "reports if there is a call with a collapsible block" do
|
||||
source = Source.new %(
|
||||
(1..3).any? { |i| i.odd? }
|
||||
|
|
|
@ -80,6 +80,27 @@ module Ameba::Rule::Style
|
|||
true
|
||||
end
|
||||
|
||||
protected def reference_count(node, obj : Crystal::Var)
|
||||
i = 0
|
||||
case node
|
||||
when Crystal::Call
|
||||
i += reference_count(node.obj, obj)
|
||||
i += reference_count(node.block, obj)
|
||||
|
||||
node.args.each do |arg|
|
||||
i += reference_count(arg, obj)
|
||||
end
|
||||
node.named_args.try &.each do |arg|
|
||||
i += reference_count(arg.value, obj)
|
||||
end
|
||||
when Crystal::Block
|
||||
i += reference_count(node.body, obj)
|
||||
when Crystal::Var
|
||||
i += 1 if node == obj
|
||||
end
|
||||
i
|
||||
end
|
||||
|
||||
protected def node_to_s(node : Crystal::Call)
|
||||
case name = node.name
|
||||
when "[]"
|
||||
|
@ -143,6 +164,11 @@ module Ameba::Rule::Style
|
|||
# ```
|
||||
return unless (block = node.block) && block.args.size == 1
|
||||
|
||||
arg = block.args.first
|
||||
|
||||
# we skip auto-generated blocks - `(1..3).any?(&.odd?)`
|
||||
return if arg.name.starts_with?("__arg")
|
||||
|
||||
# we filter out the blocks that are of call type - `i.to_i64.odd?`
|
||||
return unless (body = block.body).is_a?(Crystal::Call)
|
||||
|
||||
|
@ -155,10 +181,10 @@ module Ameba::Rule::Style
|
|||
return unless obj.is_a?(Crystal::Var)
|
||||
|
||||
# only calls with a first argument used as a receiver are the valid game
|
||||
return unless (arg = block.args.first) == obj
|
||||
return unless obj == arg
|
||||
|
||||
# we skip auto-generated blocks - `(1..3).any?(&.odd?)`
|
||||
return if arg.name.starts_with?("__arg")
|
||||
# we bail out if the block node include the block argument
|
||||
return if reference_count(body, arg) > 1
|
||||
|
||||
# add issue if the given nodes pass all of the checks
|
||||
issue_for_valid source, node, body
|
||||
|
|
Loading…
Reference in a new issue