-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new
Style/RedundantArrayConstructor
cop
Follow up #11874 (comment). Checks for the instantiation of array using redundant `Array` constructor. Autocorrect replaces to array literal which is the simplest and fastest. ```ruby # bad Array.new([]) Array[] Array([]) Array.new(['foo', 'foo', 'foo']) Array['foo', 'foo', 'foo'] Array(['foo', 'foo', 'foo']) # good [] ['foo', 'foo', 'foo'] Array.new(3, 'foo') Array.new(3) { 'foo' } ```
- Loading branch information
Showing
5 changed files
with
205 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* [#11886](https://github.com/rubocop/rubocop/pull/11886): Add new `Style/RedundantArrayConstructor` cop. ([@koic][]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Style | ||
# Checks for the instantiation of array using redundant `Array` constructor. | ||
# Autocorrect replaces to array literal which is the simplest and fastest. | ||
# | ||
# @example | ||
# | ||
# # bad | ||
# Array.new([]) | ||
# Array[] | ||
# Array([]) | ||
# Array.new(['foo', 'foo', 'foo']) | ||
# Array['foo', 'foo', 'foo'] | ||
# Array(['foo', 'foo', 'foo']) | ||
# | ||
# # good | ||
# [] | ||
# ['foo', 'foo', 'foo'] | ||
# Array.new(3, 'foo') | ||
# Array.new(3) { 'foo' } | ||
# | ||
class RedundantArrayConstructor < Base | ||
extend AutoCorrector | ||
|
||
MSG = 'Remove the redundant `Array` constructor.' | ||
|
||
RESTRICT_ON_SEND = %i[new [] Array].freeze | ||
|
||
# @!method redundant_array_constructor(node) | ||
def_node_matcher :redundant_array_constructor, <<~PATTERN | ||
{ | ||
(send | ||
(const {nil? cbase} :Array) :new | ||
$(array ...)) | ||
(send | ||
(const {nil? cbase} :Array) :[] | ||
$...) | ||
(send | ||
nil? :Array | ||
$(array ...)) | ||
} | ||
PATTERN | ||
|
||
def on_send(node) | ||
return unless (array_literal = redundant_array_constructor(node)) | ||
|
||
receiver = node.receiver | ||
selector = node.loc.selector | ||
|
||
if node.method?(:new) | ||
range = receiver.source_range.join(selector) | ||
replacement = array_literal | ||
elsif node.method?(:Array) | ||
range = selector | ||
replacement = array_literal | ||
else | ||
range = receiver | ||
replacement = selector.begin.join(node.source_range.end) | ||
end | ||
|
||
register_offense(range, node, replacement) | ||
end | ||
|
||
private | ||
|
||
def register_offense(range, node, replacement) | ||
add_offense(range) do |corrector| | ||
corrector.replace(node, replacement.source) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
121 changes: 121 additions & 0 deletions
121
spec/rubocop/cop/style/redundant_array_constructor_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Style::RedundantArrayConstructor, :config do | ||
it 'registers an offense when using an empty array literal argument for `Array.new`' do | ||
expect_offense(<<~RUBY) | ||
Array.new([]) | ||
^^^^^^^^^ Remove the redundant `Array` constructor. | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
[] | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when using an empty array literal argument for `::Array.new`' do | ||
expect_offense(<<~RUBY) | ||
::Array.new([]) | ||
^^^^^^^^^^^ Remove the redundant `Array` constructor. | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
[] | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when using an empty array literal argument for `Array[]`' do | ||
expect_offense(<<~RUBY) | ||
Array[] | ||
^^^^^ Remove the redundant `Array` constructor. | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
[] | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when using an empty array literal argument for `::Array[]`' do | ||
expect_offense(<<~RUBY) | ||
::Array[] | ||
^^^^^^^ Remove the redundant `Array` constructor. | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
[] | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when using an empty array literal argument for `Array([])`' do | ||
expect_offense(<<~RUBY) | ||
Array([]) | ||
^^^^^ Remove the redundant `Array` constructor. | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
[] | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when using an array literal with some elements as an argument for `Array.new`' do | ||
expect_offense(<<~RUBY) | ||
Array.new(['foo', 'bar', 'baz']) | ||
^^^^^^^^^ Remove the redundant `Array` constructor. | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
['foo', 'bar', 'baz'] | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when using an array literal with some elements as an argument for `Array[]`' do | ||
expect_offense(<<~RUBY) | ||
Array['foo', 'bar', 'baz'] | ||
^^^^^ Remove the redundant `Array` constructor. | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
['foo', 'bar', 'baz'] | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when using an array literal with some elements as an argument for `Array([])`' do | ||
expect_offense(<<~RUBY) | ||
Array(['foo', 'bar', 'baz']) | ||
^^^^^ Remove the redundant `Array` constructor. | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
['foo', 'bar', 'baz'] | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using an array literal' do | ||
expect_no_offenses(<<~RUBY) | ||
[] | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using single argument for `Array.new`' do | ||
expect_no_offenses(<<~RUBY) | ||
Array.new(array) | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using single argument for `Array()`' do | ||
expect_no_offenses(<<~RUBY) | ||
Array(array) | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using two argument for `Array.new`' do | ||
expect_no_offenses(<<~RUBY) | ||
Array.new(3, 'foo') | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using block argument for `Array.new`' do | ||
expect_no_offenses(<<~RUBY) | ||
Array.new(3) { 'foo' } | ||
RUBY | ||
end | ||
end |