class RuboCop::Cop::Style::FrozenStringLiteralComment
Helps you transition from mutable string literals to frozen string literals. It will add the ‘# frozen_string_literal: true` magic comment to the top of files to enable frozen string literals. Frozen string literals may be default in future Ruby. The comment will be added below a shebang and encoding comment. The frozen string literal comment is only valid in Ruby 2.3+.
Note that the cop will accept files where the comment exists but is set to ‘false` instead of `true`.
To require a blank line after this comment, please see ‘Layout/EmptyLineAfterMagicComment` cop.
@safety
This cop's autocorrection is unsafe since any strings mutations will change from being accepted to raising `FrozenError`, as all strings will become frozen by default, and will need to be manually refactored.
@example EnforcedStyle: always (default)
# The `always` style will always add the frozen string literal comment # to a file, regardless of the Ruby version or if `freeze` or `<<` are # called on a string literal. # bad module Bar # ... end # good # frozen_string_literal: true module Bar # ... end # good # frozen_string_literal: false module Bar # ... end
@example EnforcedStyle: never
# The `never` will enforce that the frozen string literal comment does # not exist in a file. # bad # frozen_string_literal: true module Baz # ... end # good module Baz # ... end
@example EnforcedStyle: always_true
# The `always_true` style enforces that the frozen string literal # comment is set to `true`. This is a stricter option than `always` # and forces projects to use frozen string literals. # bad # frozen_string_literal: false module Baz # ... end # bad module Baz # ... end # good # frozen_string_literal: true module Bar # ... end
Constants
- MSG_DISABLED
- MSG_MISSING
- MSG_MISSING_TRUE
- MSG_UNNECESSARY
- SHEBANG
Public Instance Methods
on_new_investigation()
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 99 def on_new_investigation return if processed_source.tokens.empty? case style when :never ensure_no_comment(processed_source) when :always_true ensure_enabled_comment(processed_source) else ensure_comment(processed_source) end end
Private Instance Methods
disabled_offense(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 176 def disabled_offense(processed_source) frozen_string_literal_comment = frozen_string_literal_comment(processed_source) add_offense(frozen_string_literal_comment.pos, message: MSG_DISABLED) do |corrector| enable_comment(corrector) end end
enable_comment(corrector)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 188 def enable_comment(corrector) comment = frozen_string_literal_comment(processed_source) corrector.replace(line_range(comment.line), FROZEN_STRING_LITERAL_ENABLED) end
ensure_comment(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 120 def ensure_comment(processed_source) return if frozen_string_literal_comment_exists? missing_offense(processed_source) end
ensure_enabled_comment(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 126 def ensure_enabled_comment(processed_source) if frozen_string_literal_specified? return if frozen_string_literals_enabled? # The comment exists, but is not enabled. disabled_offense(processed_source) else # The comment doesn't exist at all. missing_true_offense(processed_source) end end
ensure_no_comment(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 114 def ensure_no_comment(processed_source) return unless frozen_string_literal_comment_exists? unnecessary_comment_offense(processed_source) end
following_comment()
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 212 def following_comment "\n#{FROZEN_STRING_LITERAL_ENABLED}" end
frozen_string_literal_comment(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 150 def frozen_string_literal_comment(processed_source) processed_source.find_token do |token| token.text.start_with?(FROZEN_STRING_LITERAL) end end
insert_comment(corrector)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 194 def insert_comment(corrector) comment = last_special_comment(processed_source) if comment corrector.insert_after(line_range(comment.line), following_comment) else corrector.insert_before(processed_source.buffer.source_range, preceding_comment) end end
last_special_comment(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 137 def last_special_comment(processed_source) token_number = 0 if processed_source.tokens[token_number].text.start_with?(SHEBANG) token = processed_source.tokens[token_number] token_number += 1 end next_token = processed_source.tokens[token_number] token = next_token if Encoding::ENCODING_PATTERN.match?(next_token&.text) token end
line_range(line)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 204 def line_range(line) processed_source.buffer.line_range(line) end
missing_offense(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 156 def missing_offense(processed_source) range = source_range(processed_source.buffer, 0, 0) add_offense(range, message: MSG_MISSING) { |corrector| insert_comment(corrector) } end
missing_true_offense(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 162 def missing_true_offense(processed_source) range = source_range(processed_source.buffer, 0, 0) add_offense(range, message: MSG_MISSING_TRUE) { |corrector| insert_comment(corrector) } end
preceding_comment()
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 208 def preceding_comment "#{FROZEN_STRING_LITERAL_ENABLED}\n" end
remove_comment(corrector, node)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 184 def remove_comment(corrector, node) corrector.remove(range_with_surrounding_space(node.pos, side: :right)) end
unnecessary_comment_offense(processed_source)
click to toggle source
# File lib/rubocop/cop/style/frozen_string_literal_comment.rb, line 168 def unnecessary_comment_offense(processed_source) frozen_string_literal_comment = frozen_string_literal_comment(processed_source) add_offense(frozen_string_literal_comment.pos, message: MSG_UNNECESSARY) do |corrector| remove_comment(corrector, frozen_string_literal_comment) end end