class RuboCop::Cop::ThreadSafety::MutableClassInstanceVariable

end
end.freeze
end
puts 1
def foo
@var = Struct.new do
class Model
# good
end
@var = Something.new.freeze
class Model
# good
end
end
end
puts 1
def foo
@var = Struct.new do
class Model
# bad
end
@var = Something.new
class Model
# bad
@example EnforcedStyle: strict
end
@var = Something.new
class Model
# good
end
TESTING
This is a heredoc
@var = <<~TESTING.freeze
class Model
# good
end
@list = [1, 2, 3].freeze
class Model
# good
end
@list = [1, 2, 3]
class Model
# bad
@example EnforcedStyle: literals (default)
Luckily, there is no harm in freezing an already frozen object.
objects so there is a decent chance of getting some false positives.
updated with an exhaustive list of all methods that will produce frozen
Strict mode is considered an experimental feature. It has not been
than just literals.
Strict mode can be used to freeze all class instance variables, rather
ThreadSafety/ClassAndModuleAttributes cop.
updated via an attr_reader so would not be detected by the
between threads. A mutable object such as an array or hash may be
Class instance variables are a risk to threaded code as they are shared
See github.com/rubocop/rubocop/blob/master/lib/rubocop/cop/style/mutable_constant.rb<br>It is based on Style/MutableConstant from RuboCop.
mutable literal (e.g. array or hash).
Checks whether some class instance variable isn’t a

def autocorrect(corrector, node)

def autocorrect(corrector, node)
  expr = node.source_range
  splat_value = splat_value(node)
  if splat_value
    correct_splat_expansion(corrector, expr, splat_value)
  elsif node.array_type? && !node.bracketed?
    corrector.insert_before(expr, '[')
    corrector.insert_after(expr, ']')
  elsif requires_parentheses?(node)
    corrector.insert_before(expr, '(')
    corrector.insert_after(expr, ')')
  end
  corrector.insert_after(expr, '.freeze')
end

def check(value)

def check(value)
  return unless mutable_literal?(value) ||
                range_enclosed_in_parentheses?(value)
  return if frozen_string_literal?(value)
  add_offense(value) do |corrector|
    autocorrect(corrector, value)
  end
end

def container?(node)

def container?(node)
  return true if define_singleton_method?(node)
  return true if define_method?(node)
  %i[def defs class module].include?(node.type)
end

def correct_splat_expansion(corrector, expr, splat_value)

def correct_splat_expansion(corrector, expr, splat_value)
  if range_enclosed_in_parentheses?(splat_value)
    corrector.replace(expr, "#{splat_value.source}.to_a")
  else
    corrector.replace(expr, "(#{splat_value.source}).to_a")
  end
end

def frozen_string_literal?(node)

def frozen_string_literal?(node)
  literal_types = if target_ruby_version >= 3.0
                    FROZEN_STRING_LITERAL_TYPES_RUBY30
                  else
                    FROZEN_STRING_LITERAL_TYPES_RUBY27
                  end
  literal_types.include?(node.type) && frozen_string_literals_enabled?
end

def immutable_literal?(node)

def immutable_literal?(node)
  node.nil? || node.immutable_literal?
end

def in_class?(node)

def in_class?(node)
  container = node.ancestors.find do |ancestor|
    container?(ancestor)
  end
  return false if container.nil?
  %i[class module].include?(container.type)
end

def mutable_literal?(node)

def mutable_literal?(node)
  return false if node.nil?
  node.mutable_literal? || range_type?(node)
end

def on_assignment(value)

def on_assignment(value)
  if style == :strict
    strict_check(value)
  else
    check(value)
  end
end

def on_ivasgn(node)

def on_ivasgn(node)
  return unless in_class?(node)
  on_assignment(node.expression)
end

def on_masgn(node)

def on_masgn(node)
  return unless in_class?(node)
  mlhs, values = *node # rubocop:disable InternalAffairs/NodeDestructuring
  return unless values.array_type?
  mlhs.to_a.zip(values.to_a).each do |lhs, value|
    next unless lhs.ivasgn_type?
    on_assignment(value)
  end
end

def on_or_asgn(node)

def on_or_asgn(node)
  return unless node.assignment_node.ivasgn_type?
  return unless in_class?(node)
  on_assignment(node.expression)
end

def range_type?(node)

def range_type?(node)
  node.type?(:range)
end

def requires_parentheses?(node)

def requires_parentheses?(node)
  range_type?(node) ||
    (node.send_type? && node.loc.dot.nil?)
end

def strict_check(value)

def strict_check(value)
  return if immutable_literal?(value)
  return if operation_produces_immutable_object?(value)
  return if operation_produces_threadsafe_object?(value)
  return if frozen_string_literal?(value)
  add_offense(value) do |corrector|
    autocorrect(corrector, value)
  end
end