Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #10070] Fix a false positive for Style/MutableConstant #10071

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/fix_false_positive_for_style_mutable_constant.md
@@ -0,0 +1 @@
* [#10070](https://github.com/rubocop/rubocop/issues/10070): Fix a false positive for `Style/MutableConstant` when using non-interpolated heredoc in Ruby 3.0. ([@koic][])
17 changes: 11 additions & 6 deletions lib/rubocop/cop/mixin/frozen_string_literal.rb
Expand Up @@ -9,9 +9,8 @@ module FrozenStringLiteral
FROZEN_STRING_LITERAL = '# frozen_string_literal:'
FROZEN_STRING_LITERAL_ENABLED = '# frozen_string_literal: true'
FROZEN_STRING_LITERAL_TYPES_RUBY27 = %i[str dstr].freeze
FROZEN_STRING_LITERAL_TYPES_RUBY30 = %i[str].freeze

private_constant :FROZEN_STRING_LITERAL_TYPES_RUBY27, :FROZEN_STRING_LITERAL_TYPES_RUBY30
private_constant :FROZEN_STRING_LITERAL_TYPES_RUBY27

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

def frozen_string_literal?(node)
literal_types = if target_ruby_version >= 3.0
FROZEN_STRING_LITERAL_TYPES_RUBY30
frozen_string = if target_ruby_version >= 3.0
node.str_type? || frozen_heredoc?(node)
else
FROZEN_STRING_LITERAL_TYPES_RUBY27
FROZEN_STRING_LITERAL_TYPES_RUBY27.include?(node.type)
end

literal_types.include?(node.type) && frozen_string_literals_enabled?
frozen_string && frozen_string_literals_enabled?
end

def frozen_heredoc?(node)
return false unless node.dstr_type? && node.heredoc?

node.children.all?(&:str_type?)
end

def frozen_string_literals_enabled?
Expand Down
33 changes: 33 additions & 0 deletions spec/rubocop/cop/style/mutable_constant_spec.rb
Expand Up @@ -115,6 +115,23 @@
let(:prefix) { '# frozen_string_literal: true' }

it_behaves_like 'mutable objects', '"#{a}"'
it_behaves_like 'immutable objects', <<~'RUBY'
<<~HERE
foo
bar
HERE
RUBY
it 'registers an offense when using interpolated heredoc constant' do
expect_offense(<<~'RUBY')
# frozen_string_literal: true

CONST = <<~HERE
^^^^^^^ Freeze mutable objects assigned to constants.
foo #{use_interpolation}
bar
HERE
RUBY
end
end

context 'when the frozen string literal comment is false' do
Expand All @@ -133,6 +150,22 @@
let(:prefix) { '# frozen_string_literal: true' }

it_behaves_like 'immutable objects', '"#{a}"'
it_behaves_like 'immutable objects', <<~'RUBY'
<<~HERE
foo
bar
HERE
RUBY
it 'does not register an offense when using interpolated heredoc constant' do
expect_no_offenses(<<~'RUBY')
# frozen_string_literal: true

CONST = <<~HERE
foo #{use_interpolation}
bar
HERE
RUBY
end
end

context 'when the frozen string literal comment is false' do
Expand Down