rubocop-rails 2.15.2 → 2.16.1
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/config/default.yml +81 -0
- data/config/obsoletion.yml +10 -0
- data/lib/rubocop/cop/mixin/active_record_helper.rb +1 -4
- data/lib/rubocop/cop/mixin/active_record_migrations_helper.rb +1 -3
- data/lib/rubocop/cop/mixin/index_method.rb +5 -15
- data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +98 -0
- data/lib/rubocop/cop/rails/action_filter.rb +1 -1
- data/lib/rubocop/cop/rails/active_record_aliases.rb +1 -4
- data/lib/rubocop/cop/rails/active_record_override.rb +2 -5
- data/lib/rubocop/cop/rails/active_support_on_load.rb +70 -0
- data/lib/rubocop/cop/rails/add_column_index.rb +1 -4
- data/lib/rubocop/cop/rails/blank.rb +1 -2
- data/lib/rubocop/cop/rails/bulk_change_table.rb +6 -20
- data/lib/rubocop/cop/rails/compact_blank.rb +5 -1
- data/lib/rubocop/cop/rails/content_tag.rb +1 -3
- data/lib/rubocop/cop/rails/date.rb +4 -9
- data/lib/rubocop/cop/rails/delegate.rb +2 -5
- data/lib/rubocop/cop/rails/deprecated_active_model_errors_methods.rb +17 -13
- data/lib/rubocop/cop/rails/dot_separated_keys.rb +1 -1
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +2 -4
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -5
- data/lib/rubocop/cop/rails/environment_comparison.rb +1 -2
- data/lib/rubocop/cop/rails/file_path.rb +2 -4
- data/lib/rubocop/cop/rails/find_each.rb +8 -2
- data/lib/rubocop/cop/rails/freeze_time.rb +74 -0
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -3
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +4 -9
- data/lib/rubocop/cop/rails/http_status.rb +5 -10
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +3 -10
- data/lib/rubocop/cop/rails/inverse_of.rb +3 -6
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +2 -6
- data/lib/rubocop/cop/rails/link_to_blank.rb +1 -4
- data/lib/rubocop/cop/rails/output.rb +2 -5
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +1 -2
- data/lib/rubocop/cop/rails/presence.rb +1 -3
- data/lib/rubocop/cop/rails/present.rb +3 -6
- data/lib/rubocop/cop/rails/rake_environment.rb +1 -1
- data/lib/rubocop/cop/rails/redundant_allow_nil.rb +2 -4
- data/lib/rubocop/cop/rails/redundant_foreign_key.rb +1 -1
- data/lib/rubocop/cop/rails/redundant_presence_validation_on_belongs_to.rb +2 -2
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +28 -26
- data/lib/rubocop/cop/rails/reflection_class_name.rb +17 -0
- data/lib/rubocop/cop/rails/refute_methods.rb +1 -5
- data/lib/rubocop/cop/rails/relative_date_constant.rb +2 -5
- data/lib/rubocop/cop/rails/request_referer.rb +1 -2
- data/lib/rubocop/cop/rails/reversible_migration.rb +10 -33
- data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +1 -2
- data/lib/rubocop/cop/rails/root_pathname_methods.rb +214 -0
- data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +1 -3
- data/lib/rubocop/cop/rails/save_bang.rb +10 -22
- data/lib/rubocop/cop/rails/short_i18n.rb +1 -4
- data/lib/rubocop/cop/rails/skips_model_validations.rb +1 -2
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +1 -5
- data/lib/rubocop/cop/rails/time_zone.rb +8 -19
- data/lib/rubocop/cop/rails/to_s_with_argument.rb +41 -0
- data/lib/rubocop/cop/rails/top_level_hash_with_indifferent_access.rb +49 -0
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +3 -6
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +1 -3
- data/lib/rubocop/cop/rails/unknown_env.rb +2 -4
- data/lib/rubocop/cop/rails/validation.rb +4 -12
- data/lib/rubocop/cop/rails/where_missing.rb +111 -0
- data/lib/rubocop/cop/rails_cops.rb +7 -0
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +13 -8
- data/bin/console +0 -11
- data/bin/setup +0 -7
@@ -37,7 +37,8 @@ module RuboCop
|
|
37
37
|
extend AutoCorrector
|
38
38
|
|
39
39
|
MSG = 'Avoid manipulating ActiveModel errors as hash directly.'
|
40
|
-
|
40
|
+
AUTOCORRECTABLE_METHODS = %i[<< clear keys].freeze
|
41
|
+
INCOMPATIBLE_METHODS = %i[keys values to_h to_xml].freeze
|
41
42
|
|
42
43
|
MANIPULATIVE_METHODS = Set[
|
43
44
|
*%i[
|
@@ -55,7 +56,7 @@ module RuboCop
|
|
55
56
|
{
|
56
57
|
#root_manipulation?
|
57
58
|
#root_assignment?
|
58
|
-
#
|
59
|
+
#errors_deprecated?
|
59
60
|
#messages_details_manipulation?
|
60
61
|
#messages_details_assignment?
|
61
62
|
}
|
@@ -77,10 +78,10 @@ module RuboCop
|
|
77
78
|
...)
|
78
79
|
PATTERN
|
79
80
|
|
80
|
-
def_node_matcher :
|
81
|
+
def_node_matcher :errors_deprecated?, <<~PATTERN
|
81
82
|
(send
|
82
83
|
(send #receiver_matcher :errors)
|
83
|
-
:keys)
|
84
|
+
{:keys :values :to_h :to_xml})
|
84
85
|
PATTERN
|
85
86
|
|
86
87
|
def_node_matcher :messages_details_manipulation?, <<~PATTERN
|
@@ -106,10 +107,10 @@ module RuboCop
|
|
106
107
|
|
107
108
|
def on_send(node)
|
108
109
|
any_manipulation?(node) do
|
109
|
-
next if
|
110
|
+
next if target_rails_version <= 6.0 && INCOMPATIBLE_METHODS.include?(node.method_name)
|
110
111
|
|
111
112
|
add_offense(node) do |corrector|
|
112
|
-
next
|
113
|
+
next if skip_autocorrect?(node)
|
113
114
|
|
114
115
|
autocorrect(corrector, node)
|
115
116
|
end
|
@@ -118,14 +119,16 @@ module RuboCop
|
|
118
119
|
|
119
120
|
private
|
120
121
|
|
122
|
+
def skip_autocorrect?(node)
|
123
|
+
return true unless AUTOCORRECTABLE_METHODS.include?(node.method_name)
|
124
|
+
return false unless (receiver = node.receiver.receiver)
|
125
|
+
|
126
|
+
receiver.send_type? && receiver.method?(:details) && node.method?(:<<)
|
127
|
+
end
|
128
|
+
|
121
129
|
def autocorrect(corrector, node)
|
122
130
|
receiver = node.receiver
|
123
131
|
|
124
|
-
if receiver.receiver.send_type? && receiver.receiver.method?(:messages)
|
125
|
-
corrector.remove(receiver.receiver.loc.dot)
|
126
|
-
corrector.remove(receiver.receiver.loc.selector)
|
127
|
-
end
|
128
|
-
|
129
132
|
range = offense_range(node, receiver)
|
130
133
|
replacement = replacement(node, receiver)
|
131
134
|
|
@@ -133,11 +136,12 @@ module RuboCop
|
|
133
136
|
end
|
134
137
|
|
135
138
|
def offense_range(node, receiver)
|
136
|
-
|
139
|
+
receiver = receiver.receiver while receiver.send_type? && !receiver.method?(:errors) && receiver.receiver
|
140
|
+
range_between(receiver.source_range.end_pos, node.source_range.end_pos)
|
137
141
|
end
|
138
142
|
|
139
143
|
def replacement(node, receiver)
|
140
|
-
return '.
|
144
|
+
return '.attribute_names' if node.method?(:keys)
|
141
145
|
|
142
146
|
key = receiver.first_argument.source
|
143
147
|
|
@@ -37,7 +37,7 @@ module RuboCop
|
|
37
37
|
|
38
38
|
add_offense(scope_node) do |corrector|
|
39
39
|
# Eat the comma on the left.
|
40
|
-
range = range_with_surrounding_space(
|
40
|
+
range = range_with_surrounding_space(scope_node.source_range, side: :left)
|
41
41
|
range = range_with_surrounding_comma(range, :left)
|
42
42
|
corrector.remove(range)
|
43
43
|
|
@@ -70,8 +70,7 @@ module RuboCop
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def allowed_invocation?(node)
|
73
|
-
allowed_method?(node) || allowed_receiver?(node) ||
|
74
|
-
whitelisted?(node)
|
73
|
+
allowed_method?(node) || allowed_receiver?(node) || whitelisted?(node)
|
75
74
|
end
|
76
75
|
|
77
76
|
def allowed_method?(node)
|
@@ -95,8 +94,7 @@ module RuboCop
|
|
95
94
|
end
|
96
95
|
|
97
96
|
def autocorrect_method_name(corrector, node)
|
98
|
-
corrector.replace(node.loc.selector,
|
99
|
-
static_method_name(node.method_name.to_s))
|
97
|
+
corrector.replace(node.loc.selector, static_method_name(node.method_name.to_s))
|
100
98
|
end
|
101
99
|
|
102
100
|
def autocorrect_argument_keywords(corrector, node, keywords)
|
@@ -20,8 +20,7 @@ module RuboCop
|
|
20
20
|
class EnumUniqueness < Base
|
21
21
|
include Duplication
|
22
22
|
|
23
|
-
MSG = 'Duplicate value `%<value>s` found in `%<enum>s` '
|
24
|
-
'enum declaration.'
|
23
|
+
MSG = 'Duplicate value `%<value>s` found in `%<enum>s` enum declaration.'
|
25
24
|
RESTRICT_ON_SEND = %i[enum].freeze
|
26
25
|
|
27
26
|
def_node_matcher :enum?, <<~PATTERN
|
@@ -41,9 +40,7 @@ module RuboCop
|
|
41
40
|
next unless duplicates?(items)
|
42
41
|
|
43
42
|
consecutive_duplicates(items).each do |item|
|
44
|
-
add_offense(item, message: format(
|
45
|
-
MSG, value: item.source, enum: enum_name(key)
|
46
|
-
))
|
43
|
+
add_offense(item, message: format(MSG, value: item.source, enum: enum_name(key)))
|
47
44
|
end
|
48
45
|
end
|
49
46
|
end
|
@@ -96,8 +96,7 @@ module RuboCop
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def rails_env_on_lhs?(node)
|
99
|
-
comparing_str_env_with_rails_env_on_lhs?(node) ||
|
100
|
-
comparing_sym_env_with_rails_env_on_lhs?(node)
|
99
|
+
comparing_str_env_with_rails_env_on_lhs?(node) || comparing_sym_env_with_rails_env_on_lhs?(node)
|
101
100
|
end
|
102
101
|
|
103
102
|
def build_predicate_method_for_rails_env_on_lhs(node)
|
@@ -50,8 +50,7 @@ module RuboCop
|
|
50
50
|
return unless node.children.last.str_type?
|
51
51
|
|
52
52
|
last_child_source = node.children.last.source
|
53
|
-
return unless last_child_source.start_with?('.') ||
|
54
|
-
last_child_source.include?(File::SEPARATOR)
|
53
|
+
return unless last_child_source.start_with?('.') || last_child_source.include?(File::SEPARATOR)
|
55
54
|
return if last_child_source.start_with?(':')
|
56
55
|
|
57
56
|
register_offense(node)
|
@@ -97,8 +96,7 @@ module RuboCop
|
|
97
96
|
|
98
97
|
def register_offense(node)
|
99
98
|
line_range = node.loc.column...node.loc.last_column
|
100
|
-
source_range = source_range(processed_source.buffer, node.first_line,
|
101
|
-
line_range)
|
99
|
+
source_range = source_range(processed_source.buffer, node.first_line, line_range)
|
102
100
|
add_offense(source_range)
|
103
101
|
end
|
104
102
|
|
@@ -13,11 +13,17 @@ module RuboCop
|
|
13
13
|
# # good
|
14
14
|
# User.all.find_each
|
15
15
|
#
|
16
|
-
# @example
|
16
|
+
# @example AllowedMethods: ['order']
|
17
|
+
# # good
|
18
|
+
# User.order(:foo).each
|
19
|
+
#
|
20
|
+
# @example AllowedPattern: [/order/]
|
17
21
|
# # good
|
18
22
|
# User.order(:foo).each
|
19
23
|
class FindEach < Base
|
20
24
|
include ActiveRecordHelper
|
25
|
+
include AllowedMethods
|
26
|
+
include AllowedPattern
|
21
27
|
extend AutoCorrector
|
22
28
|
|
23
29
|
MSG = 'Use `find_each` instead of `each`.'
|
@@ -47,7 +53,7 @@ module RuboCop
|
|
47
53
|
|
48
54
|
method_chain = node.each_node(:send).map(&:method_name)
|
49
55
|
|
50
|
-
|
56
|
+
method_chain.any? { |method_name| allowed_method?(method_name) || matches_allowed_pattern?(method_name) }
|
51
57
|
end
|
52
58
|
|
53
59
|
def active_model_error_where?(node)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# Identifies usages of `travel_to` with an argument of the current time and
|
7
|
+
# change them to use `freeze_time` instead.
|
8
|
+
#
|
9
|
+
# @safety
|
10
|
+
# This cop’s autocorrection is unsafe because `freeze_time` just delegates to
|
11
|
+
# `travel_to` with a default `Time.now`, it is not strictly equivalent to `Time.now`
|
12
|
+
# if the argument of `travel_to` is the current time considering time zone.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# travel_to(Time.now)
|
17
|
+
# travel_to(Time.new)
|
18
|
+
# travel_to(DateTime.now)
|
19
|
+
# travel_to(Time.current)
|
20
|
+
# travel_to(Time.zone.now)
|
21
|
+
# travel_to(Time.now.in_time_zone)
|
22
|
+
# travel_to(Time.current.to_time)
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# freeze_time
|
26
|
+
#
|
27
|
+
class FreezeTime < Base
|
28
|
+
extend AutoCorrector
|
29
|
+
|
30
|
+
MSG = 'Use `freeze_time` instead of `travel_to`.'
|
31
|
+
NOW_METHODS = %i[now new current].freeze
|
32
|
+
CONV_METHODS = %i[to_time in_time_zone].freeze
|
33
|
+
RESTRICT_ON_SEND = %i[travel_to].freeze
|
34
|
+
|
35
|
+
# @!method time_now?(node)
|
36
|
+
def_node_matcher :time_now?, <<~PATTERN
|
37
|
+
(const nil? {:Time :DateTime})
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
# @!method zoned_time_now?(node)
|
41
|
+
def_node_matcher :zoned_time_now?, <<~PATTERN
|
42
|
+
(send (const nil? :Time) :zone)
|
43
|
+
PATTERN
|
44
|
+
|
45
|
+
def on_send(node)
|
46
|
+
child_node, method_name, time_argument = *node.first_argument.children
|
47
|
+
return if time_argument || !child_node
|
48
|
+
return unless current_time?(child_node, method_name) || current_time_with_convert?(child_node, method_name)
|
49
|
+
|
50
|
+
add_offense(node) do |corrector|
|
51
|
+
last_argument = node.last_argument
|
52
|
+
freeze_time_method = last_argument.block_pass_type? ? "freeze_time(#{last_argument.source})" : 'freeze_time'
|
53
|
+
corrector.replace(node, freeze_time_method)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def current_time?(node, method_name)
|
60
|
+
return false unless NOW_METHODS.include?(method_name)
|
61
|
+
|
62
|
+
node.send_type? ? zoned_time_now?(node) : time_now?(node)
|
63
|
+
end
|
64
|
+
|
65
|
+
def current_time_with_convert?(node, method_name)
|
66
|
+
return false unless CONV_METHODS.include?(method_name)
|
67
|
+
|
68
|
+
child_node, child_method_name = *node.children
|
69
|
+
current_time?(child_node, child_method_name)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -105,9 +105,7 @@ module RuboCop
|
|
105
105
|
|
106
106
|
return false unless node.parent
|
107
107
|
|
108
|
-
return true if contain_valid_options_in_with_options_block?(
|
109
|
-
node.parent.parent
|
110
|
-
)
|
108
|
+
return true if contain_valid_options_in_with_options_block?(node.parent.parent)
|
111
109
|
end
|
112
110
|
|
113
111
|
false
|
@@ -22,11 +22,8 @@ module RuboCop
|
|
22
22
|
extend AutoCorrector
|
23
23
|
extend TargetRailsVersion
|
24
24
|
|
25
|
-
MSG = 'Use keyword arguments instead of '
|
26
|
-
|
27
|
-
KEYWORD_ARGS = %i[
|
28
|
-
method params session body flash xhr as headers env to
|
29
|
-
].freeze
|
25
|
+
MSG = 'Use keyword arguments instead of positional arguments for http call: `%<verb>s`.'
|
26
|
+
KEYWORD_ARGS = %i[method params session body flash xhr as headers env to].freeze
|
30
27
|
ROUTING_METHODS = %i[draw routes].freeze
|
31
28
|
RESTRICT_ON_SEND = %i[get post put patch delete head].freeze
|
32
29
|
|
@@ -75,8 +72,7 @@ module RuboCop
|
|
75
72
|
return false if kwsplat_hash?(data)
|
76
73
|
|
77
74
|
data.each_pair.none? do |pair|
|
78
|
-
special_keyword_arg?(pair.key) ||
|
79
|
-
(format_arg?(pair.key) && data.pairs.one?)
|
75
|
+
special_keyword_arg?(pair.key) || (format_arg?(pair.key) && data.pairs.one?)
|
80
76
|
end
|
81
77
|
end
|
82
78
|
|
@@ -98,8 +94,7 @@ module RuboCop
|
|
98
94
|
return '' if data.hash_type? && data.empty?
|
99
95
|
|
100
96
|
hash_data = if data.hash_type?
|
101
|
-
format('{ %<data>s }',
|
102
|
-
data: data.pairs.map(&:source).join(', '))
|
97
|
+
format('{ %<data>s }', data: data.pairs.map(&:source).join(', '))
|
103
98
|
else
|
104
99
|
# user supplies an object,
|
105
100
|
# no need to surround with braces
|
@@ -84,10 +84,8 @@ module RuboCop
|
|
84
84
|
|
85
85
|
# :nodoc:
|
86
86
|
class SymbolicStyleChecker
|
87
|
-
MSG = 'Prefer `%<prefer>s` over `%<current>s` '
|
88
|
-
|
89
|
-
DEFAULT_MSG = 'Prefer `symbolic` over `numeric` ' \
|
90
|
-
'to define HTTP status code.'
|
87
|
+
MSG = 'Prefer `%<prefer>s` over `%<current>s` to define HTTP status code.'
|
88
|
+
DEFAULT_MSG = 'Prefer `symbolic` over `numeric` to define HTTP status code.'
|
91
89
|
|
92
90
|
attr_reader :node
|
93
91
|
|
@@ -118,17 +116,14 @@ module RuboCop
|
|
118
116
|
end
|
119
117
|
|
120
118
|
def custom_http_status_code?
|
121
|
-
node.int_type? &&
|
122
|
-
!::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(number)
|
119
|
+
node.int_type? && !::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(number)
|
123
120
|
end
|
124
121
|
end
|
125
122
|
|
126
123
|
# :nodoc:
|
127
124
|
class NumericStyleChecker
|
128
|
-
MSG = 'Prefer `%<prefer>s` over `%<current>s` '
|
129
|
-
|
130
|
-
DEFAULT_MSG = 'Prefer `numeric` over `symbolic` ' \
|
131
|
-
'to define HTTP status code.'
|
125
|
+
MSG = 'Prefer `%<prefer>s` over `%<current>s` to define HTTP status code.'
|
126
|
+
DEFAULT_MSG = 'Prefer `numeric` over `symbolic` to define HTTP status code.'
|
132
127
|
PERMITTED_STATUS = %i[error success missing redirect].freeze
|
133
128
|
|
134
129
|
attr_reader :node
|
@@ -42,12 +42,7 @@ module RuboCop
|
|
42
42
|
`%<ignore>s` option will be ignored when `%<prefer>s` and `%<ignore>s` are used together.
|
43
43
|
MSG
|
44
44
|
|
45
|
-
RESTRICT_ON_SEND = %i[
|
46
|
-
skip_after_action
|
47
|
-
skip_around_action
|
48
|
-
skip_before_action
|
49
|
-
skip_action_callback
|
50
|
-
].freeze
|
45
|
+
RESTRICT_ON_SEND = %i[skip_after_action skip_around_action skip_before_action skip_action_callback].freeze
|
51
46
|
|
52
47
|
FILTERS = RESTRICT_ON_SEND.map { |method_name| ":#{method_name}" }
|
53
48
|
|
@@ -67,11 +62,9 @@ module RuboCop
|
|
67
62
|
options = options_hash(options)
|
68
63
|
|
69
64
|
if if_and_only?(options)
|
70
|
-
add_offense(options[:if],
|
71
|
-
message: format(MSG, prefer: :only, ignore: :if))
|
65
|
+
add_offense(options[:if], message: format(MSG, prefer: :only, ignore: :if))
|
72
66
|
elsif if_and_except?(options)
|
73
|
-
add_offense(options[:except],
|
74
|
-
message: format(MSG, prefer: :if, ignore: :except))
|
67
|
+
add_offense(options[:except], message: format(MSG, prefer: :if, ignore: :except))
|
75
68
|
end
|
76
69
|
end
|
77
70
|
|
@@ -192,8 +192,7 @@ module RuboCop
|
|
192
192
|
end
|
193
193
|
return if options_ignoring_inverse_of?(options)
|
194
194
|
|
195
|
-
return unless scope?(arguments) ||
|
196
|
-
options_requiring_inverse_of?(options)
|
195
|
+
return unless scope?(arguments) || options_requiring_inverse_of?(options)
|
197
196
|
|
198
197
|
return if options_contain_inverse_of?(options)
|
199
198
|
|
@@ -206,8 +205,7 @@ module RuboCop
|
|
206
205
|
|
207
206
|
def options_requiring_inverse_of?(options)
|
208
207
|
required = options.any? do |opt|
|
209
|
-
conditions_option?(opt) ||
|
210
|
-
foreign_key_option?(opt)
|
208
|
+
conditions_option?(opt) || foreign_key_option?(opt)
|
211
209
|
end
|
212
210
|
|
213
211
|
return required if target_rails_version >= 5.2
|
@@ -227,8 +225,7 @@ module RuboCop
|
|
227
225
|
|
228
226
|
def with_options_arguments(recv, node)
|
229
227
|
blocks = node.each_ancestor(:block).select do |block|
|
230
|
-
block.send_node.command?(:with_options) &&
|
231
|
-
same_context_in_with_options?(block.arguments.first, recv)
|
228
|
+
block.send_node.command?(:with_options) && same_context_in_with_options?(block.arguments.first, recv)
|
232
229
|
end
|
233
230
|
blocks.flat_map { |n| n.send_node.arguments }
|
234
231
|
end
|
@@ -184,13 +184,9 @@ module RuboCop
|
|
184
184
|
# @return [String]
|
185
185
|
def message(methods, parent)
|
186
186
|
if methods.size == 1
|
187
|
-
format(MSG,
|
188
|
-
action: "`#{methods[0]}` is",
|
189
|
-
type: parent.type)
|
187
|
+
format(MSG, action: "`#{methods[0]}` is", type: parent.type)
|
190
188
|
else
|
191
|
-
format(MSG,
|
192
|
-
action: "`#{methods.join('`, `')}` are",
|
193
|
-
type: parent.type)
|
189
|
+
format(MSG, action: "`#{methods.join('`, `')}` are", type: parent.type)
|
194
190
|
end
|
195
191
|
end
|
196
192
|
end
|
@@ -68,10 +68,7 @@ module RuboCop
|
|
68
68
|
|
69
69
|
def append_to_rel(rel_node, corrector)
|
70
70
|
existing_rel = rel_node.children.last.value
|
71
|
-
str_range = rel_node.children.last.loc.expression.adjust(
|
72
|
-
begin_pos: 1,
|
73
|
-
end_pos: -1
|
74
|
-
)
|
71
|
+
str_range = rel_node.children.last.loc.expression.adjust(begin_pos: 1, end_pos: -1)
|
75
72
|
corrector.replace(str_range, "#{existing_rel} noopener")
|
76
73
|
end
|
77
74
|
|
@@ -21,11 +21,8 @@ module RuboCop
|
|
21
21
|
include RangeHelp
|
22
22
|
extend AutoCorrector
|
23
23
|
|
24
|
-
MSG =
|
25
|
-
|
26
|
-
RESTRICT_ON_SEND = %i[
|
27
|
-
ap p pp pretty_print print puts binwrite syswrite write write_nonblock
|
28
|
-
].freeze
|
24
|
+
MSG = "Do not write to stdout. Use Rails's logger if you want to log."
|
25
|
+
RESTRICT_ON_SEND = %i[ap p pp pretty_print print puts binwrite syswrite write write_nonblock].freeze
|
29
26
|
|
30
27
|
def_node_matcher :output?, <<~PATTERN
|
31
28
|
(send nil? {:ap :p :pp :pretty_print :print :puts} ...)
|
@@ -94,8 +94,7 @@ module RuboCop
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def duration_method?(method_name)
|
97
|
-
SINGULAR_DURATION_METHODS.key?(method_name) ||
|
98
|
-
PLURAL_DURATION_METHODS.key?(method_name)
|
97
|
+
SINGULAR_DURATION_METHODS.key?(method_name) || PLURAL_DURATION_METHODS.key?(method_name)
|
99
98
|
end
|
100
99
|
end
|
101
100
|
end
|
@@ -106,9 +106,7 @@ module RuboCop
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def message(node, receiver, other)
|
109
|
-
format(MSG,
|
110
|
-
prefer: replacement(receiver, other),
|
111
|
-
current: node.source)
|
109
|
+
format(MSG, prefer: replacement(receiver, other), current: node.source)
|
112
110
|
end
|
113
111
|
|
114
112
|
def replacement(receiver, other)
|
@@ -47,10 +47,8 @@ module RuboCop
|
|
47
47
|
extend AutoCorrector
|
48
48
|
|
49
49
|
MSG_NOT_BLANK = 'Use `%<prefer>s` instead of `%<current>s`.'
|
50
|
-
MSG_EXISTS_AND_NOT_EMPTY = 'Use `%<prefer>s` instead of '
|
51
|
-
|
52
|
-
MSG_UNLESS_BLANK = 'Use `if %<prefer>s` instead of ' \
|
53
|
-
'`%<current>s`.'
|
50
|
+
MSG_EXISTS_AND_NOT_EMPTY = 'Use `%<prefer>s` instead of `%<current>s`.'
|
51
|
+
MSG_UNLESS_BLANK = 'Use `if %<prefer>s` instead of `%<current>s`.'
|
54
52
|
RESTRICT_ON_SEND = %i[!].freeze
|
55
53
|
|
56
54
|
def_node_matcher :exists_and_not_empty?, <<~PATTERN
|
@@ -118,8 +116,7 @@ module RuboCop
|
|
118
116
|
|
119
117
|
unless_blank?(node) do |method_call, receiver|
|
120
118
|
range = unless_condition(node, method_call)
|
121
|
-
msg = format(MSG_UNLESS_BLANK, prefer: replacement(receiver),
|
122
|
-
current: range.source)
|
119
|
+
msg = format(MSG_UNLESS_BLANK, prefer: replacement(receiver), current: range.source)
|
123
120
|
add_offense(range, message: msg) do |corrector|
|
124
121
|
autocorrect(corrector, node)
|
125
122
|
end
|
@@ -39,7 +39,7 @@ module RuboCop
|
|
39
39
|
(block $(send nil? :task ...) ...)
|
40
40
|
PATTERN
|
41
41
|
|
42
|
-
def on_block(node)
|
42
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
43
43
|
task_definition?(node) do |task_method|
|
44
44
|
return if task_name(task_method) == :default
|
45
45
|
return if with_dependencies?(task_method)
|
@@ -30,11 +30,9 @@ module RuboCop
|
|
30
30
|
include RangeHelp
|
31
31
|
extend AutoCorrector
|
32
32
|
|
33
|
-
MSG_SAME =
|
34
|
-
'`allow_nil` is redundant when `allow_blank` has the same value.'
|
33
|
+
MSG_SAME = '`allow_nil` is redundant when `allow_blank` has the same value.'
|
35
34
|
|
36
|
-
MSG_ALLOW_NIL_FALSE =
|
37
|
-
'`allow_nil: false` is redundant when `allow_blank` is true.'
|
35
|
+
MSG_ALLOW_NIL_FALSE = '`allow_nil: false` is redundant when `allow_blank` is true.'
|
38
36
|
|
39
37
|
RESTRICT_ON_SEND = %i[validates].freeze
|
40
38
|
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
association_with_foreign_key(node) do |type, name, options, foreign_key_pair, foreign_key|
|
42
42
|
if redundant?(node, type, name, options, foreign_key)
|
43
43
|
add_offense(foreign_key_pair.loc.expression) do |corrector|
|
44
|
-
range = range_with_surrounding_space(
|
44
|
+
range = range_with_surrounding_space(foreign_key_pair.source_range, side: :left)
|
45
45
|
range = range_with_surrounding_comma(range, :left)
|
46
46
|
|
47
47
|
corrector.remove(range)
|
@@ -217,7 +217,7 @@ module RuboCop
|
|
217
217
|
keys.each do |key|
|
218
218
|
key_node = node.arguments.find { |arg| arg.value == key }
|
219
219
|
key_range = range_with_surrounding_space(
|
220
|
-
|
220
|
+
range_with_surrounding_comma(key_node.source_range, :right),
|
221
221
|
side: :right
|
222
222
|
)
|
223
223
|
corrector.remove(key_range)
|
@@ -226,7 +226,7 @@ module RuboCop
|
|
226
226
|
|
227
227
|
def remove_presence_option(corrector, presence)
|
228
228
|
range = range_with_surrounding_comma(
|
229
|
-
range_with_surrounding_space(
|
229
|
+
range_with_surrounding_space(presence.source_range, side: :left),
|
230
230
|
:left
|
231
231
|
)
|
232
232
|
corrector.remove(range)
|
@@ -60,15 +60,6 @@ module RuboCop
|
|
60
60
|
|
61
61
|
MSG = 'Redundant receiver in `with_options`.'
|
62
62
|
|
63
|
-
def_node_matcher :with_options?, <<~PATTERN
|
64
|
-
(block
|
65
|
-
(send nil? :with_options
|
66
|
-
(...))
|
67
|
-
(args
|
68
|
-
$_arg)
|
69
|
-
$_body)
|
70
|
-
PATTERN
|
71
|
-
|
72
63
|
def_node_search :all_block_nodes_in, <<~PATTERN
|
73
64
|
(block ...)
|
74
65
|
PATTERN
|
@@ -78,29 +69,40 @@ module RuboCop
|
|
78
69
|
PATTERN
|
79
70
|
|
80
71
|
def on_block(node)
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
93
|
-
end
|
72
|
+
return unless node.method?(:with_options)
|
73
|
+
return unless (body = node.body)
|
74
|
+
return unless all_block_nodes_in(body).count.zero?
|
75
|
+
|
76
|
+
send_nodes = all_send_nodes_in(body)
|
77
|
+
return unless redundant_receiver?(send_nodes, node)
|
78
|
+
|
79
|
+
send_nodes.each do |send_node|
|
80
|
+
receiver = send_node.receiver
|
81
|
+
add_offense(receiver.source_range) do |corrector|
|
82
|
+
autocorrect(corrector, send_node, node)
|
94
83
|
end
|
95
84
|
end
|
96
85
|
end
|
97
86
|
|
87
|
+
alias on_numblock on_block
|
88
|
+
|
98
89
|
private
|
99
90
|
|
100
|
-
def autocorrect(corrector, node)
|
101
|
-
corrector.remove(
|
102
|
-
corrector.remove(
|
103
|
-
corrector.remove(block_argument_range(
|
91
|
+
def autocorrect(corrector, send_node, node)
|
92
|
+
corrector.remove(send_node.receiver.source_range)
|
93
|
+
corrector.remove(send_node.loc.dot)
|
94
|
+
corrector.remove(block_argument_range(send_node)) unless node.numblock_type?
|
95
|
+
end
|
96
|
+
|
97
|
+
def redundant_receiver?(send_nodes, node)
|
98
|
+
proc = if node.numblock_type?
|
99
|
+
->(n) { n.receiver.lvar_type? && n.receiver.source == '_1' }
|
100
|
+
else
|
101
|
+
arg = node.arguments.first
|
102
|
+
->(n) { same_value?(arg, n.receiver) }
|
103
|
+
end
|
104
|
+
|
105
|
+
send_nodes.all?(&proc)
|
104
106
|
end
|
105
107
|
|
106
108
|
def block_argument_range(node)
|
@@ -34,12 +34,29 @@ module RuboCop
|
|
34
34
|
|
35
35
|
def on_send(node)
|
36
36
|
association_with_reflection(node) do |reflection_class_name|
|
37
|
+
return if reflection_class_name.value.send_type? && reflection_class_name.value.receiver.nil?
|
38
|
+
return if reflection_class_name.value.lvar_type? && str_assigned?(reflection_class_name)
|
39
|
+
|
37
40
|
add_offense(reflection_class_name.loc.expression)
|
38
41
|
end
|
39
42
|
end
|
40
43
|
|
41
44
|
private
|
42
45
|
|
46
|
+
def str_assigned?(reflection_class_name)
|
47
|
+
lvar = reflection_class_name.value.source
|
48
|
+
|
49
|
+
reflection_class_name.ancestors.each do |nodes|
|
50
|
+
return true if nodes.each_child_node(:lvasgn).detect do |node|
|
51
|
+
lhs, rhs = *node
|
52
|
+
|
53
|
+
lhs.to_s == lvar && ALLOWED_REFLECTION_CLASS_TYPES.include?(rhs.type)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
43
60
|
def reflection_class_value?(class_value)
|
44
61
|
if class_value.send_type?
|
45
62
|
!class_value.method?(:to_s) || class_value.receiver&.const_type?
|