2021-01-26 13:09:30 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-01-09 12:30:04 -05:00
|
|
|
module RuboCop
|
|
|
|
module Cop
|
|
|
|
module Gitlab
|
|
|
|
class PredicateMemoization < RuboCop::Cop::Cop
|
2021-01-26 13:09:30 -05:00
|
|
|
MSG = <<~EOL
|
2018-01-09 12:30:04 -05:00
|
|
|
Avoid using `@value ||= query` inside predicate methods in order to
|
|
|
|
properly memoize `false` or `nil` values.
|
|
|
|
https://docs.gitlab.com/ee/development/utilities.html#strongmemoize
|
|
|
|
EOL
|
|
|
|
|
|
|
|
def on_def(node)
|
|
|
|
return unless predicate_method?(node)
|
|
|
|
|
|
|
|
select_offenses(node).each do |offense|
|
2021-01-26 13:09:30 -05:00
|
|
|
add_offense(offense)
|
2018-01-09 12:30:04 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def predicate_method?(node)
|
|
|
|
node.method_name.to_s.end_with?('?')
|
|
|
|
end
|
|
|
|
|
|
|
|
def or_ivar_assignment?(or_assignment)
|
|
|
|
lhs = or_assignment.each_child_node.first
|
|
|
|
|
|
|
|
lhs.ivasgn_type?
|
|
|
|
end
|
|
|
|
|
|
|
|
def select_offenses(node)
|
|
|
|
node.each_descendant(:or_asgn).select do |or_assignment|
|
|
|
|
or_ivar_assignment?(or_assignment)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|