diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 14:34:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 14:34:42 +0000 |
commit | 9f46488805e86b1bc341ea1620b866016c2ce5ed (patch) | |
tree | f9748c7e287041e37d6da49e0a29c9511dc34768 /rubocop/cop/performance/ar_exists_and_present_blank.rb | |
parent | dfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff) | |
download | gitlab-ce-9f46488805e86b1bc341ea1620b866016c2ce5ed.tar.gz |
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'rubocop/cop/performance/ar_exists_and_present_blank.rb')
-rw-r--r-- | rubocop/cop/performance/ar_exists_and_present_blank.rb | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/rubocop/cop/performance/ar_exists_and_present_blank.rb b/rubocop/cop/performance/ar_exists_and_present_blank.rb new file mode 100644 index 00000000000..54c2d6bf95a --- /dev/null +++ b/rubocop/cop/performance/ar_exists_and_present_blank.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Performance + class ARExistsAndPresentBlank < RuboCop::Cop::Cop + def message_present(ivar) + "Avoid `#{ivar}.present?`, because it will generate database query 'Select TABLE.*' which is expensive. "\ + "Suggest to use `#{ivar}.any?` to replace `#{ivar}.present?`" + end + + def message_blank(ivar) + "Avoid `#{ivar}.blank?`, because it will generate database query 'Select TABLE.*' which is expensive. "\ + "Suggest to use `#{ivar}.empty?` to replace `#{ivar}.blank?`" + end + + def_node_matcher :exists_match, <<~PATTERN + (send (ivar $_) :exists?) + PATTERN + + def_node_matcher :present_match, <<~PATTERN + (send (ivar $_) :present?) + PATTERN + + def_node_matcher :blank_match, <<~PATTERN + (send (ivar $_) :blank?) + PATTERN + + def file_name(node) + node.location.expression.source_buffer.name + end + + def in_haml_file?(node) + file_name(node).end_with?('.haml.rb') + end + + def on_send(node) + return unless in_haml_file?(node) + + ivar_present = present_match(node) + ivar_blank = blank_match(node) + return unless ivar_present || ivar_blank + + node.each_ancestor(:begin) do |begin_node| + begin_node.each_descendant do |n| + ivar_exists = exists_match(n) + next unless ivar_exists + + add_offense(node, location: :expression, message: message_present(ivar_exists)) if ivar_exists == ivar_present + add_offense(node, location: :expression, message: message_blank(ivar_exists)) if ivar_exists == ivar_blank + end + end + end + end + end + end +end |