Class: RuboCop::AST::IfNode

Inherits:
Node
  • Object
show all
Includes:
ConditionalNode, ModifierNode
Defined in:
lib/rubocop/ast/node/if_node.rb

Overview

A node extension for if nodes. This will be used in place of a plain node when the builder constructs the AST, making its methods available to all if nodes within RuboCop.

Constant Summary

Constants inherited from Node

Node::ASSIGNMENTS, Node::BASIC_CONDITIONALS, Node::BASIC_LITERALS, Node::COMPARISON_OPERATORS, Node::COMPOSITE_LITERALS, Node::CONDITIONALS, Node::EQUALS_ASSIGNMENTS, Node::FALSEY_LITERALS, Node::IMMUTABLE_LITERALS, Node::KEYWORDS, Node::LITERALS, Node::MUTABLE_LITERALS, Node::OPERATOR_KEYWORDS, Node::REFERENCES, Node::SHORTHAND_ASSIGNMENTS, Node::SPECIAL_KEYWORDS, Node::TRUTHY_LITERALS, Node::VARIABLES

Instance Method Summary collapse

Methods included from ConditionalNode

#body, #condition, #multiline_condition?, #single_line_condition?

Methods inherited from Node

#ancestors, #argument?, #assignment?, #basic_conditional?, #basic_literal?, #boolean_type?, #call_type?, #chained?, #child_nodes, #complete!, #complete?, #conditional?, #const_name, #defined_module, #defined_module_name, #descendants, #each_ancestor, #each_child_node, #each_descendant, #each_node, #empty_source?, #equals_asgn?, #falsey_literal?, #first_line, #guard_clause?, #immutable_literal?, #initialize, #keyword?, #last_line, #line_count, #literal?, #multiline?, #mutable_literal?, #nonempty_line_count, #numeric_type?, #operator_keyword?, #parent, #parent_module_name, #parenthesized_call?, #pure?, #range_type?, #receiver, #reference?, #shorthand_asgn?, #sibling_index, #single_line?, #source, #source_length, #source_range, #special_keyword?, #truthy_literal?, #updated, #value_used?, #variable?

Methods included from NodePattern::Macros

#def_node_matcher, #def_node_search, #node_search, #node_search_all, #node_search_body, #node_search_first

Methods included from Sexp

#s

Constructor Details

This class inherits a constructor from RuboCop::AST::Node

Instance Method Details

#branchesArray<Node>

Returns an array of all the branches in the conditional statement.



148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/rubocop/ast/node/if_node.rb', line 148

def branches
  branches = [if_branch]

  return branches unless else_branch

  other_branches = if elsif_conditional?
                     else_branch.branches
                   else
                     [else_branch]
                   end
  branches.concat(other_branches)
end

#each_branchself, Enumerator

Calls the given block for each branch node in the conditional statement. If no block is given, an Enumerator is returned.



166
167
168
169
170
171
172
# File 'lib/rubocop/ast/node/if_node.rb', line 166

def each_branch
  return branches.to_enum(__method__) unless block_given?

  branches.each do |branch|
    yield branch
  end
end

#else?Boolean

Note:

This returns true for nodes containing an elsif clause. This is legacy behavior, and many cops rely on it.

Checks whether the if node has an else clause.



42
43
44
# File 'lib/rubocop/ast/node/if_node.rb', line 42

def else?
  loc.respond_to?(:else) && loc.else
end

#else_branchNode?

Note:

This is normalized for unless nodes.

Returns the branch of the if node that gets evaluated when its condition is falsey.



127
128
129
# File 'lib/rubocop/ast/node/if_node.rb', line 127

def else_branch
  node_parts[2]
end

#elsif?Boolean

Checks whether the if is an elsif. Parser handles these by nesting if nodes in the else branch.



32
33
34
# File 'lib/rubocop/ast/node/if_node.rb', line 32

def elsif?
  keyword == 'elsif'
end

#elsif_conditional?Boolean

Checks whether the if node has at least one elsif branch. Returns true if this if node itself is an elsif.



105
106
107
# File 'lib/rubocop/ast/node/if_node.rb', line 105

def elsif_conditional?
  else_branch&.if_type? && else_branch&.elsif?
end

#if?Boolean

Checks whether this node is an if statement. (This is not true of ternary operators and unless statements.)



16
17
18
# File 'lib/rubocop/ast/node/if_node.rb', line 16

def if?
  keyword == 'if'
end

#if_branchNode?

Note:

This is normalized for unless nodes.

Returns the branch of the if node that gets evaluated when its condition is truthy.



116
117
118
# File 'lib/rubocop/ast/node/if_node.rb', line 116

def if_branch
  node_parts[1]
end

#inverse_keywordString

Returns the inverse keyword of the if node as a string. Returns if for unless nodes and vice versa. Returns an empty string for ternary operators.



66
67
68
69
70
71
72
73
74
# File 'lib/rubocop/ast/node/if_node.rb', line 66

def inverse_keyword
  if keyword == 'if'
    'unless'
  elsif keyword == 'unless'
    'if'
  else
    ''
  end
end

#keywordString

Returns the keyword of the if statement as a string. Returns an empty string for ternary operators.



57
58
59
# File 'lib/rubocop/ast/node/if_node.rb', line 57

def keyword
  ternary? ? '' : loc.keyword.source
end

#modifier_form?Boolean

Checks whether the if node is in a modifier form, i.e. a condition trailing behind an expression. Only if and unless nodes without other branches can be modifiers.



81
82
83
# File 'lib/rubocop/ast/node/if_node.rb', line 81

def modifier_form?
  (if? || unless?) && super
end

#nested_conditional?Boolean

Note:

This performs a shallow search.

Chacks whether the if node has nested if nodes in any of its branches.



91
92
93
94
95
96
97
98
99
# File 'lib/rubocop/ast/node/if_node.rb', line 91

def nested_conditional?
  node_parts[1..2].compact.each do |branch|
    branch.each_node(:if) do |nested|
      return true unless nested.elsif?
    end
  end

  false
end

#node_partsArray<Node>

Custom destructuring method. This is used to normalize the branches for if and unless nodes, to aid comparisons and conversions.



135
136
137
138
139
140
141
142
143
# File 'lib/rubocop/ast/node/if_node.rb', line 135

def node_parts
  if unless?
    condition, false_branch, true_branch = *self
  else
    condition, true_branch, false_branch = *self
  end

  [condition, true_branch, false_branch]
end

#ternary?Boolean

Checks whether the if node is a ternary operator.



49
50
51
# File 'lib/rubocop/ast/node/if_node.rb', line 49

def ternary?
  loc.respond_to?(:question)
end

#unless?Boolean

Checks whether this node is an unless statement. (This is not true of ternary operators and if statements.)



24
25
26
# File 'lib/rubocop/ast/node/if_node.rb', line 24

def unless?
  keyword == 'unless'
end