Class: RuboCop::Cop::VariableForce::Variable Private
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/rubocop/cop/variable_force/variable.rb |
Overview
A Variable represents existence of a local variable. This holds a variable declaration node and some states of the variable.
Constant Summary
-
VARIABLE_DECLARATION_TYPES =
# File 'lib/rubocop/cop/variable_force/variable.rb', line 9(VARIABLE_ASSIGNMENT_TYPES + ARGUMENT_DECLARATION_TYPES).freeze
Class Method Summary
- .new(name, declaration_node, scope) ⇒ Variable constructor Internal use only
Instance Attribute Summary
- #argument? ⇒ Boolean readonly Internal use only
- #assignments readonly Internal use only
- #block_argument? ⇒ Boolean readonly Internal use only
-
#captured_by_block?
readonly
Alias for #captured_by_block.
- #declaration_node readonly Internal use only
- #explicit_block_local_variable? ⇒ Boolean readonly Internal use only
- #keyword_argument? ⇒ Boolean readonly Internal use only
- #method_argument? ⇒ Boolean readonly Internal use only
- #name readonly Internal use only
- #referenced? ⇒ Boolean readonly Internal use only
- #references readonly Internal use only
- #scope readonly Internal use only
- #should_be_unused? ⇒ Boolean readonly Internal use only
-
#used? ⇒ Boolean
readonly
Internal use only
This is a convenient way to check whether the variable is used in its entire variable lifetime.
Instance Method Summary
- #assign(node) Internal use only
- #capture_with_block! Internal use only
- #captured_by_block (also: #captured_by_block?) readonly Internal use only
-
#in_modifier_conditional?(assignment) ⇒ Boolean
Internal use only
Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.
-
#reference!(node)
Internal use only
Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.
Constructor Details
.new(name, declaration_node, scope) ⇒ Variable
# File 'lib/rubocop/cop/variable_force/variable.rb', line 15
def initialize(name, declaration_node, scope) unless VARIABLE_DECLARATION_TYPES.include?(declaration_node.type) raise ArgumentError, "Node type must be any of #{VARIABLE_DECLARATION_TYPES}, " \ "passed #{declaration_node.type}" end @name = name.to_sym @declaration_node = declaration_node @scope = scope @assignments = [] @references = [] @captured_by_block = false end
Instance Attribute Details
#argument? ⇒ Boolean
(readonly)
# File 'lib/rubocop/cop/variable_force/variable.rb', line 98
def argument? ARGUMENT_DECLARATION_TYPES.include?(@declaration_node.type) end
#assignments (readonly)
[ GitHub ]# File 'lib/rubocop/cop/variable_force/variable.rb', line 11
attr_reader :name, :declaration_node, :scope, :assignments, :references, :captured_by_block
#block_argument? ⇒ Boolean
(readonly)
# File 'lib/rubocop/cop/variable_force/variable.rb', line 106
def block_argument? argument? && @scope.node.block_type? end
#captured_by_block? (readonly)
Alias for #captured_by_block.
# File 'lib/rubocop/cop/variable_force/variable.rb', line 13
alias captured_by_block? captured_by_block
#declaration_node (readonly)
[ GitHub ]# File 'lib/rubocop/cop/variable_force/variable.rb', line 11
attr_reader :name, :declaration_node, :scope, :assignments, :references, :captured_by_block
#explicit_block_local_variable? ⇒ Boolean
(readonly)
# File 'lib/rubocop/cop/variable_force/variable.rb', line 114
def explicit_block_local_variable? @declaration_node.shadowarg_type? end
#keyword_argument? ⇒ Boolean
(readonly)
# File 'lib/rubocop/cop/variable_force/variable.rb', line 110
def keyword_argument? %i[kwarg kwoptarg].include?(@declaration_node.type) end
#method_argument? ⇒ Boolean
(readonly)
# File 'lib/rubocop/cop/variable_force/variable.rb', line 102
def method_argument? argument? && %i[def defs].include?(@scope.node.type) end
#name (readonly)
[ GitHub ]# File 'lib/rubocop/cop/variable_force/variable.rb', line 11
attr_reader :name, :declaration_node, :scope, :assignments, :references, :captured_by_block
#referenced? ⇒ Boolean
(readonly)
# File 'lib/rubocop/cop/variable_force/variable.rb', line 39
def referenced? !@references.empty? end
#references (readonly)
[ GitHub ]# File 'lib/rubocop/cop/variable_force/variable.rb', line 11
attr_reader :name, :declaration_node, :scope, :assignments, :references, :captured_by_block
#scope (readonly)
[ GitHub ]# File 'lib/rubocop/cop/variable_force/variable.rb', line 11
attr_reader :name, :declaration_node, :scope, :assignments, :references, :captured_by_block
#should_be_unused? ⇒ Boolean
(readonly)
# File 'lib/rubocop/cop/variable_force/variable.rb', line 94
def should_be_unused? name.to_s.start_with?('_') end
#used? ⇒ Boolean
(readonly)
This is a convenient way to check whether the variable is used in its entire variable lifetime. For more precise usage check, refer Assignment#used?.
Once the variable is captured by a block, we have no idea when, where, and how many times the block would be invoked. This means we cannot track the usage of the variable. So we consider it’s used to suppress false positive offenses.
# File 'lib/rubocop/cop/variable_force/variable.rb', line 90
def used? @captured_by_block || referenced? end
Instance Method Details
#assign(node)
[ GitHub ]# File 'lib/rubocop/cop/variable_force/variable.rb', line 31
def assign(node) assignment = Assignment.new(node, self) @assignments.last&.reassigned! unless captured_by_block? @assignments << assignment end
#capture_with_block!
[ GitHub ]# File 'lib/rubocop/cop/variable_force/variable.rb', line 78
def capture_with_block! @captured_by_block = true end
#captured_by_block (readonly) Also known as: #captured_by_block?
[ GitHub ]# File 'lib/rubocop/cop/variable_force/variable.rb', line 11
attr_reader :name, :declaration_node, :scope, :assignments, :references, :captured_by_block
#in_modifier_conditional?(assignment) ⇒ Boolean
Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# File 'lib/rubocop/cop/variable_force/variable.rb', line 70
def in_modifier_conditional?(assignment) parent = assignment.node.parent parent = parent.parent if parent&.begin_type? return false if parent.nil? (parent.if_type? || parent.while_type? || parent.until_type?) && parent.modifier_form? end
#reference!(node)
Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# File 'lib/rubocop/cop/variable_force/variable.rb', line 44
def reference!(node) reference = Reference.new(node, @scope) @references << reference consumed_branches = nil @assignments.reverse_each do |assignment| next if consumed_branches&.include?(assignment.branch) assignment.reference!(node) unless assignment.run_exclusively_with?(reference) # Modifier if/unless conditions are special. Assignments made in # them do not put the assigned variable in scope to the left of the # if/unless keyword. A preceding assignment is needed to put the # variable in scope. For this reason we skip to the next assignment # here. next if in_modifier_conditional?(assignment) break if !assignment.branch || assignment.branch == reference.branch unless assignment.branch.may_run_incompletely? (consumed_branches ||= Set.new) << assignment.branch end end end