Skip to content

Commit

Permalink
Interpolated string literals are no longer frozen
Browse files Browse the repository at this point in the history
Since Ruby 3.0 or higher interpolated strings are not frozen
automatically anymore.

Therefore, two changes must happen to how we treat interpolated literals

* Style/MutableConstant should enforce freezing them
* Style/RedundantFreeze should not consider it redundant to freeze them

Strongly inspired by #8743
  • Loading branch information
splattael committed Aug 23, 2021
1 parent d8cae21 commit c537fc2
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 21 deletions.
1 change: 1 addition & 0 deletions changelog/change_interpolated_string_literals_are_no.md
@@ -0,0 +1 @@
* [#10006](https://github.com/rubocop/rubocop/pull/10006): Interpolated string literals are no longer frozen since Ruby 3.0. ([@splattael][])
13 changes: 10 additions & 3 deletions lib/rubocop/cop/mixin/frozen_string_literal.rb
Expand Up @@ -8,9 +8,10 @@ module FrozenStringLiteral

FROZEN_STRING_LITERAL = '# frozen_string_literal:'
FROZEN_STRING_LITERAL_ENABLED = '# frozen_string_literal: true'
FROZEN_STRING_LITERAL_TYPES = %i[str dstr].freeze
FROZEN_STRING_LITERAL_TYPES_RUBY27 = %i[str dstr].freeze
FROZEN_STRING_LITERAL_TYPES_RUBY30 = %i[str].freeze

private_constant :FROZEN_STRING_LITERAL_TYPES
private_constant :FROZEN_STRING_LITERAL_TYPES_RUBY27, :FROZEN_STRING_LITERAL_TYPES_RUBY30

def frozen_string_literal_comment_exists?
leading_comment_lines.any? { |line| MagicComment.parse(line).valid_literal_value? }
Expand All @@ -19,7 +20,13 @@ def frozen_string_literal_comment_exists?
private

def frozen_string_literal?(node)
FROZEN_STRING_LITERAL_TYPES.include?(node.type) && frozen_string_literals_enabled?
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 frozen_string_literals_enabled?
Expand Down
3 changes: 3 additions & 0 deletions lib/rubocop/cop/style/mutable_constant.rb
Expand Up @@ -21,6 +21,9 @@ module Style
#
# NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
#
# NOTE: From Ruby 3.0, this cop allows explicit freezing of interpolated
# string literals when `# frozen-string-literal: true` is used.
#
# @example EnforcedStyle: literals (default)
# # bad
# CONST = [1, 2, 3]
Expand Down
3 changes: 3 additions & 0 deletions lib/rubocop/cop/style/redundant_freeze.rb
Expand Up @@ -7,6 +7,9 @@ module Style
#
# NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
#
# NOTE: From Ruby 3.0, this cop allows explicit freezing of interpolated
# string literals when `# frozen-string-literal: true` is used.
#
# @example
# # bad
# CONST = 1.freeze
Expand Down
38 changes: 29 additions & 9 deletions spec/rubocop/cop/style/mutable_constant_spec.rb
Expand Up @@ -106,20 +106,40 @@
end
end

context 'when the frozen string literal comment is missing' do
it_behaves_like 'mutable objects', '"#{a}"'
end
context 'Ruby 3.0 or higher', :ruby30 do
context 'when the frozen string literal comment is missing' do
it_behaves_like 'mutable objects', '"#{a}"'
end

context 'when the frozen string literal comment is true' do
let(:prefix) { '# frozen_string_literal: true' }
context 'when the frozen string literal comment is true' do
let(:prefix) { '# frozen_string_literal: true' }

it_behaves_like 'immutable objects', '"#{a}"'
it_behaves_like 'mutable objects', '"#{a}"'
end

context 'when the frozen string literal comment is false' do
let(:prefix) { '# frozen_string_literal: false' }

it_behaves_like 'mutable objects', '"#{a}"'
end
end

context 'when the frozen string literal comment is false' do
let(:prefix) { '# frozen_string_literal: false' }
context 'Ruby 2.7 or lower', :ruby27 do
context 'when the frozen string literal comment is missing' do
it_behaves_like 'mutable objects', '"#{a}"'
end

it_behaves_like 'mutable objects', '"#{a}"'
context 'when the frozen string literal comment is true' do
let(:prefix) { '# frozen_string_literal: true' }

it_behaves_like 'immutable objects', '"#{a}"'
end

context 'when the frozen string literal comment is false' do
let(:prefix) { '# frozen_string_literal: false' }

it_behaves_like 'mutable objects', '"#{a}"'
end
end
end

Expand Down
38 changes: 29 additions & 9 deletions spec/rubocop/cop/style/redundant_freeze_spec.rb
Expand Up @@ -75,20 +75,40 @@
end
end

context 'when the frozen string literal comment is missing' do
it_behaves_like 'mutable objects', '"#{a}"'
end
context 'Ruby 3.0 or higher', :ruby30 do
context 'when the frozen string literal comment is missing' do
it_behaves_like 'mutable objects', '"#{a}"'
end

context 'when the frozen string literal comment is true' do
let(:prefix) { '# frozen_string_literal: true' }

context 'when the frozen string literal comment is true' do
let(:prefix) { '# frozen_string_literal: true' }
it_behaves_like 'mutable objects', '"#{a}"'
end

context 'when the frozen string literal comment is false' do
let(:prefix) { '# frozen_string_literal: false' }

it_behaves_like 'immutable objects', '"#{a}"'
it_behaves_like 'mutable objects', '"#{a}"'
end
end

context 'when the frozen string literal comment is false' do
let(:prefix) { '# frozen_string_literal: false' }
context 'Ruby 2.7 or lower', :ruby27 do
context 'when the frozen string literal comment is missing' do
it_behaves_like 'mutable objects', '"#{a}"'
end

context 'when the frozen string literal comment is true' do
let(:prefix) { '# frozen_string_literal: true' }

it_behaves_like 'immutable objects', '"#{a}"'
end

context 'when the frozen string literal comment is false' do
let(:prefix) { '# frozen_string_literal: false' }

it_behaves_like 'mutable objects', '"#{a}"'
it_behaves_like 'mutable objects', '"#{a}"'
end
end

describe 'Regexp and Range literals' do
Expand Down

0 comments on commit c537fc2

Please sign in to comment.