Skip to content

Commit

Permalink
[Fix rubocop#3366] Make Style/MutableConstant cop aware of splat as…
Browse files Browse the repository at this point in the history
…signments (rubocop#3367)

This cop would generate false positives on code like:

```
FOO = *(1...10)
```

and:

```
BAR = *[1...10].freeze
```

This change fixes that.
  • Loading branch information
Drenmi authored and Neodelf committed Oct 15, 2016
1 parent 0d048ac commit 1aae481
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* [#3351](https://github.com/bbatsov/rubocop/issues/3351): Fix bad auto-correct for `Performance/RedundantMatch` cop. ([@annaswims][])
* [#3347](https://github.com/bbatsov/rubocop/issues/3347): Prevent infinite loop in `Style/TernaryParentheses` cop when used together with `Style/RedundantParentheses`. ([@drenmi][])
* [#3209](https://github.com/bbatsov/rubocop/issues/3209): Remove faulty line length check from `Style/GuardClause` cop. ([@drenmi][])
* [#3366](https://github.com/bbatsov/rubocop/issues/3366): Make `Style/MutableConstant` cop aware of splat assignments. ([@drenmi][])

### Changes

Expand Down
28 changes: 17 additions & 11 deletions lib/rubocop/cop/style/mutable_constant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ module Style
# # good
# CONST = [1, 2, 3].freeze
class MutableConstant < Cop
MSG = 'Freeze mutable objects assigned to constants.'.freeze

include FrozenStringLiteral

MSG = 'Freeze mutable objects assigned to constants.'.freeze

def on_casgn(node)
_scope, _const_name, value = *node
on_assignment(value)
Expand All @@ -31,6 +31,18 @@ def on_or_asgn(node)
on_assignment(value)
end

private

def on_assignment(value)
value = splat_value(value) if splat_value(value)

return unless value && value.mutable_literal?
return if FROZEN_STRING_LITERAL_TYPES.include?(value.type) &&
frozen_string_literals_enabled?(processed_source)

add_offense(value, :expression)
end

def autocorrect(node)
expr = node.source_range
lambda do |corrector|
Expand All @@ -43,15 +55,9 @@ def autocorrect(node)
end
end

private

def on_assignment(value)
return unless value && value.mutable_literal?
return if FROZEN_STRING_LITERAL_TYPES.include?(value.type) &&
frozen_string_literals_enabled?(processed_source)

add_offense(value, :expression)
end
def_node_matcher :splat_value, <<-PATTERN
(array (splat $_))
PATTERN
end
end
end
Expand Down
23 changes: 23 additions & 0 deletions spec/rubocop/cop/style/mutable_constant_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,29 @@
expect(cop.offenses).to be_empty
end

context 'when performing a splat assignment' do
it 'allows an immutable value' do
inspect_source(cop, 'FOO = *(1...10)')
expect(cop.offenses).to be_empty
end

it 'allows a frozen array value' do
inspect_source(cop, 'FOO = *[1...10].freeze')
expect(cop.offenses).to be_empty
end

it 'registers an offense for a mutable value' do
source = 'BAR = *[1, 2, 3]'

inspect_source(cop, source)
expect(cop.offenses.size).to eq(1)

corrected = autocorrect_source(cop, source)

expect(corrected).to eq('BAR = *[1, 2, 3].freeze')
end
end

context 'when assigning an array without brackets' do
it 'adds brackets when auto-correcting' do
new_source = autocorrect_source(cop, 'XXX = YYY, ZZZ')
Expand Down

0 comments on commit 1aae481

Please sign in to comment.