Class: RuboCop::Cop::Style::MutableConstant

Inherits:
Cop
  • Object
show all
Includes:
ConfigurableEnforcedStyle, FrozenStringLiteral
Defined in:
lib/rubocop/cop/style/mutable_constant.rb

Overview

This cop checks whether some constant value isn't a mutable literal (e.g. array or hash).

Strict mode can be used to freeze all constants, rather than just literals. Strict mode is considered an experimental feature. It has not been updated with an exhaustive list of all methods that will produce frozen objects so there is a decent chance of getting some false positives. Luckily, there is no harm in freezing an already frozen object.

Examples:

EnforcedStyle: literals (default)

# bad
CONST = [1, 2, 3]

# good
CONST = [1, 2, 3].freeze

# good
CONST = <<~TESTING.freeze
  This is a heredoc
TESTING

# good
CONST = Something.new

EnforcedStyle: strict

# bad
CONST = Something.new

# bad
CONST = Struct.new do
  def foo
    puts 1
  end
end

# good
CONST = Something.new.freeze

# good
CONST = Struct.new do
  def foo
    puts 1
  end
end.freeze

Constant Summary collapse

MSG =
'Freeze mutable objects assigned to constants.'

Constants included from FrozenStringLiteral

FrozenStringLiteral::FROZEN_STRING_LITERAL, FrozenStringLiteral::FROZEN_STRING_LITERAL_ENABLED, FrozenStringLiteral::FROZEN_STRING_LITERAL_TYPES

Constants included from Util

Util::LITERAL_REGEX

Instance Attribute Summary

Attributes inherited from Cop

#config, #corrections, #offenses, #processed_source

Instance Method Summary collapse

Methods included from ConfigurableEnforcedStyle

#alternative_style, #alternative_styles, #ambiguous_style_detected, #correct_style_detected, #detected_style, #detected_style=, #no_acceptable_style!, #no_acceptable_style?, #opposite_style_detected, #style, #style_detected, #style_parameter_name, #supported_styles, #unexpected_style_detected

Methods included from FrozenStringLiteral

frozen_string_literal_comment_exists?

Methods inherited from Cop

#add_offense, all, autocorrect_incompatible_with, badge, #config_to_allow_offenses, #config_to_allow_offenses=, #cop_config, cop_name, #cop_name, #correct, department, #duplicate_location?, #excluded_file?, #find_location, #highlights, inherited, #initialize, #join_force?, lint?, match?, #message, #messages, non_rails, #parse, qualified_cop_name, #relevant_file?, #target_rails_version, #target_ruby_version

Methods included from NodePattern::Macros

#def_node_matcher, #def_node_search, #node_search, #node_search_all, #node_search_body, #node_search_first

Methods included from AST::Sexp

#s

Methods included from AutocorrectLogic

#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #support_autocorrect?

Methods included from IgnoredNode

#ignore_node, #ignored_node?, #part_of_ignored_node?

Methods included from Util

begins_its_line?, comment_line?, double_quotes_required?, escape_string, first_part_of_call_chain, interpret_string_escapes, line_range, needs_escaping?, on_node, parentheses?, same_line?, to_string_literal, to_supported_styles, tokens, trim_string_interporation_escape_character

Methods included from PathUtil

absolute?, chdir, hidden_dir?, hidden_file_in_not_hidden_dir?, match_path?, pwd, relative_path, reset_pwd, smart_path

Constructor Details

This class inherits a constructor from RuboCop::Cop::Cop

Instance Method Details

#autocorrect(node) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/rubocop/cop/style/mutable_constant.rb', line 72

def autocorrect(node)
  expr = node.source_range

  lambda do |corrector|
    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
end

#on_casgn(node) ⇒ Object



59
60
61
62
# File 'lib/rubocop/cop/style/mutable_constant.rb', line 59

def on_casgn(node)
  _scope, _const_name, value = *node
  on_assignment(value)
end

#on_or_asgn(node) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/rubocop/cop/style/mutable_constant.rb', line 64

def on_or_asgn(node)
  lhs, value = *node

  return unless lhs&.casgn_type?

  on_assignment(value)
end