class RuboCop::Cop::Lint::ShadowedArgument


end
bar
foo = super
def do_something(foo)
end
super
foo = 42
def do_something(foo)
# good
@example IgnoreImplicitReferences: true
end
bar
foo = super
def do_something(foo)
end
super
foo = 42
def do_something(foo)
# bad
@example IgnoreImplicitReferences: false (default)
end
puts foo
def do_something(foo)
end
puts foo
foo = foo + 42
def do_something(foo)
end
puts foo
foo = foo + 42
do_something do |foo|
# good
end
puts foo
foo = 42
def do_something(foo)
end
puts foo
foo = 42
do_something do |foo|
# bad
@example
to zero arity ‘super` when `IgnoreImplicitReferences` is `true`.
It means argument shadowing is used in order to pass parameters
This cop has `IgnoreImplicitReferences` configuration option.
Checks for shadowed arguments.

def self.joining_forces

def self.joining_forces
  VariableForce
end

def after_leaving_scope(scope, _variable_table)

def after_leaving_scope(scope, _variable_table)
  scope.variables.each_value { |variable| check_argument(variable) }
end

def argument_references(argument)


Get argument references without assignments' references
def argument_references(argument)
  assignment_references = argument.assignments.flat_map(&:references).map(&:source_range)
  argument.references.reject do |ref|
    next false unless ref.explicit?
    assignment_references.include?(ref.node.source_range)
  end
end

def assignment_without_argument_usage(argument)


shadowing location is not known.
block, it is impossible to tell whether it's executed, so precise
argument at the rhs. If the assignment occurs inside a branch or
Find the first argument assignment, which doesn't reference the
def assignment_without_argument_usage(argument)
  argument.assignments.reduce(true) do |location_known, assignment|
    assignment_node = assignment.meta_assignment_node || assignment.node
    # Shorthand assignments always use their arguments
    next false if assignment_node.shorthand_asgn?
    next false unless assignment_node.parent
    node_within_block_or_conditional =
      node_within_block_or_conditional?(assignment_node.parent, argument.scope.node)
    unless uses_var?(assignment_node, argument.name)
      # It's impossible to decide whether a branch or block is executed,
      # so the precise reassignment location is undecidable.
      next false if node_within_block_or_conditional
      yield(assignment.node, location_known)
      break
    end
    location_known
  end
end

def check_argument(argument)

def check_argument(argument)
  return unless argument.method_argument? || argument.block_argument?
  # Block local variables, i.e., variables declared after ; inside
  # |...| aren't really arguments.
  return if argument.explicit_block_local_variable?
  shadowing_assignment(argument) do |node|
    message = format(MSG, argument: argument.name)
    add_offense(node, message: message)
  end
end

def ignore_implicit_references?

def ignore_implicit_references?
  cop_config['IgnoreImplicitReferences']
end

def node_within_block_or_conditional?(node, stop_search_node)


Check whether the given node is nested into block or conditional.
def node_within_block_or_conditional?(node, stop_search_node)
  return false if node == stop_search_node
  node.conditional? || node.block_type? ||
    node_within_block_or_conditional?(node.parent, stop_search_node)
end

def reference_pos(node)

def reference_pos(node)
  node = node.parent if node.parent.masgn_type?
  node.source_range.begin_pos
end

def shadowing_assignment(argument)

def shadowing_assignment(argument)
  return unless argument.referenced?
  assignment_without_argument_usage(argument) do |node, location_known|
    assignment_without_usage_pos = node.source_range.begin_pos
    references = argument_references(argument)
    # If argument was referenced before it was reassigned
    # then it's not shadowed
    next if references.any? do |reference|
      next true if !reference.explicit? && ignore_implicit_references?
      reference_pos(reference.node) <= assignment_without_usage_pos
    end
    yield location_known ? node : argument.declaration_node
  end
end