From ed39d2b22d406bc1ab10b51fffe4e7a3fea06c06 Mon Sep 17 00:00:00 2001 From: Daniel Vandersluis Date: Wed, 29 Sep 2021 00:19:42 -0400 Subject: [PATCH] [Fix #10134] Update `Style/MutableConstant` to not consider multiline uninterpolated strings as unfrozen in ruby 3.0. --- .../fix_update_stylemutableconstant_to_not.md | 1 + .../cop/mixin/frozen_string_literal.rb | 6 +++- lib/rubocop/cop/style/mutable_constant.rb | 5 ++-- .../cop/style/mutable_constant_spec.rb | 28 +++++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_update_stylemutableconstant_to_not.md diff --git a/changelog/fix_update_stylemutableconstant_to_not.md b/changelog/fix_update_stylemutableconstant_to_not.md new file mode 100644 index 00000000000..ba18e164c0d --- /dev/null +++ b/changelog/fix_update_stylemutableconstant_to_not.md @@ -0,0 +1 @@ +* [#10134](https://github.com/rubocop/rubocop/issues/10134): Update `Style/MutableConstant` to not consider multiline uninterpolated strings as unfrozen in ruby 3.0. ([@dvandersluis][]) diff --git a/lib/rubocop/cop/mixin/frozen_string_literal.rb b/lib/rubocop/cop/mixin/frozen_string_literal.rb index 56b93a328dd..6f58a9adf57 100644 --- a/lib/rubocop/cop/mixin/frozen_string_literal.rb +++ b/lib/rubocop/cop/mixin/frozen_string_literal.rb @@ -20,7 +20,7 @@ def frozen_string_literal_comment_exists? def frozen_string_literal?(node) frozen_string = if target_ruby_version >= 3.0 - node.str_type? || frozen_heredoc?(node) + uninterpolated_string?(node) || frozen_heredoc?(node) else FROZEN_STRING_LITERAL_TYPES_RUBY27.include?(node.type) end @@ -28,6 +28,10 @@ def frozen_string_literal?(node) frozen_string && frozen_string_literals_enabled? end + def uninterpolated_string?(node) + node.str_type? || (node.dstr_type? && node.each_descendant(:begin).none?) + end + def frozen_heredoc?(node) return false unless node.dstr_type? && node.heredoc? diff --git a/lib/rubocop/cop/style/mutable_constant.rb b/lib/rubocop/cop/style/mutable_constant.rb index fd16a40285f..6382eb8a875 100644 --- a/lib/rubocop/cop/style/mutable_constant.rb +++ b/lib/rubocop/cop/style/mutable_constant.rb @@ -21,8 +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. + # NOTE: From Ruby 3.0, interpolated strings are not frozen when + # `# frozen-string-literal: true` is used, so this cop enforces explicit + # freezing for such strings. # # NOTE: From Ruby 3.0, this cop allows explicit freezing of constants when # the `shareable_constant_value` directive is used. diff --git a/spec/rubocop/cop/style/mutable_constant_spec.rb b/spec/rubocop/cop/style/mutable_constant_spec.rb index 04151a41711..b65a5c7cdaa 100644 --- a/spec/rubocop/cop/style/mutable_constant_spec.rb +++ b/spec/rubocop/cop/style/mutable_constant_spec.rb @@ -132,6 +132,25 @@ HERE RUBY end + + it 'does not register an offense when using a multiline string' do + expect_no_offenses(<<~RUBY) + # frozen_string_literal: true + + CONST = 'foo' \ + 'bar' + RUBY + end + + it 'registers an offense when using a multiline string with interpolation' do + expect_offense(<<~'RUBY') + # frozen_string_literal: true + + CONST = "#{foo}" \ + ^^^^^^^^^^ Freeze mutable objects assigned to constants. + 'bar' + RUBY + end end context 'when the frozen string literal comment is false' do @@ -166,6 +185,15 @@ HERE RUBY end + + it 'does not register an offense when using a multiline string' do + expect_no_offenses(<<~RUBY) + # frozen_string_literal: true + + CONST = 'foo' \ + 'bar' + RUBY + end end context 'when the frozen string literal comment is false' do