lib/reek/context/visibility_tracker.rb
# frozen_string_literal: true
module Reek
module Context
# Responsible for tracking visibilities in regards to CodeContexts.
class VisibilityTracker
VISIBILITY_MODIFIERS = [:private, :public, :protected, :module_function].freeze
VISIBILITY_MAP = { public_class_method: :public, private_class_method: :private }.freeze
def initialize
@tracked_visibility = :public
end
# Handle the effects of a visibility modifier.
#
# @example Modifying the visibility of existing children
# track_visibility children, :private, [:hide_me, :implementation_detail]
#
# @param children [Array<CodeContext>]
# @param visibility [Symbol]
# @param names [Array<Symbol>]
#
def track_visibility(children:, visibility:, names:)
return unless VISIBILITY_MODIFIERS.include? visibility
if names.any?
children.each do |child|
child.visibility = visibility if names.include?(child.name)
end
else
self.tracked_visibility = visibility
end
end
# Handle the effects of a singleton visibility modifier. These can only
# be used to modify existing children.
#
# @example
# track_singleton_visibility children, :private_class_method,
# [:hide_me, :implementation_detail]
#
# @param children [Array<CodeContext>]
# @param visibility [Symbol]
# @param names [Array<Symbol>]
#
def track_singleton_visibility(children:, visibility:, names:)
return if names.empty?
visibility = VISIBILITY_MAP[visibility]
return unless visibility
track_visibility children: children, visibility: visibility, names: names
end
# Sets the visibility of a CodeContext to the tracked visibility.
#
# @param context [CodeContext]
#
def apply_visibility(context)
context.apply_current_visibility tracked_visibility
end
private
attr_accessor :tracked_visibility
end
end
end