Class: Reek::SmellDetectors::ControlParameterHelpers::CallInConditionFinder

Inherits:
Object
  • Object
show all
Defined in:
lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb

Overview

CallInConditionFinder finds usages of the given parameter in the context of a method call in a condition, e.g.:

def alfa(bravo)

if charlie(bravo)
  delta
end

end

or

def alfa(bravo)

if bravo.charlie?
  delta
end

end

Those usages are legit and should not trigger the ControlParameter smell warning.

Constant Summary collapse

COMPARISON_METHOD_NAMES =
[:==, :!=, :=~].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node, parameter) ⇒ CallInConditionFinder

Returns a new instance of CallInConditionFinder.

Parameters:

  • node (Reek::AST::Node)

    the node in our current scope, e.g. s(:def, :alfa,

    s(:args,
      s(:arg, :bravo),
    
  • parameter (Symbol)

    the parameter name in question e.g. in the example above this would be :bravo



37
38
39
40
# File 'lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb', line 37

def initialize(node, parameter)
  @node = node
  @parameter = parameter
end

Instance Attribute Details

#nodeObject (readonly, private)

Returns the value of attribute node.



58
59
60
# File 'lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb', line 58

def node
  @node
end

#parameterObject (readonly, private)

Returns the value of attribute parameter.



58
59
60
# File 'lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb', line 58

def parameter
  @parameter
end

Instance Method Details

#call_involving_param?(call_node) ⇒ Boolean (private)

Returns if the parameter is used in the given method call.

Returns:

  • (Boolean)

    if the parameter is used in the given method call



77
78
79
# File 'lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb', line 77

def call_involving_param?(call_node)
  call_node.each_node(:lvar).any? { |it| it.var_name == parameter }
end

#comparison_call?(call_node) ⇒ Boolean (private)

:reek:UtilityFunction

Returns:

  • (Boolean)

    if the given method call is a comparison call



85
86
87
# File 'lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb', line 85

def comparison_call?(call_node)
  COMPARISON_METHOD_NAMES.include? call_node.name
end

#regular_call_involving_param?(call_node) ⇒ Boolean (private)

Returns if the parameter is used in a method call that is not a comparison call e.g. this would return true given that “bravo” is the parameter in question:

if charlie(bravo) then delta end

while this would return false (since its a comparison):

if bravo == charlie then charlie end.

Returns:

  • (Boolean)

    if the parameter is used in a method call that is not a comparison call e.g. this would return true given that “bravo” is the parameter in question:

    if charlie(bravo) then delta end
    

    while this would return false (since its a comparison):

    if bravo == charlie then charlie end
    


70
71
72
# File 'lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb', line 70

def regular_call_involving_param?(call_node)
  call_involving_param?(call_node) && !comparison_call?(call_node)
end

#uses_param_in_call_in_condition?Boolean

Returns if the parameter in question has been used in the context of a method call in a condition.

Returns:

  • (Boolean)

    if the parameter in question has been used in the context of a method call in a condition



46
47
48
49
50
51
52
53
54
# File 'lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb', line 46

def uses_param_in_call_in_condition?
  condition = node.condition
  return false unless condition

  condition.each_node(:send) do |inner|
    return true if regular_call_involving_param?(inner)
  end
  false
end