rubocop-rails 2.26.2 → 2.32.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 +45 -7
- data/config/default.yml +87 -49
- data/lib/rubocop/cop/mixin/active_record_helper.rb +2 -2
- data/lib/rubocop/cop/mixin/active_record_migrations_helper.rb +2 -2
- data/lib/rubocop/cop/mixin/database_type_resolvable.rb +2 -2
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +6 -1
- data/lib/rubocop/cop/mixin/index_method.rb +69 -61
- data/lib/rubocop/cop/mixin/routes_helper.rb +20 -0
- data/lib/rubocop/cop/mixin/target_rails_version.rb +3 -5
- data/lib/rubocop/cop/rails/add_column_index.rb +1 -0
- data/lib/rubocop/cop/rails/arel_star.rb +5 -5
- data/lib/rubocop/cop/rails/belongs_to.rb +1 -1
- data/lib/rubocop/cop/rails/blank.rb +1 -1
- data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -0
- data/lib/rubocop/cop/rails/content_tag.rb +1 -1
- data/lib/rubocop/cop/rails/dangerous_column_names.rb +2 -0
- data/lib/rubocop/cop/rails/delegate.rb +53 -7
- data/lib/rubocop/cop/rails/duplicate_association.rb +8 -4
- data/lib/rubocop/cop/rails/eager_evaluation_log_message.rb +1 -3
- data/lib/rubocop/cop/rails/enum_syntax.rb +2 -0
- data/lib/rubocop/cop/rails/env_local.rb +26 -3
- data/lib/rubocop/cop/rails/file_path.rb +61 -9
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +7 -0
- data/lib/rubocop/cop/rails/index_by.rb +37 -12
- data/lib/rubocop/cop/rails/index_with.rb +37 -12
- data/lib/rubocop/cop/rails/inquiry.rb +1 -1
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +11 -1
- data/lib/rubocop/cop/rails/match_route.rb +1 -9
- data/lib/rubocop/cop/rails/multiple_route_paths.rb +50 -0
- data/lib/rubocop/cop/rails/not_null_column.rb +6 -2
- data/lib/rubocop/cop/rails/output.rb +1 -2
- data/lib/rubocop/cop/rails/pluck.rb +30 -4
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +1 -1
- data/lib/rubocop/cop/rails/presence.rb +1 -1
- data/lib/rubocop/cop/rails/present.rb +1 -1
- data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +1 -1
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +6 -1
- data/lib/rubocop/cop/rails/reflection_class_name.rb +2 -2
- data/lib/rubocop/cop/rails/relative_date_constant.rb +1 -1
- data/lib/rubocop/cop/rails/reversible_migration.rb +4 -1
- data/lib/rubocop/cop/rails/root_pathname_methods.rb +6 -1
- data/lib/rubocop/cop/rails/save_bang.rb +8 -7
- data/lib/rubocop/cop/rails/schema_comment.rb +2 -1
- data/lib/rubocop/cop/rails/select_map.rb +3 -2
- data/lib/rubocop/cop/rails/skips_model_validations.rb +1 -1
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +1 -1
- data/lib/rubocop/cop/rails/strip_heredoc.rb +1 -1
- data/lib/rubocop/cop/rails/strong_parameters_expect.rb +104 -0
- data/lib/rubocop/cop/rails/three_state_boolean_column.rb +3 -2
- data/lib/rubocop/cop/rails/time_zone.rb +16 -7
- data/lib/rubocop/cop/rails/transaction_exit_statement.rb +7 -2
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +10 -33
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +1 -1
- data/lib/rubocop/cop/rails/where_range.rb +1 -1
- data/lib/rubocop/cop/rails_cops.rb +3 -0
- data/lib/rubocop/rails/migration_file_skippable.rb +54 -0
- data/lib/rubocop/rails/plugin.rb +48 -0
- data/lib/rubocop/rails/version.rb +1 -1
- data/lib/rubocop/rails.rb +1 -8
- data/lib/rubocop-rails.rb +4 -5
- metadata +28 -12
- data/lib/rubocop/rails/inject.rb +0 -18
@@ -29,18 +29,34 @@ module RuboCop
|
|
29
29
|
PATTERN
|
30
30
|
|
31
31
|
def_node_matcher :on_bad_to_h, <<~PATTERN
|
32
|
-
|
33
|
-
(
|
34
|
-
|
35
|
-
|
32
|
+
{
|
33
|
+
(block
|
34
|
+
(call _ :to_h)
|
35
|
+
(args (arg $_el))
|
36
|
+
(array $_ (lvar _el)))
|
37
|
+
(numblock
|
38
|
+
(call _ :to_h) $1
|
39
|
+
(array $_ (lvar :_1)))
|
40
|
+
(itblock
|
41
|
+
(call _ :to_h) $:it
|
42
|
+
(array $_ (lvar :it)))
|
43
|
+
}
|
36
44
|
PATTERN
|
37
45
|
|
38
46
|
def_node_matcher :on_bad_map_to_h, <<~PATTERN
|
39
47
|
(call
|
40
|
-
|
41
|
-
(
|
42
|
-
|
43
|
-
|
48
|
+
{
|
49
|
+
(block
|
50
|
+
(call _ {:map :collect})
|
51
|
+
(args (arg $_el))
|
52
|
+
(array $_ (lvar _el)))
|
53
|
+
(numblock
|
54
|
+
(call _ {:map :collect}) $1
|
55
|
+
(array $_ (lvar :_1)))
|
56
|
+
(itblock
|
57
|
+
(call _ {:map :collect}) $:it
|
58
|
+
(array $_ (lvar :it)))
|
59
|
+
}
|
44
60
|
:to_h)
|
45
61
|
PATTERN
|
46
62
|
|
@@ -48,10 +64,19 @@ module RuboCop
|
|
48
64
|
(send
|
49
65
|
(const {nil? cbase} :Hash)
|
50
66
|
:[]
|
51
|
-
|
52
|
-
(
|
53
|
-
|
54
|
-
|
67
|
+
{
|
68
|
+
(block
|
69
|
+
(call _ {:map :collect})
|
70
|
+
(args (arg $_el))
|
71
|
+
(array $_ (lvar _el)))
|
72
|
+
(numblock
|
73
|
+
(call _ {:map :collect}) $1
|
74
|
+
(array $_ (lvar :_1)))
|
75
|
+
(itblock
|
76
|
+
(call _ {:map :collect}) $:it
|
77
|
+
(array $_ (lvar :it)))
|
78
|
+
}
|
79
|
+
)
|
55
80
|
PATTERN
|
56
81
|
|
57
82
|
private
|
@@ -32,18 +32,34 @@ module RuboCop
|
|
32
32
|
PATTERN
|
33
33
|
|
34
34
|
def_node_matcher :on_bad_to_h, <<~PATTERN
|
35
|
-
|
36
|
-
(
|
37
|
-
|
38
|
-
|
35
|
+
{
|
36
|
+
(block
|
37
|
+
(call _ :to_h)
|
38
|
+
(args (arg $_el))
|
39
|
+
(array (lvar _el) $_))
|
40
|
+
(numblock
|
41
|
+
(call _ :to_h) $1
|
42
|
+
(array (lvar :_1) $_))
|
43
|
+
(itblock
|
44
|
+
(call _ :to_h) $:it
|
45
|
+
(array (lvar :it) $_))
|
46
|
+
}
|
39
47
|
PATTERN
|
40
48
|
|
41
49
|
def_node_matcher :on_bad_map_to_h, <<~PATTERN
|
42
50
|
(call
|
43
|
-
|
44
|
-
(
|
45
|
-
|
46
|
-
|
51
|
+
{
|
52
|
+
(block
|
53
|
+
(call _ {:map :collect})
|
54
|
+
(args (arg $_el))
|
55
|
+
(array (lvar _el) $_))
|
56
|
+
(numblock
|
57
|
+
(call _ {:map :collect}) $1
|
58
|
+
(array (lvar :_1) $_))
|
59
|
+
(itblock
|
60
|
+
(call _ {:map :collect}) $:it
|
61
|
+
(array (lvar :it) $_))
|
62
|
+
}
|
47
63
|
:to_h)
|
48
64
|
PATTERN
|
49
65
|
|
@@ -51,10 +67,19 @@ module RuboCop
|
|
51
67
|
(send
|
52
68
|
(const {nil? cbase} :Hash)
|
53
69
|
:[]
|
54
|
-
|
55
|
-
(
|
56
|
-
|
57
|
-
|
70
|
+
{
|
71
|
+
(block
|
72
|
+
(call _ {:map :collect})
|
73
|
+
(args (arg $_el))
|
74
|
+
(array (lvar _el) $_))
|
75
|
+
(numblock
|
76
|
+
(call _ {:map :collect}) $1
|
77
|
+
(array (lvar :_1) $_))
|
78
|
+
(itblock
|
79
|
+
(call _ {:map :collect}) $:it
|
80
|
+
(array (lvar :it) $_))
|
81
|
+
}
|
82
|
+
)
|
58
83
|
PATTERN
|
59
84
|
|
60
85
|
private
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
def on_send(node)
|
30
30
|
return unless node.arguments.empty?
|
31
31
|
return unless (receiver = node.receiver)
|
32
|
-
return
|
32
|
+
return unless receiver.type?(:str, :array)
|
33
33
|
|
34
34
|
add_offense(node.loc.selector)
|
35
35
|
end
|
@@ -115,6 +115,10 @@ module RuboCop
|
|
115
115
|
$_)))
|
116
116
|
PATTERN
|
117
117
|
|
118
|
+
def_node_matcher :delegated_methods, <<~PATTERN
|
119
|
+
(send nil? :delegate (sym $_)+ (hash <(pair (sym :to) _) ...>))
|
120
|
+
PATTERN
|
121
|
+
|
118
122
|
def on_send(node)
|
119
123
|
methods_node = only_or_except_filter_methods(node)
|
120
124
|
return unless methods_node
|
@@ -139,7 +143,13 @@ module RuboCop
|
|
139
143
|
return [] unless block
|
140
144
|
|
141
145
|
defined_methods = block.each_child_node(:def).map(&:method_name)
|
142
|
-
defined_methods + aliased_action_methods(block, defined_methods)
|
146
|
+
defined_methods + delegated_action_methods(block) + aliased_action_methods(block, defined_methods)
|
147
|
+
end
|
148
|
+
|
149
|
+
def delegated_action_methods(node)
|
150
|
+
node.each_child_node(:send).flat_map do |child_node|
|
151
|
+
delegated_methods(child_node) || []
|
152
|
+
end
|
143
153
|
end
|
144
154
|
|
145
155
|
def aliased_action_methods(node, defined_methods)
|
@@ -21,11 +21,11 @@ module RuboCop
|
|
21
21
|
# match 'photos/:id', to: 'photos#show', via: :all
|
22
22
|
#
|
23
23
|
class MatchRoute < Base
|
24
|
+
include RoutesHelper
|
24
25
|
extend AutoCorrector
|
25
26
|
|
26
27
|
MSG = 'Use `%<http_method>s` instead of `match` to define a route.'
|
27
28
|
RESTRICT_ON_SEND = %i[match].freeze
|
28
|
-
HTTP_METHODS = %i[get post put patch delete].freeze
|
29
29
|
|
30
30
|
def_node_matcher :match_method_call?, <<~PATTERN
|
31
31
|
(send nil? :match $_ $(hash ...) ?)
|
@@ -60,14 +60,6 @@ module RuboCop
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def_node_matcher :routes_draw?, <<~PATTERN
|
64
|
-
(send (send _ :routes) :draw)
|
65
|
-
PATTERN
|
66
|
-
|
67
|
-
def within_routes?(node)
|
68
|
-
node.each_ancestor(:block).any? { |a| routes_draw?(a.send_node) }
|
69
|
-
end
|
70
|
-
|
71
63
|
def extract_via(node)
|
72
64
|
via_pair = via_pair(node)
|
73
65
|
return %i[get] unless via_pair
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# Checks for mapping a route with multiple paths, which is deprecated and will be removed in Rails 8.1.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# get '/users', '/other_path', to: 'users#index'
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# get '/users', to: 'users#index'
|
15
|
+
# get '/other_path', to: 'users#index'
|
16
|
+
#
|
17
|
+
class MultipleRoutePaths < Base
|
18
|
+
include RoutesHelper
|
19
|
+
extend AutoCorrector
|
20
|
+
|
21
|
+
MSG = 'Use separate routes instead of combining multiple route paths in a single route.'
|
22
|
+
RESTRICT_ON_SEND = HTTP_METHODS
|
23
|
+
|
24
|
+
IGNORED_ARGUMENT_TYPES = %i[array hash].freeze
|
25
|
+
|
26
|
+
def on_send(node)
|
27
|
+
return unless within_routes?(node)
|
28
|
+
|
29
|
+
route_paths = node.arguments.reject { |argument| IGNORED_ARGUMENT_TYPES.include?(argument.type) }
|
30
|
+
return if route_paths.count < 2
|
31
|
+
|
32
|
+
add_offense(node) do |corrector|
|
33
|
+
corrector.replace(node, migrate_to_multiple_routes(node, route_paths))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def migrate_to_multiple_routes(node, route_paths)
|
40
|
+
rest = route_paths.last.source_range.end.join(node.source_range.end).source
|
41
|
+
indentation = ' ' * node.source_range.column
|
42
|
+
|
43
|
+
route_paths.map do |route_path|
|
44
|
+
"#{node.method_name} #{route_path.source}#{rest}"
|
45
|
+
end.join("\n#{indentation}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -41,10 +41,14 @@ module RuboCop
|
|
41
41
|
# change_column_null :products, :category_id, false
|
42
42
|
class NotNullColumn < Base
|
43
43
|
include DatabaseTypeResolvable
|
44
|
+
include MigrationsHelper
|
44
45
|
|
45
46
|
MSG = 'Do not add a NOT NULL column without a default value.'
|
46
47
|
RESTRICT_ON_SEND = %i[add_column add_reference].freeze
|
47
48
|
|
49
|
+
VIRTUAL_TYPE_VALUES = [:virtual, 'virtual'].freeze
|
50
|
+
TEXT_TYPE_VALUES = [:text, 'text'].freeze
|
51
|
+
|
48
52
|
def_node_matcher :add_not_null_column?, <<~PATTERN
|
49
53
|
(send nil? :add_column _ _ $_ (hash $...))
|
50
54
|
PATTERN
|
@@ -91,8 +95,8 @@ module RuboCop
|
|
91
95
|
|
92
96
|
def check_column(type, pairs)
|
93
97
|
if type.respond_to?(:value)
|
94
|
-
return if
|
95
|
-
return if (type.value
|
98
|
+
return if VIRTUAL_TYPE_VALUES.include?(type.value)
|
99
|
+
return if TEXT_TYPE_VALUES.include?(type.value) && database == MYSQL
|
96
100
|
end
|
97
101
|
|
98
102
|
check_pairs(pairs)
|
@@ -23,7 +23,6 @@ module RuboCop
|
|
23
23
|
|
24
24
|
MSG = "Do not write to stdout. Use Rails's logger if you want to log."
|
25
25
|
RESTRICT_ON_SEND = %i[ap p pp pretty_print print puts binwrite syswrite write write_nonblock].freeze
|
26
|
-
ALLOWED_TYPES = %i[send csend block numblock].freeze
|
27
26
|
|
28
27
|
def_node_matcher :output?, <<~PATTERN
|
29
28
|
(send nil? {:ap :p :pp :pretty_print :print :puts} ...)
|
@@ -40,7 +39,7 @@ module RuboCop
|
|
40
39
|
PATTERN
|
41
40
|
|
42
41
|
def on_send(node)
|
43
|
-
return if
|
42
|
+
return if node.parent&.call_type? || node.block_node
|
44
43
|
return if !output?(node) && !io_output?(node)
|
45
44
|
|
46
45
|
range = offense_range(node)
|
@@ -9,6 +9,24 @@ module RuboCop
|
|
9
9
|
# element in an enumerable. When called on an Active Record relation, it
|
10
10
|
# results in a more efficient query that only selects the necessary key.
|
11
11
|
#
|
12
|
+
# NOTE: If the receiver's relation is not loaded and `pluck` is used inside an iteration,
|
13
|
+
# it may result in N+1 queries because `pluck` queries the database on each iteration.
|
14
|
+
# This cop ignores offenses for `map/collect` when they are suspected to be part of an iteration
|
15
|
+
# to prevent such potential issues.
|
16
|
+
#
|
17
|
+
# [source,ruby]
|
18
|
+
# ----
|
19
|
+
# users = User.all
|
20
|
+
# 5.times do
|
21
|
+
# users.map { |user| user[:foo] } # Only one query is executed
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# users = User.all
|
25
|
+
# 5.times do
|
26
|
+
# users.pluck(:id) # A query is executed on every iteration
|
27
|
+
# end
|
28
|
+
# ----
|
29
|
+
#
|
12
30
|
# @safety
|
13
31
|
# This cop is unsafe because model can use column aliases.
|
14
32
|
#
|
@@ -38,30 +56,38 @@ module RuboCop
|
|
38
56
|
minimum_target_rails_version 5.0
|
39
57
|
|
40
58
|
def_node_matcher :pluck_candidate?, <<~PATTERN
|
41
|
-
(
|
59
|
+
(any_block (call _ {:map :collect}) $_argument (send lvar :[] $_key))
|
42
60
|
PATTERN
|
43
61
|
|
62
|
+
# rubocop:disable Metrics/AbcSize
|
44
63
|
def on_block(node)
|
64
|
+
return if node.each_ancestor(:any_block).any?
|
65
|
+
|
45
66
|
pluck_candidate?(node) do |argument, key|
|
46
67
|
next if key.regexp_type? || !use_one_block_argument?(argument)
|
47
68
|
|
48
69
|
match = if node.block_type?
|
49
70
|
block_argument = argument.children.first.source
|
50
71
|
use_block_argument_in_key?(block_argument, key)
|
51
|
-
|
52
|
-
|
72
|
+
elsif node.numblock_type?
|
73
|
+
use_block_argument_in_key?('_1', key)
|
74
|
+
else # itblock
|
75
|
+
use_block_argument_in_key?('it', key)
|
53
76
|
end
|
54
77
|
next unless match
|
55
78
|
|
56
79
|
register_offense(node, key)
|
57
80
|
end
|
58
81
|
end
|
82
|
+
# rubocop:enable Metrics/AbcSize
|
59
83
|
alias on_numblock on_block
|
84
|
+
alias on_itblock on_block
|
60
85
|
|
61
86
|
private
|
62
87
|
|
63
88
|
def use_one_block_argument?(argument)
|
64
|
-
|
89
|
+
# Checks for numbered argument `_1` or `it block parameter.
|
90
|
+
return true if [1, :it].include?(argument)
|
65
91
|
|
66
92
|
argument.respond_to?(:one?) && argument.one?
|
67
93
|
end
|
@@ -110,7 +110,7 @@ module RuboCop
|
|
110
110
|
def on_if(node)
|
111
111
|
return unless cop_config['UnlessBlank']
|
112
112
|
return unless node.unless?
|
113
|
-
return if node.else? && config.
|
113
|
+
return if node.else? && config.cop_enabled?('Style/UnlessElse')
|
114
114
|
|
115
115
|
unless_blank?(node) do |method_call, receiver|
|
116
116
|
range = unless_condition(node, method_call)
|
@@ -174,7 +174,7 @@ module RuboCop
|
|
174
174
|
parent = node.parent
|
175
175
|
return false unless POSSIBLE_ENUMERABLE_BLOCK_METHODS.include?(parent.method_name)
|
176
176
|
|
177
|
-
parent.
|
177
|
+
parent.block_literal? || parent.first_argument&.block_pass_type?
|
178
178
|
end
|
179
179
|
|
180
180
|
def sensitive_association_method?(node)
|
@@ -85,18 +85,22 @@ module RuboCop
|
|
85
85
|
end
|
86
86
|
|
87
87
|
alias on_numblock on_block
|
88
|
+
alias on_itblock on_block
|
88
89
|
|
89
90
|
private
|
90
91
|
|
91
92
|
def autocorrect(corrector, send_node, node)
|
92
93
|
corrector.remove(send_node.receiver)
|
93
94
|
corrector.remove(send_node.loc.dot)
|
94
|
-
corrector.remove(block_argument_range(send_node))
|
95
|
+
corrector.remove(block_argument_range(send_node)) if node.block_type?
|
95
96
|
end
|
96
97
|
|
98
|
+
# rubocop:disable Metrics/AbcSize
|
97
99
|
def redundant_receiver?(send_nodes, node)
|
98
100
|
proc = if node.numblock_type?
|
99
101
|
->(n) { n.receiver.lvar_type? && n.receiver.source == '_1' }
|
102
|
+
elsif node.itblock_type?
|
103
|
+
->(n) { n.receiver.lvar_type? && n.receiver.source == 'it' }
|
100
104
|
else
|
101
105
|
return false if node.arguments.empty?
|
102
106
|
|
@@ -106,6 +110,7 @@ module RuboCop
|
|
106
110
|
|
107
111
|
send_nodes.all?(&proc)
|
108
112
|
end
|
113
|
+
# rubocop:enable Metrics/AbcSize
|
109
114
|
|
110
115
|
def block_argument_range(node)
|
111
116
|
block_node = node.each_ancestor(:block).first
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
|
41
41
|
def on_send(node)
|
42
42
|
association_with_reflection(node) do |reflection_class_name|
|
43
|
-
return if reflection_class_name.value.send_type? && reflection_class_name.value.receiver
|
43
|
+
return if reflection_class_name.value.send_type? && !reflection_class_name.value.receiver&.const_type?
|
44
44
|
return if reflection_class_name.value.lvar_type? && str_assigned?(reflection_class_name)
|
45
45
|
|
46
46
|
add_offense(reflection_class_name) do |corrector|
|
@@ -76,7 +76,7 @@ module RuboCop
|
|
76
76
|
def autocorrect(corrector, class_config)
|
77
77
|
class_value = class_config.value
|
78
78
|
replacement = const_or_string(class_value)
|
79
|
-
return unless replacement
|
79
|
+
return unless replacement
|
80
80
|
|
81
81
|
corrector.replace(class_value, replacement.source.inspect)
|
82
82
|
end
|
@@ -205,6 +205,7 @@ module RuboCop
|
|
205
205
|
end
|
206
206
|
|
207
207
|
alias on_numblock on_block
|
208
|
+
alias on_itblock on_block
|
208
209
|
|
209
210
|
private
|
210
211
|
|
@@ -215,8 +216,10 @@ module RuboCop
|
|
215
216
|
end
|
216
217
|
|
217
218
|
def check_drop_table_node(node)
|
219
|
+
return unless (last_argument = node.last_argument)
|
220
|
+
|
218
221
|
drop_table_call(node) do
|
219
|
-
unless node.parent.
|
222
|
+
unless node.parent.any_block_type? || last_argument.block_pass_type?
|
220
223
|
add_offense(node, message: format(MSG, action: 'drop_table(without block)'))
|
221
224
|
end
|
222
225
|
end
|
@@ -237,7 +237,12 @@ module RuboCop
|
|
237
237
|
end
|
238
238
|
|
239
239
|
replacement = "#{path_replacement}.#{method}"
|
240
|
-
|
240
|
+
|
241
|
+
if args.any?
|
242
|
+
formatted_args = args.map { |arg| arg.array_type? ? "*#{arg.source}" : arg.source }
|
243
|
+
replacement += "(#{formatted_args.join(', ')})"
|
244
|
+
end
|
245
|
+
|
241
246
|
replacement
|
242
247
|
end
|
243
248
|
|
@@ -182,7 +182,7 @@ module RuboCop
|
|
182
182
|
def right_assignment_node(assignment)
|
183
183
|
node = assignment.node.child_nodes.first
|
184
184
|
|
185
|
-
return node unless node&.
|
185
|
+
return node unless node&.any_block_type?
|
186
186
|
|
187
187
|
node.send_node
|
188
188
|
end
|
@@ -244,11 +244,11 @@ module RuboCop
|
|
244
244
|
end
|
245
245
|
|
246
246
|
def operator_or_single_negative?(node)
|
247
|
-
node.
|
247
|
+
node.operator_keyword? || single_negative?(node)
|
248
248
|
end
|
249
249
|
|
250
250
|
def conditional?(parent)
|
251
|
-
parent.
|
251
|
+
parent.type?(:if, :case)
|
252
252
|
end
|
253
253
|
|
254
254
|
def deparenthesize(node)
|
@@ -305,7 +305,7 @@ module RuboCop
|
|
305
305
|
|
306
306
|
node = assignable_node(node)
|
307
307
|
method, sibling_index = find_method_with_sibling_index(node.parent)
|
308
|
-
return false unless method
|
308
|
+
return false unless method&.type?(:def, :any_block)
|
309
309
|
|
310
310
|
method.children.size == node.sibling_index + sibling_index
|
311
311
|
end
|
@@ -324,12 +324,13 @@ module RuboCop
|
|
324
324
|
|
325
325
|
def explicit_return?(node)
|
326
326
|
ret = assignable_node(node).parent
|
327
|
-
ret
|
327
|
+
ret&.type?(:return, :next)
|
328
328
|
end
|
329
329
|
|
330
330
|
def return_value_assigned?(node)
|
331
|
-
assignment = assignable_node(node).parent
|
332
|
-
|
331
|
+
return false unless (assignment = assignable_node(node).parent)
|
332
|
+
|
333
|
+
assignment.assignment?
|
333
334
|
end
|
334
335
|
|
335
336
|
def persist_method?(node, methods = RESTRICT_ON_SEND)
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
#
|
24
24
|
class SchemaComment < Base
|
25
25
|
include ActiveRecordMigrationsHelper
|
26
|
+
include MigrationsHelper
|
26
27
|
|
27
28
|
COLUMN_MSG = 'New database column without `comment`.'
|
28
29
|
TABLE_MSG = 'New database table without `comment`.'
|
@@ -38,7 +39,7 @@ module RuboCop
|
|
38
39
|
|
39
40
|
# @!method comment_present?(node)
|
40
41
|
def_node_matcher :comment_present?, <<~PATTERN
|
41
|
-
(hash <(pair {(sym :comment) (str "comment")} (
|
42
|
+
(hash <(pair {(sym :comment) (str "comment")} !{nil (str blank?)}) ...>)
|
42
43
|
PATTERN
|
43
44
|
|
44
45
|
# @!method add_column?(node)
|
@@ -40,12 +40,13 @@ module RuboCop
|
|
40
40
|
autocorrect(corrector, select_node, node, preferred_method)
|
41
41
|
end
|
42
42
|
end
|
43
|
+
alias on_csend on_send
|
43
44
|
|
44
45
|
private
|
45
46
|
|
46
47
|
def find_select_node(node, column_name)
|
47
48
|
node.descendants.detect do |select_candidate|
|
48
|
-
next if !select_candidate.
|
49
|
+
next if !select_candidate.call_type? || !select_candidate.method?(:select)
|
49
50
|
|
50
51
|
match_column_name?(select_candidate, column_name)
|
51
52
|
end
|
@@ -53,7 +54,7 @@ module RuboCop
|
|
53
54
|
|
54
55
|
# rubocop:disable Metrics/AbcSize
|
55
56
|
def autocorrect(corrector, select_node, node, preferred_method)
|
56
|
-
corrector.remove(select_node.
|
57
|
+
corrector.remove(select_node.parent.loc.dot)
|
57
58
|
corrector.remove(select_node.loc.selector.begin.join(select_node.source_range.end))
|
58
59
|
corrector.replace(node.loc.selector.begin.join(node.source_range.end), preferred_method)
|
59
60
|
end
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
|
34
34
|
def on_send(node)
|
35
35
|
return unless (receiver = node.receiver)
|
36
|
-
return unless receiver.
|
36
|
+
return unless receiver.type?(:str, :dstr)
|
37
37
|
return unless receiver.respond_to?(:heredoc?) && receiver.heredoc?
|
38
38
|
|
39
39
|
register_offense(node, receiver)
|