class RuboCop::Cop::Sorbet::ForbidIncludeConstLiteral
def autocorrect(node)
def autocorrect(node) lambda do |corrector| # Find parent class node parent = node.parent parent = parent.parent if parent.type == :begin # Build include variable name class_name = (parent.child_nodes.first.const_name || 'Anon').split('::').last include_name = find_free_name("#{class_name}Include") used_names << include_name # Apply fix indent = ' ' * node.loc.column fix = "#{include_name} = #{node.child_nodes.first.source}\n#{indent}" corrector.insert_before(node.loc.expression, fix) corrector.replace(node.child_nodes.first.loc.expression, include_name) end end
def find_free_name(base_name)
we need to ensure that we don't use the same name twice in the same
Since each include uses its own local variable to store the send result,
Find a free local variable name
def find_free_name(base_name) return base_name unless used_names.include?(base_name) i = 2 i += 1 while used_names.include?("#{base_name}#{i}") "#{base_name}#{i}" end
def initialize(*)
def initialize(*) super self.used_names = Set.new end
def on_send(node)
def on_send(node) return unless not_lit_const_include?(node) do |send_argument| ![:const, :self].include?(send_argument.type) end parent = node.parent return unless parent parent = parent.parent if [:begin, :block].include?(parent.type) return unless [:module, :class, :sclass].include?(parent.type) add_offense(node) end