Performance/Count -> Performance/SizeAfterFilter

This commit is contained in:
Vitalii Elenhaupt 2018-09-03 22:38:32 +03:00
parent 799c0fd5e1
commit 790b519653
No known key found for this signature in database
GPG key ID: 7558EF3A4056C706
2 changed files with 23 additions and 15 deletions

View file

@ -1,9 +1,9 @@
require "../../../spec_helper" require "../../../spec_helper"
module Ameba::Rule::Performance module Ameba::Rule::Performance
subject = Count.new subject = SizeAfterFilter.new
describe Count do describe SizeAfterFilter do
it "passes if there is no potential performance improvements" do it "passes if there is no potential performance improvements" do
source = Source.new %( source = Source.new %(
[1, 2, 3].select { |e| e > 2 } [1, 2, 3].select { |e| e > 2 }
@ -43,8 +43,8 @@ module Ameba::Rule::Performance
source = Source.new %( source = Source.new %(
[1, 2, 3].reject(&.empty?).size [1, 2, 3].reject(&.empty?).size
) )
rule = Rule::Performance::Count.new rule = Rule::Performance::SizeAfterFilter.new
rule.object_call_names = %w(select) rule.filter_names = %w(select)
rule.catch(source).should be_valid rule.catch(source).should be_valid
end end
end end

View file

@ -1,6 +1,5 @@
module Ameba::Rule::Performance module Ameba::Rule::Performance
# This rule is used to identify usage of `size` calls that follow to object # This rule is used to identify usage of `size` calls that follow filter.
# caller names `select` and `reject`.
# #
# For example, this is considered invalid: # For example, this is considered invalid:
# #
@ -16,20 +15,29 @@ module Ameba::Rule::Performance
# #
# ``` # ```
# [1, 2, 3].count { |e| e > 2 } # [1, 2, 3].count { |e| e > 2 }
# [1, 2, 3].count { |e| e > 2 } # [1, 2, 3].count { |e| e >= 2 }
# [1, 2, 3].count(&.< 2) # [1, 2, 3].count(&.< 2)
# [0, 1, 2].count(&.zero?) # [0, 1, 2].count(&.zero?)
# [0, 1, 2].count(&.!= 0) # [0, 1, 2].count(&.!= 0)
# ``` # ```
# #
struct Count < Base # YAML configuration example:
SIZE_CALL_NAME = "size" #
MSG = "Use `count {...}` instead of `%s {...}.#{SIZE_CALL_NAME}`." # ```
# Performance/SizeAfterFilter:
# Enabled: true
# FilterNames:
# - select
# - reject
# ```
#
struct SizeAfterFilter < Base
SIZE_NAME = "size"
MSG = "Use `count {...}` instead of `%s {...}.#{SIZE_NAME}`."
properties do properties do
object_call_names : Array(String) = %w(select reject) filter_names : Array(String) = %w(select reject)
description "Identifies usage of `size` calls that follow to object \ description "Identifies usage of `size` calls that follow filter"
caller names (`select`/`reject` by default)."
end end
def test(source) def test(source)
@ -37,10 +45,10 @@ module Ameba::Rule::Performance
end end
def test(source, node : Crystal::Call) def test(source, node : Crystal::Call)
return unless node.name == SIZE_CALL_NAME && (obj = node.obj) return unless node.name == SIZE_NAME && (obj = node.obj)
if obj.is_a?(Crystal::Call) && if obj.is_a?(Crystal::Call) &&
object_call_names.includes?(obj.name) && !obj.block.nil? filter_names.includes?(obj.name) && !obj.block.nil?
issue_for obj.name_location, node.name_end_location, MSG % obj.name issue_for obj.name_location, node.name_end_location, MSG % obj.name
end end