mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
New rule: RedundantWithObject (#121)
This commit is contained in:
parent
b6cc454039
commit
fde321f7e6
2 changed files with 138 additions and 0 deletions
83
spec/ameba/rule/lint/redundant_with_object_spec.cr
Normal file
83
spec/ameba/rule/lint/redundant_with_object_spec.cr
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
require "../../../spec_helper"
|
||||||
|
|
||||||
|
module Ameba::Rule::Lint
|
||||||
|
describe RedundantWithObject do
|
||||||
|
subject = RedundantWithObject.new
|
||||||
|
|
||||||
|
it "does not report if there is index argument" do
|
||||||
|
s = Source.new %(
|
||||||
|
collection.each_with_object(0) do |e, obj|
|
||||||
|
obj += i
|
||||||
|
end
|
||||||
|
)
|
||||||
|
subject.catch(s).should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports if there is not index argument" do
|
||||||
|
s = Source.new %(
|
||||||
|
collection.each_with_object(0) do |e|
|
||||||
|
e += 1
|
||||||
|
end
|
||||||
|
)
|
||||||
|
subject.catch(s).should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports if there is underscored index argument" do
|
||||||
|
s = Source.new %(
|
||||||
|
collection.each_with_object(0) do |e, _|
|
||||||
|
e += 1
|
||||||
|
end
|
||||||
|
)
|
||||||
|
subject.catch(s).should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports if there is no args" do
|
||||||
|
s = Source.new %(
|
||||||
|
collection.each_with_object(0) do
|
||||||
|
puts :nothing
|
||||||
|
end
|
||||||
|
)
|
||||||
|
subject.catch(s).should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not report if there is no block" do
|
||||||
|
s = Source.new %(
|
||||||
|
collection.each_with_object(0)
|
||||||
|
)
|
||||||
|
subject.catch(s).should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not report if first argument is underscored" do
|
||||||
|
s = Source.new %(
|
||||||
|
collection.each_with_object(0) do |_, obj|
|
||||||
|
puts i
|
||||||
|
end
|
||||||
|
)
|
||||||
|
subject.catch(s).should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not report if there are more than 2 args" do
|
||||||
|
s = Source.new %(
|
||||||
|
tup.each_with_object(0) do |key, value, obj|
|
||||||
|
puts i
|
||||||
|
end
|
||||||
|
)
|
||||||
|
subject.catch(s).should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports rule, location and message" do
|
||||||
|
s = Source.new %(
|
||||||
|
def valid?
|
||||||
|
collection.each_with_object(0) do |e|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
), "source.cr"
|
||||||
|
subject.catch(s).should_not be_valid
|
||||||
|
issue = s.issues.first
|
||||||
|
issue.rule.should_not be_nil
|
||||||
|
issue.location.to_s.should eq "source.cr:2:14"
|
||||||
|
issue.end_location.to_s.should eq "source.cr:2:30"
|
||||||
|
issue.message.should eq "Use each instead of each_with_object"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
55
src/ameba/rule/lint/redundant_with_object.cr
Normal file
55
src/ameba/rule/lint/redundant_with_object.cr
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
module Ameba::Rule::Lint
|
||||||
|
# A rule that disallows redundant `each_with_object` calls.
|
||||||
|
#
|
||||||
|
# For example, this is considered invalid:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# collection.each_with_object(0) do |e|
|
||||||
|
# # ...
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# collection.each_with_object(0) do |e, _|
|
||||||
|
# # ...
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# and it should be written as follows:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# collection.each do |e|
|
||||||
|
# # ...
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# YAML configuration example:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# Lint/RedundantWithObject:
|
||||||
|
# Enabled: true
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
struct RedundantWithObject < Base
|
||||||
|
properties do
|
||||||
|
description "Disallows redundant `with_object` calls"
|
||||||
|
end
|
||||||
|
|
||||||
|
def test(source)
|
||||||
|
AST::NodeVisitor.new self, source
|
||||||
|
end
|
||||||
|
|
||||||
|
def test(source, node : Crystal::Call)
|
||||||
|
return if node.name != "each_with_object" ||
|
||||||
|
node.args.size != 1 ||
|
||||||
|
node.block.nil? ||
|
||||||
|
with_index_arg?(node.block.not_nil!)
|
||||||
|
|
||||||
|
issue_for node.name_location,
|
||||||
|
node.name_end_location,
|
||||||
|
"Use each instead of each_with_object"
|
||||||
|
end
|
||||||
|
|
||||||
|
private def with_index_arg?(block : Crystal::Block)
|
||||||
|
block.args.size >= 2 && block.args.last.name != "_"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue