rubocop-rails 2.4.2 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +5 -1
- data/config/default.yml +179 -9
- data/lib/rubocop-rails.rb +3 -0
- data/lib/rubocop/cop/mixin/active_record_helper.rb +84 -0
- data/lib/rubocop/cop/mixin/index_method.rb +161 -0
- data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +145 -0
- data/lib/rubocop/cop/rails/content_tag.rb +69 -0
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +1 -3
- data/lib/rubocop/cop/rails/default_scope.rb +54 -0
- data/lib/rubocop/cop/rails/delegate.rb +2 -4
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +40 -15
- data/lib/rubocop/cop/rails/environment_comparison.rb +60 -14
- data/lib/rubocop/cop/rails/exit.rb +2 -2
- data/lib/rubocop/cop/rails/file_path.rb +2 -1
- data/lib/rubocop/cop/rails/find_by_id.rb +103 -0
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +2 -2
- data/lib/rubocop/cop/rails/http_status.rb +2 -0
- data/lib/rubocop/cop/rails/index_by.rb +56 -0
- data/lib/rubocop/cop/rails/index_with.rb +59 -0
- data/lib/rubocop/cop/rails/inquiry.rb +34 -0
- data/lib/rubocop/cop/rails/inverse_of.rb +0 -4
- data/lib/rubocop/cop/rails/link_to_blank.rb +3 -3
- data/lib/rubocop/cop/rails/mailer_name.rb +80 -0
- data/lib/rubocop/cop/rails/match_route.rb +117 -0
- data/lib/rubocop/cop/rails/negate_include.rb +39 -0
- data/lib/rubocop/cop/rails/pick.rb +55 -0
- data/lib/rubocop/cop/rails/pluck.rb +59 -0
- data/lib/rubocop/cop/rails/pluck_id.rb +58 -0
- data/lib/rubocop/cop/rails/pluck_in_where.rb +36 -0
- data/lib/rubocop/cop/rails/presence.rb +2 -6
- data/lib/rubocop/cop/rails/rake_environment.rb +17 -0
- data/lib/rubocop/cop/rails/redundant_foreign_key.rb +80 -0
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -3
- data/lib/rubocop/cop/rails/refute_methods.rb +52 -26
- data/lib/rubocop/cop/rails/render_inline.rb +48 -0
- data/lib/rubocop/cop/rails/render_plain_text.rb +76 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +6 -1
- data/lib/rubocop/cop/rails/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/rails/save_bang.rb +6 -7
- data/lib/rubocop/cop/rails/short_i18n.rb +76 -0
- data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -8
- data/lib/rubocop/cop/rails/time_zone.rb +1 -3
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +12 -12
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +155 -0
- data/lib/rubocop/cop/rails/unknown_env.rb +7 -6
- data/lib/rubocop/cop/rails/where_exists.rb +68 -0
- data/lib/rubocop/cop/rails_cops.rb +22 -0
- data/lib/rubocop/rails/schema_loader.rb +61 -0
- data/lib/rubocop/rails/schema_loader/schema.rb +190 -0
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +46 -8
@@ -10,37 +10,41 @@ module RuboCop
|
|
10
10
|
# @example
|
11
11
|
# # bad
|
12
12
|
# User.find_by_name(name)
|
13
|
-
#
|
14
|
-
# # bad
|
15
13
|
# User.find_by_name_and_email(name)
|
16
|
-
#
|
17
|
-
# # bad
|
18
14
|
# User.find_by_email!(name)
|
19
15
|
#
|
20
16
|
# # good
|
21
17
|
# User.find_by(name: name)
|
18
|
+
# User.find_by(name: name, email: email)
|
19
|
+
# User.find_by!(email: email)
|
20
|
+
#
|
21
|
+
# @example AllowedMethods: find_by_sql
|
22
|
+
# # bad
|
23
|
+
# User.find_by_query(users_query)
|
22
24
|
#
|
23
25
|
# # good
|
24
|
-
# User.
|
26
|
+
# User.find_by_sql(users_sql)
|
27
|
+
#
|
28
|
+
# @example AllowedReceivers: Gem::Specification
|
29
|
+
# # bad
|
30
|
+
# Specification.find_by_name('backend').gem_dir
|
25
31
|
#
|
26
32
|
# # good
|
27
|
-
#
|
33
|
+
# Gem::Specification.find_by_name('backend').gem_dir
|
28
34
|
class DynamicFindBy < Cop
|
29
35
|
MSG = 'Use `%<static_name>s` instead of dynamic `%<method>s`.'
|
30
36
|
METHOD_PATTERN = /^find_by_(.+?)(!)?$/.freeze
|
31
37
|
|
32
38
|
def on_send(node)
|
33
|
-
|
34
|
-
|
35
|
-
return if whitelist.include?(method_name)
|
39
|
+
return if allowed_invocation?(node)
|
36
40
|
|
41
|
+
method_name = node.method_name
|
37
42
|
static_name = static_method_name(method_name)
|
38
|
-
|
39
43
|
return unless static_name
|
40
44
|
|
41
45
|
add_offense(node,
|
42
46
|
message: format(MSG, static_name: static_name,
|
43
|
-
method:
|
47
|
+
method: method_name))
|
44
48
|
end
|
45
49
|
alias on_csend on_send
|
46
50
|
|
@@ -57,6 +61,31 @@ module RuboCop
|
|
57
61
|
|
58
62
|
private
|
59
63
|
|
64
|
+
def allowed_invocation?(node)
|
65
|
+
allowed_method?(node) || allowed_receiver?(node) ||
|
66
|
+
whitelisted?(node)
|
67
|
+
end
|
68
|
+
|
69
|
+
def allowed_method?(node)
|
70
|
+
return unless cop_config['AllowedMethods']
|
71
|
+
|
72
|
+
cop_config['AllowedMethods'].include?(node.method_name.to_s)
|
73
|
+
end
|
74
|
+
|
75
|
+
def allowed_receiver?(node)
|
76
|
+
return unless cop_config['AllowedReceivers'] && node.receiver
|
77
|
+
|
78
|
+
cop_config['AllowedReceivers'].include?(node.receiver.source)
|
79
|
+
end
|
80
|
+
|
81
|
+
# config option `WhiteList` will be deprecated soon
|
82
|
+
def whitelisted?(node)
|
83
|
+
whitelist_config = cop_config['Whitelist']
|
84
|
+
return unless whitelist_config
|
85
|
+
|
86
|
+
whitelist_config.include?(node.method_name.to_s)
|
87
|
+
end
|
88
|
+
|
60
89
|
def autocorrect_method_name(corrector, node)
|
61
90
|
corrector.replace(node.loc.selector,
|
62
91
|
static_method_name(node.method_name.to_s))
|
@@ -68,10 +97,6 @@ module RuboCop
|
|
68
97
|
end
|
69
98
|
end
|
70
99
|
|
71
|
-
def whitelist
|
72
|
-
cop_config['Whitelist']
|
73
|
-
end
|
74
|
-
|
75
100
|
def column_keywords(method)
|
76
101
|
keyword_string = method.to_s[METHOD_PATTERN, 1]
|
77
102
|
keyword_string.split('_and_').map { |keyword| "#{keyword}: " }
|
@@ -16,52 +16,98 @@ module RuboCop
|
|
16
16
|
# # good
|
17
17
|
# Rails.env.production?
|
18
18
|
class EnvironmentComparison < Cop
|
19
|
-
MSG =
|
19
|
+
MSG = 'Favor `%<bang>sRails.env.%<env>s?` over `%<source>s`.'
|
20
20
|
|
21
21
|
SYM_MSG = 'Do not compare `Rails.env` with a symbol, it will always ' \
|
22
22
|
'evaluate to `false`.'
|
23
23
|
|
24
|
-
def_node_matcher :
|
24
|
+
def_node_matcher :comparing_str_env_with_rails_env_on_lhs?, <<~PATTERN
|
25
25
|
(send
|
26
26
|
(send (const {nil? cbase} :Rails) :env)
|
27
|
-
:==
|
27
|
+
{:== :!=}
|
28
28
|
$str
|
29
29
|
)
|
30
30
|
PATTERN
|
31
31
|
|
32
|
-
def_node_matcher :
|
32
|
+
def_node_matcher :comparing_str_env_with_rails_env_on_rhs?, <<~PATTERN
|
33
|
+
(send
|
34
|
+
$str
|
35
|
+
{:== :!=}
|
36
|
+
(send (const {nil? cbase} :Rails) :env)
|
37
|
+
)
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
def_node_matcher :comparing_sym_env_with_rails_env_on_lhs?, <<~PATTERN
|
33
41
|
(send
|
34
42
|
(send (const {nil? cbase} :Rails) :env)
|
35
|
-
:==
|
43
|
+
{:== :!=}
|
36
44
|
$sym
|
37
45
|
)
|
38
46
|
PATTERN
|
39
47
|
|
48
|
+
def_node_matcher :comparing_sym_env_with_rails_env_on_rhs?, <<~PATTERN
|
49
|
+
(send
|
50
|
+
$sym
|
51
|
+
{:== :!=}
|
52
|
+
(send (const {nil? cbase} :Rails) :env)
|
53
|
+
)
|
54
|
+
PATTERN
|
55
|
+
|
56
|
+
def_node_matcher :content, <<~PATTERN
|
57
|
+
({str sym} $_)
|
58
|
+
PATTERN
|
59
|
+
|
40
60
|
def on_send(node)
|
41
|
-
|
61
|
+
if (env_node = comparing_str_env_with_rails_env_on_lhs?(node) ||
|
62
|
+
comparing_str_env_with_rails_env_on_rhs?(node))
|
42
63
|
env, = *env_node
|
43
|
-
|
64
|
+
bang = node.method?(:!=) ? '!' : ''
|
65
|
+
|
66
|
+
add_offense(node, message: format(
|
67
|
+
MSG, bang: bang, env: env, source: node.source
|
68
|
+
))
|
44
69
|
end
|
45
|
-
|
70
|
+
|
71
|
+
if comparing_sym_env_with_rails_env_on_lhs?(node) ||
|
72
|
+
comparing_sym_env_with_rails_env_on_rhs?(node)
|
46
73
|
add_offense(node, message: SYM_MSG)
|
47
74
|
end
|
48
75
|
end
|
49
76
|
|
50
77
|
def autocorrect(node)
|
51
78
|
lambda do |corrector|
|
52
|
-
|
79
|
+
replacement = build_predicate_method(node)
|
80
|
+
|
81
|
+
corrector.replace(node.source_range, replacement)
|
53
82
|
end
|
54
83
|
end
|
55
84
|
|
56
85
|
private
|
57
86
|
|
58
|
-
def
|
59
|
-
|
87
|
+
def build_predicate_method(node)
|
88
|
+
if rails_env_on_lhs?(node)
|
89
|
+
build_predicate_method_for_rails_env_on_lhs(node)
|
90
|
+
else
|
91
|
+
build_predicate_method_for_rails_env_on_rhs(node)
|
92
|
+
end
|
60
93
|
end
|
61
94
|
|
62
|
-
|
63
|
-
(
|
64
|
-
|
95
|
+
def rails_env_on_lhs?(node)
|
96
|
+
comparing_str_env_with_rails_env_on_lhs?(node) ||
|
97
|
+
comparing_sym_env_with_rails_env_on_lhs?(node)
|
98
|
+
end
|
99
|
+
|
100
|
+
def build_predicate_method_for_rails_env_on_lhs(node)
|
101
|
+
bang = node.method?(:!=) ? '!' : ''
|
102
|
+
|
103
|
+
"#{bang}#{node.receiver.source}.#{content(node.first_argument)}?"
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_predicate_method_for_rails_env_on_rhs(node)
|
107
|
+
bang = node.method?(:!=) ? '!' : ''
|
108
|
+
|
109
|
+
"#{bang}#{node.first_argument.source}.#{content(node.receiver)}?"
|
110
|
+
end
|
65
111
|
end
|
66
112
|
end
|
67
113
|
end
|
@@ -9,11 +9,11 @@ module RuboCop
|
|
9
9
|
#
|
10
10
|
# There are two obvious cases where `exit` is particularly harmful:
|
11
11
|
#
|
12
|
-
#
|
12
|
+
# * Usage in library code for your application. Even though Rails will
|
13
13
|
# rescue from a `SystemExit` and continue on, unit testing that library
|
14
14
|
# code will result in specs exiting (potentially silently if `exit(0)`
|
15
15
|
# is used.)
|
16
|
-
#
|
16
|
+
# * Usage in application code outside of the web process could result in
|
17
17
|
# the program exiting, which could result in the code failing to run and
|
18
18
|
# do its job.
|
19
19
|
#
|
@@ -48,6 +48,7 @@ module RuboCop
|
|
48
48
|
|
49
49
|
def on_dstr(node)
|
50
50
|
return unless rails_root_nodes?(node)
|
51
|
+
return unless node.children.last.str_type?
|
51
52
|
return unless node.children.last.source.start_with?('.') ||
|
52
53
|
node.children.last.source.include?(File::SEPARATOR)
|
53
54
|
|
@@ -89,7 +90,7 @@ module RuboCop
|
|
89
90
|
end
|
90
91
|
|
91
92
|
def string_with_slash?(node)
|
92
|
-
node.str_type? && node.source
|
93
|
+
node.str_type? && node.source.match?(%r{/})
|
93
94
|
end
|
94
95
|
|
95
96
|
def register_offense(node)
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# This cop enforces that `ActiveRecord#find` is used instead of
|
7
|
+
# `where.take!`, `find_by!`, and `find_by_id!` to retrieve a single record
|
8
|
+
# by primary key when you expect it to be found.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# User.where(id: id).take!
|
13
|
+
# User.find_by_id!(id)
|
14
|
+
# User.find_by!(id: id)
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# User.find(id)
|
18
|
+
#
|
19
|
+
class FindById < Cop
|
20
|
+
include RangeHelp
|
21
|
+
|
22
|
+
MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
|
23
|
+
|
24
|
+
def_node_matcher :where_take?, <<~PATTERN
|
25
|
+
(send
|
26
|
+
$(send _ :where
|
27
|
+
(hash
|
28
|
+
(pair (sym :id) $_))) :take!)
|
29
|
+
PATTERN
|
30
|
+
|
31
|
+
def_node_matcher :find_by?, <<~PATTERN
|
32
|
+
{
|
33
|
+
(send _ :find_by_id! $_)
|
34
|
+
(send _ :find_by! (hash (pair (sym :id) $_)))
|
35
|
+
}
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
def on_send(node)
|
39
|
+
where_take?(node) do |where, id_value|
|
40
|
+
range = where_take_offense_range(node, where)
|
41
|
+
|
42
|
+
good_method = build_good_method(id_value)
|
43
|
+
bad_method = build_where_take_bad_method(id_value)
|
44
|
+
message = format(MSG, good_method: good_method, bad_method: bad_method)
|
45
|
+
|
46
|
+
add_offense(node, location: range, message: message)
|
47
|
+
end
|
48
|
+
|
49
|
+
find_by?(node) do |id_value|
|
50
|
+
range = find_by_offense_range(node)
|
51
|
+
|
52
|
+
good_method = build_good_method(id_value)
|
53
|
+
bad_method = build_find_by_bad_method(node, id_value)
|
54
|
+
message = format(MSG, good_method: good_method, bad_method: bad_method)
|
55
|
+
|
56
|
+
add_offense(node, location: range, message: message)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def autocorrect(node)
|
61
|
+
if (matches = where_take?(node))
|
62
|
+
where, id_value = *matches
|
63
|
+
range = where_take_offense_range(node, where)
|
64
|
+
elsif (id_value = find_by?(node))
|
65
|
+
range = find_by_offense_range(node)
|
66
|
+
end
|
67
|
+
|
68
|
+
lambda do |corrector|
|
69
|
+
replacement = build_good_method(id_value)
|
70
|
+
corrector.replace(range, replacement)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def where_take_offense_range(node, where)
|
77
|
+
range_between(where.loc.selector.begin_pos, node.loc.expression.end_pos)
|
78
|
+
end
|
79
|
+
|
80
|
+
def find_by_offense_range(node)
|
81
|
+
range_between(node.loc.selector.begin_pos, node.loc.expression.end_pos)
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_good_method(id_value)
|
85
|
+
"find(#{id_value.source})"
|
86
|
+
end
|
87
|
+
|
88
|
+
def build_where_take_bad_method(id_value)
|
89
|
+
"where(id: #{id_value.source}).take!"
|
90
|
+
end
|
91
|
+
|
92
|
+
def build_find_by_bad_method(node, id_value)
|
93
|
+
case node.method_name
|
94
|
+
when :find_by_id!
|
95
|
+
"find_by_id!(#{id_value.source})"
|
96
|
+
when :find_by!
|
97
|
+
"find_by!(id: #{id_value.source})"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
# change them to use keyword args. This cop only applies to Rails >= 5.
|
9
9
|
# If you are running Rails < 5 you should disable the
|
10
10
|
# Rails/HttpPositionalArguments cop or set your TargetRailsVersion in your
|
11
|
-
# .rubocop.yml file to 4.
|
11
|
+
# .rubocop.yml file to 4.2.
|
12
12
|
#
|
13
13
|
# @example
|
14
14
|
# # bad
|
@@ -22,7 +22,7 @@ module RuboCop
|
|
22
22
|
MSG = 'Use keyword arguments instead of ' \
|
23
23
|
'positional arguments for http call: `%<verb>s`.'
|
24
24
|
KEYWORD_ARGS = %i[
|
25
|
-
method params session body flash xhr as headers env
|
25
|
+
method params session body flash xhr as headers env to
|
26
26
|
].freeze
|
27
27
|
HTTP_METHODS = %i[get post put patch delete head].freeze
|
28
28
|
|
@@ -83,6 +83,7 @@ module RuboCop
|
|
83
83
|
'to define HTTP status code.'
|
84
84
|
|
85
85
|
attr_reader :node
|
86
|
+
|
86
87
|
def initialize(node)
|
87
88
|
@node = node
|
88
89
|
end
|
@@ -124,6 +125,7 @@ module RuboCop
|
|
124
125
|
PERMITTED_STATUS = %i[error success missing redirect].freeze
|
125
126
|
|
126
127
|
attr_reader :node
|
128
|
+
|
127
129
|
def initialize(node)
|
128
130
|
@node = node
|
129
131
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# This cop looks for uses of `each_with_object({}) { ... }`,
|
7
|
+
# `map { ... }.to_h`, and `Hash[map { ... }]` that are transforming
|
8
|
+
# an enumerable into a hash where the values are the original elements.
|
9
|
+
# Rails provides the `index_by` method for this purpose.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# [1, 2, 3].each_with_object({}) { |el, h| h[foo(el)] = el }
|
14
|
+
# [1, 2, 3].map { |el| [foo(el), el] }.to_h
|
15
|
+
# Hash[[1, 2, 3].collect { |el| [foo(el), el] }]
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# [1, 2, 3].index_by { |el| foo(el) }
|
19
|
+
class IndexBy < Cop
|
20
|
+
include IndexMethod
|
21
|
+
|
22
|
+
def_node_matcher :on_bad_each_with_object, <<~PATTERN
|
23
|
+
(block
|
24
|
+
({send csend} _ :each_with_object (hash))
|
25
|
+
(args (arg $_el) (arg _memo))
|
26
|
+
({send csend} (lvar _memo) :[]= $_ (lvar _el)))
|
27
|
+
PATTERN
|
28
|
+
|
29
|
+
def_node_matcher :on_bad_map_to_h, <<~PATTERN
|
30
|
+
({send csend}
|
31
|
+
(block
|
32
|
+
({send csend} _ {:map :collect})
|
33
|
+
(args (arg $_el))
|
34
|
+
(array $_ (lvar _el)))
|
35
|
+
:to_h)
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
def_node_matcher :on_bad_hash_brackets_map, <<~PATTERN
|
39
|
+
(send
|
40
|
+
(const _ :Hash)
|
41
|
+
:[]
|
42
|
+
(block
|
43
|
+
({send csend} _ {:map :collect})
|
44
|
+
(args (arg $_el))
|
45
|
+
(array $_ (lvar _el))))
|
46
|
+
PATTERN
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def new_method_name
|
51
|
+
'index_by'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# This cop looks for uses of `each_with_object({}) { ... }`,
|
7
|
+
# `map { ... }.to_h`, and `Hash[map { ... }]` that are transforming
|
8
|
+
# an enumerable into a hash where the keys are the original elements.
|
9
|
+
# Rails provides the `index_with` method for this purpose.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# [1, 2, 3].each_with_object({}) { |el, h| h[el] = foo(el) }
|
14
|
+
# [1, 2, 3].map { |el| [el, foo(el)] }.to_h
|
15
|
+
# Hash[[1, 2, 3].collect { |el| [el, foo(el)] }]
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# [1, 2, 3].index_with { |el| foo(el) }
|
19
|
+
class IndexWith < Cop
|
20
|
+
extend TargetRailsVersion
|
21
|
+
include IndexMethod
|
22
|
+
|
23
|
+
minimum_target_rails_version 6.0
|
24
|
+
|
25
|
+
def_node_matcher :on_bad_each_with_object, <<~PATTERN
|
26
|
+
(block
|
27
|
+
({send csend} _ :each_with_object (hash))
|
28
|
+
(args (arg $_el) (arg _memo))
|
29
|
+
({send csend} (lvar _memo) :[]= (lvar _el) $_))
|
30
|
+
PATTERN
|
31
|
+
|
32
|
+
def_node_matcher :on_bad_map_to_h, <<~PATTERN
|
33
|
+
({send csend}
|
34
|
+
(block
|
35
|
+
({send csend} _ {:map :collect})
|
36
|
+
(args (arg $_el))
|
37
|
+
(array (lvar _el) $_))
|
38
|
+
:to_h)
|
39
|
+
PATTERN
|
40
|
+
|
41
|
+
def_node_matcher :on_bad_hash_brackets_map, <<~PATTERN
|
42
|
+
(send
|
43
|
+
(const _ :Hash)
|
44
|
+
:[]
|
45
|
+
(block
|
46
|
+
({send csend} _ {:map :collect})
|
47
|
+
(args (arg $_el))
|
48
|
+
(array (lvar _el) $_)))
|
49
|
+
PATTERN
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def new_method_name
|
54
|
+
'index_with'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|