rubocop-rails 2.8.0 → 2.10.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/LICENSE.txt +1 -1
- data/README.md +18 -2
- data/config/default.yml +101 -5
- data/config/obsoletion.yml +7 -0
- data/lib/rubocop/cop/mixin/active_record_helper.rb +16 -3
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
- data/lib/rubocop/cop/mixin/index_method.rb +8 -11
- data/lib/rubocop/cop/rails/action_filter.rb +10 -14
- data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
- data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +17 -12
- data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
- data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
- data/lib/rubocop/cop/rails/after_commit_override.rb +9 -2
- data/lib/rubocop/cop/rails/application_controller.rb +3 -7
- data/lib/rubocop/cop/rails/application_job.rb +2 -1
- data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
- data/lib/rubocop/cop/rails/application_record.rb +2 -7
- data/lib/rubocop/cop/rails/arel_star.rb +41 -0
- data/lib/rubocop/cop/rails/assert_not.rb +8 -10
- data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
- data/lib/rubocop/cop/rails/belongs_to.rb +10 -19
- data/lib/rubocop/cop/rails/blank.rb +31 -27
- data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
- data/lib/rubocop/cop/rails/content_tag.rb +33 -18
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
- data/lib/rubocop/cop/rails/date.rb +10 -11
- data/lib/rubocop/cop/rails/default_scope.rb +11 -4
- data/lib/rubocop/cop/rails/delegate.rb +9 -9
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +15 -12
- data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
- data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
- data/lib/rubocop/cop/rails/environment_variable_access.rb +67 -0
- data/lib/rubocop/cop/rails/exit.rb +4 -10
- data/lib/rubocop/cop/rails/file_path.rb +6 -7
- data/lib/rubocop/cop/rails/find_by.rb +13 -13
- data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
- data/lib/rubocop/cop/rails/find_each.rb +19 -18
- data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +37 -6
- data/lib/rubocop/cop/rails/helper_instance_variable.rb +29 -3
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +32 -21
- data/lib/rubocop/cop/rails/http_status.rb +7 -9
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
- data/lib/rubocop/cop/rails/index_by.rb +3 -2
- data/lib/rubocop/cop/rails/index_with.rb +3 -2
- data/lib/rubocop/cop/rails/inquiry.rb +4 -3
- data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
- data/lib/rubocop/cop/rails/link_to_blank.rb +25 -23
- data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
- data/lib/rubocop/cop/rails/match_route.rb +14 -13
- data/lib/rubocop/cop/rails/negate_include.rb +10 -8
- data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
- data/lib/rubocop/cop/rails/order_by_id.rb +1 -2
- data/lib/rubocop/cop/rails/output.rb +5 -2
- data/lib/rubocop/cop/rails/output_safety.rb +3 -2
- data/lib/rubocop/cop/rails/pick.rb +14 -12
- data/lib/rubocop/cop/rails/pluck.rb +6 -9
- data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
- data/lib/rubocop/cop/rails/pluck_in_where.rb +7 -7
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
- data/lib/rubocop/cop/rails/presence.rb +12 -13
- data/lib/rubocop/cop/rails/present.rb +30 -24
- data/lib/rubocop/cop/rails/rake_environment.rb +8 -10
- data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
- data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
- data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
- data/lib/rubocop/cop/rails/reflection_class_name.rb +17 -3
- data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
- data/lib/rubocop/cop/rails/relative_date_constant.rb +30 -21
- data/lib/rubocop/cop/rails/render_inline.rb +2 -1
- data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
- data/lib/rubocop/cop/rails/request_referer.rb +7 -7
- data/lib/rubocop/cop/rails/require_dependency.rb +38 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +4 -8
- data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +75 -0
- data/lib/rubocop/cop/rails/safe_navigation.rb +30 -11
- data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
- data/lib/rubocop/cop/rails/save_bang.rb +17 -20
- data/lib/rubocop/cop/rails/scope_args.rb +2 -1
- data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
- data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
- data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +5 -6
- data/lib/rubocop/cop/rails/time_zone.rb +35 -25
- data/lib/rubocop/cop/rails/time_zone_assignment.rb +37 -0
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +4 -6
- data/lib/rubocop/cop/rails/unique_validation_without_index.rb +4 -2
- data/lib/rubocop/cop/rails/unknown_env.rb +3 -3
- data/lib/rubocop/cop/rails/validation.rb +15 -14
- data/lib/rubocop/cop/rails/where_equals.rb +98 -0
- data/lib/rubocop/cop/rails/where_exists.rb +19 -13
- data/lib/rubocop/cop/rails/where_not.rb +14 -19
- data/lib/rubocop/cop/rails_cops.rb +8 -0
- data/lib/rubocop/rails.rb +2 -0
- data/lib/rubocop/rails/schema_loader.rb +4 -4
- data/lib/rubocop/rails/schema_loader/schema.rb +2 -4
- data/lib/rubocop/rails/version.rb +5 -1
- metadata +29 -14
@@ -20,8 +20,11 @@ module RuboCop
|
|
20
20
|
# match 'photos/:id', to: 'photos#show', via: [:get, :post]
|
21
21
|
# match 'photos/:id', to: 'photos#show', via: :all
|
22
22
|
#
|
23
|
-
class MatchRoute <
|
23
|
+
class MatchRoute < Base
|
24
|
+
extend AutoCorrector
|
25
|
+
|
24
26
|
MSG = 'Use `%<http_method>s` instead of `match` to define a route.'
|
27
|
+
RESTRICT_ON_SEND = %i[match].freeze
|
25
28
|
HTTP_METHODS = %i[get post put patch delete].freeze
|
26
29
|
|
27
30
|
def_node_matcher :match_method_call?, <<~PATTERN
|
@@ -35,30 +38,28 @@ module RuboCop
|
|
35
38
|
options_node = path_node.hash_type? ? path_node : options_node.first
|
36
39
|
|
37
40
|
if options_node.nil?
|
38
|
-
|
39
|
-
add_offense(node, message: message)
|
41
|
+
register_offense(node, 'get')
|
40
42
|
else
|
41
43
|
via = extract_via(options_node)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
44
|
+
return unless via.size == 1 && http_method?(via.first)
|
45
|
+
|
46
|
+
register_offense(node, via.first)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
private
|
52
|
+
|
53
|
+
def register_offense(node, http_method)
|
54
|
+
add_offense(node, message: format(MSG, http_method: http_method)) do |corrector|
|
55
|
+
match_method_call?(node) do |path_node, options_node|
|
56
|
+
options_node = options_node.first
|
53
57
|
|
54
|
-
lambda do |corrector|
|
55
58
|
corrector.replace(node, replacement(path_node, options_node))
|
56
59
|
end
|
57
60
|
end
|
58
61
|
end
|
59
62
|
|
60
|
-
private
|
61
|
-
|
62
63
|
def_node_matcher :routes_draw?, <<~PATTERN
|
63
64
|
(send (send _ :routes) :draw)
|
64
65
|
PATTERN
|
@@ -6,6 +6,9 @@ module RuboCop
|
|
6
6
|
# This cop enforces the use of `collection.exclude?(obj)`
|
7
7
|
# over `!collection.include?(obj)`.
|
8
8
|
#
|
9
|
+
# It is marked as unsafe by default because false positive will occur for
|
10
|
+
# a receiver object that do not have `exclude?` method. (e.g. `IPAddr`)
|
11
|
+
#
|
9
12
|
# @example
|
10
13
|
# # bad
|
11
14
|
# !array.include?(2)
|
@@ -15,22 +18,21 @@ module RuboCop
|
|
15
18
|
# array.exclude?(2)
|
16
19
|
# hash.exclude?(:key)
|
17
20
|
#
|
18
|
-
class NegateInclude <
|
21
|
+
class NegateInclude < Base
|
22
|
+
extend AutoCorrector
|
23
|
+
|
19
24
|
MSG = 'Use `.exclude?` and remove the negation part.'
|
25
|
+
RESTRICT_ON_SEND = %i[!].freeze
|
20
26
|
|
21
27
|
def_node_matcher :negate_include_call?, <<~PATTERN
|
22
28
|
(send (send $_ :include? $_) :!)
|
23
29
|
PATTERN
|
24
30
|
|
25
31
|
def on_send(node)
|
26
|
-
|
27
|
-
end
|
32
|
+
return unless (receiver, obj = negate_include_call?(node))
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
lambda do |corrector|
|
32
|
-
corrector.replace(node, "#{receiver.source}.exclude?(#{obj.source})")
|
33
|
-
end
|
34
|
+
add_offense(node) do |corrector|
|
35
|
+
corrector.replace(node, "#{receiver.source}.exclude?(#{obj.source})")
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
@@ -16,8 +16,9 @@ module RuboCop
|
|
16
16
|
# add_column :users, :name, :string, null: false, default: ''
|
17
17
|
# add_reference :products, :category
|
18
18
|
# add_reference :products, :category, null: false, default: 1
|
19
|
-
class NotNullColumn <
|
19
|
+
class NotNullColumn < Base
|
20
20
|
MSG = 'Do not add a NOT NULL column without a default value.'
|
21
|
+
RESTRICT_ON_SEND = %i[add_column add_reference].freeze
|
21
22
|
|
22
23
|
def_node_matcher :add_not_null_column?, <<~PATTERN
|
23
24
|
(send nil? :add_column _ _ _ (hash $...))
|
@@ -25,6 +25,7 @@ module RuboCop
|
|
25
25
|
|
26
26
|
MSG = 'Do not use the `id` column for ordering. '\
|
27
27
|
'Use a timestamp column to order chronologically.'
|
28
|
+
RESTRICT_ON_SEND = %i[order].freeze
|
28
29
|
|
29
30
|
def_node_matcher :order_by_id?, <<~PATTERN
|
30
31
|
(send _ :order
|
@@ -37,8 +38,6 @@ module RuboCop
|
|
37
38
|
PATTERN
|
38
39
|
|
39
40
|
def on_send(node)
|
40
|
-
return unless node.method?(:order)
|
41
|
-
|
42
41
|
add_offense(offense_range(node)) if order_by_id?(node)
|
43
42
|
end
|
44
43
|
|
@@ -13,9 +13,12 @@ module RuboCop
|
|
13
13
|
#
|
14
14
|
# # good
|
15
15
|
# Rails.logger.debug 'A debug message'
|
16
|
-
class Output <
|
16
|
+
class Output < Base
|
17
17
|
MSG = 'Do not write to stdout. ' \
|
18
18
|
"Use Rails's logger if you want to log."
|
19
|
+
RESTRICT_ON_SEND = %i[
|
20
|
+
ap p pp pretty_print print puts binwrite syswrite write write_nonblock
|
21
|
+
].freeze
|
19
22
|
|
20
23
|
def_node_matcher :output?, <<~PATTERN
|
21
24
|
(send nil? {:ap :p :pp :pretty_print :print :puts} ...)
|
@@ -35,7 +38,7 @@ module RuboCop
|
|
35
38
|
return unless (output?(node) || io_output?(node)) &&
|
36
39
|
node.arguments?
|
37
40
|
|
38
|
-
add_offense(node
|
41
|
+
add_offense(node.loc.selector)
|
39
42
|
end
|
40
43
|
|
41
44
|
private
|
@@ -62,8 +62,9 @@ module RuboCop
|
|
62
62
|
# safe_join([user_content, " ", content_tag(:span, user_content)])
|
63
63
|
# # => ActiveSupport::SafeBuffer
|
64
64
|
# # "<b>hi</b> <span><b>hi</b></span>"
|
65
|
-
class OutputSafety <
|
65
|
+
class OutputSafety < Base
|
66
66
|
MSG = 'Tagging a string as html safe may be a security risk.'
|
67
|
+
RESTRICT_ON_SEND = %i[html_safe raw safe_concat].freeze
|
67
68
|
|
68
69
|
def on_send(node)
|
69
70
|
return if non_interpolated_string?(node)
|
@@ -72,7 +73,7 @@ module RuboCop
|
|
72
73
|
looks_like_rails_raw?(node) ||
|
73
74
|
looks_like_rails_safe_concat?(node)
|
74
75
|
|
75
|
-
add_offense(node
|
76
|
+
add_offense(node.loc.selector)
|
76
77
|
end
|
77
78
|
alias on_csend on_send
|
78
79
|
|
@@ -17,10 +17,12 @@ module RuboCop
|
|
17
17
|
# # good
|
18
18
|
# Model.pick(:a)
|
19
19
|
# [{ a: :b, c: :d }].pick(:a, :b)
|
20
|
-
class Pick <
|
20
|
+
class Pick < Base
|
21
|
+
extend AutoCorrector
|
21
22
|
extend TargetRailsVersion
|
22
23
|
|
23
24
|
MSG = 'Prefer `pick(%<args>s)` over `pluck(%<args>s).first`.'
|
25
|
+
RESTRICT_ON_SEND = %i[first].freeze
|
24
26
|
|
25
27
|
minimum_target_rails_version 6.0
|
26
28
|
|
@@ -30,24 +32,24 @@ module RuboCop
|
|
30
32
|
|
31
33
|
def on_send(node)
|
32
34
|
pick_candidate?(node) do
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
receiver = node.receiver
|
36
|
+
receiver_selector = receiver.loc.selector
|
37
|
+
node_selector = node.loc.selector
|
38
|
+
range = receiver_selector.join(node_selector)
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
+
add_offense(range, message: message(receiver)) do |corrector|
|
41
|
+
first_range = receiver.source_range.end.join(node_selector)
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
43
|
+
corrector.remove(first_range)
|
44
|
+
corrector.replace(receiver_selector, 'pick')
|
45
|
+
end
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
49
|
private
|
48
50
|
|
49
|
-
def message(
|
50
|
-
format(MSG, args:
|
51
|
+
def message(receiver)
|
52
|
+
format(MSG, args: receiver.arguments.map(&:source).join(', '))
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
@@ -17,7 +17,8 @@ module RuboCop
|
|
17
17
|
# # good
|
18
18
|
# Post.published.pluck(:title)
|
19
19
|
# [{ a: :b, c: :d }].pluck(:a)
|
20
|
-
class Pluck <
|
20
|
+
class Pluck < Base
|
21
|
+
extend AutoCorrector
|
21
22
|
extend TargetRailsVersion
|
22
23
|
|
23
24
|
MSG = 'Prefer `pluck(:%<value>s)` over `%<method>s { |%<argument>s| %<element>s[:%<value>s] }`.'
|
@@ -32,15 +33,11 @@ module RuboCop
|
|
32
33
|
pluck_candidate?(node) do |method, argument, element, value|
|
33
34
|
next unless argument == element
|
34
35
|
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def autocorrect(node)
|
40
|
-
_method, _argument, _element, value = pluck_candidate?(node)
|
36
|
+
message = message(method, argument, element, value)
|
41
37
|
|
42
|
-
|
43
|
-
|
38
|
+
add_offense(offense_range(node), message: message) do |corrector|
|
39
|
+
corrector.replace(offense_range(node), "pluck(:#{value})")
|
40
|
+
end
|
44
41
|
end
|
45
42
|
end
|
46
43
|
|
@@ -22,11 +22,13 @@ module RuboCop
|
|
22
22
|
# ids
|
23
23
|
# end
|
24
24
|
#
|
25
|
-
class PluckId <
|
25
|
+
class PluckId < Base
|
26
26
|
include RangeHelp
|
27
27
|
include ActiveRecordHelper
|
28
|
+
extend AutoCorrector
|
28
29
|
|
29
30
|
MSG = 'Use `ids` instead of `%<bad_method>s`.'
|
31
|
+
RESTRICT_ON_SEND = %i[pluck].freeze
|
30
32
|
|
31
33
|
def_node_matcher :pluck_id_call?, <<~PATTERN
|
32
34
|
(send _ :pluck {(sym :id) (send nil? :primary_key)})
|
@@ -38,11 +40,7 @@ module RuboCop
|
|
38
40
|
range = offense_range(node)
|
39
41
|
message = format(MSG, bad_method: range.source)
|
40
42
|
|
41
|
-
add_offense(
|
42
|
-
end
|
43
|
-
|
44
|
-
def autocorrect(node)
|
45
|
-
lambda do |corrector|
|
43
|
+
add_offense(range, message: message) do |corrector|
|
46
44
|
corrector.replace(offense_range(node), 'ids')
|
47
45
|
end
|
48
46
|
end
|
@@ -34,22 +34,22 @@ module RuboCop
|
|
34
34
|
# # bad
|
35
35
|
# Post.where(user_id: active_users.pluck(:id))
|
36
36
|
#
|
37
|
-
class PluckInWhere <
|
37
|
+
class PluckInWhere < Base
|
38
38
|
include ActiveRecordHelper
|
39
39
|
include ConfigurableEnforcedStyle
|
40
|
+
extend AutoCorrector
|
40
41
|
|
41
42
|
MSG = 'Use `select` instead of `pluck` within `where` query method.'
|
43
|
+
RESTRICT_ON_SEND = %i[pluck].freeze
|
42
44
|
|
43
45
|
def on_send(node)
|
44
|
-
return unless
|
46
|
+
return unless in_where?(node)
|
45
47
|
return if style == :conservative && !root_receiver(node)&.const_type?
|
46
48
|
|
47
|
-
|
48
|
-
end
|
49
|
+
range = node.loc.selector
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
corrector.replace(node.loc.selector, 'select')
|
51
|
+
add_offense(range) do |corrector|
|
52
|
+
corrector.replace(range, 'select')
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -14,7 +14,9 @@ module RuboCop
|
|
14
14
|
# # good
|
15
15
|
# 3.days.ago
|
16
16
|
# 1.month.ago
|
17
|
-
class PluralizationGrammar <
|
17
|
+
class PluralizationGrammar < Base
|
18
|
+
extend AutoCorrector
|
19
|
+
|
18
20
|
SINGULAR_DURATION_METHODS = { second: :seconds,
|
19
21
|
minute: :minutes,
|
20
22
|
hour: :hours,
|
@@ -24,21 +26,18 @@ module RuboCop
|
|
24
26
|
month: :months,
|
25
27
|
year: :years }.freeze
|
26
28
|
|
29
|
+
RESTRICT_ON_SEND = SINGULAR_DURATION_METHODS.keys + SINGULAR_DURATION_METHODS.values
|
30
|
+
|
27
31
|
PLURAL_DURATION_METHODS = SINGULAR_DURATION_METHODS.invert.freeze
|
28
32
|
|
29
33
|
MSG = 'Prefer `%<number>s.%<correct>s`.'
|
30
34
|
|
31
35
|
def on_send(node)
|
32
|
-
return unless duration_method?(node.method_name)
|
33
|
-
return unless literal_number?(node.receiver)
|
36
|
+
return unless duration_method?(node.method_name) && literal_number?(node.receiver) && offense?(node)
|
34
37
|
|
35
|
-
|
36
|
-
|
37
|
-
add_offense(node)
|
38
|
-
end
|
38
|
+
number, = *node.receiver
|
39
39
|
|
40
|
-
|
41
|
-
lambda do |corrector|
|
40
|
+
add_offense(node, message: message(number, node.method_name)) do |corrector|
|
42
41
|
method_name = node.loc.selector.source
|
43
42
|
|
44
43
|
corrector.replace(node.loc.selector, correct_method(method_name))
|
@@ -47,11 +46,8 @@ module RuboCop
|
|
47
46
|
|
48
47
|
private
|
49
48
|
|
50
|
-
def message(
|
51
|
-
number,
|
52
|
-
|
53
|
-
format(MSG, number: number,
|
54
|
-
correct: correct_method(node.method_name.to_s))
|
49
|
+
def message(number, method_name)
|
50
|
+
format(MSG, number: number, correct: correct_method(method_name))
|
55
51
|
end
|
56
52
|
|
57
53
|
def correct_method(method_name)
|
@@ -37,8 +37,9 @@ module RuboCop
|
|
37
37
|
#
|
38
38
|
# # good
|
39
39
|
# a.presence || b
|
40
|
-
class Presence <
|
40
|
+
class Presence < Base
|
41
41
|
include RangeHelp
|
42
|
+
extend AutoCorrector
|
42
43
|
|
43
44
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
44
45
|
|
@@ -76,28 +77,26 @@ module RuboCop
|
|
76
77
|
return if ignore_if_node?(node)
|
77
78
|
|
78
79
|
redundant_receiver_and_other(node) do |receiver, other|
|
79
|
-
|
80
|
+
return if ignore_other_node?(other) || receiver.nil?
|
81
|
+
|
82
|
+
register_offense(node, receiver, other)
|
80
83
|
end
|
81
84
|
|
82
85
|
redundant_negative_receiver_and_other(node) do |receiver, other|
|
83
|
-
|
86
|
+
return if ignore_other_node?(other) || receiver.nil?
|
87
|
+
|
88
|
+
register_offense(node, receiver, other)
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
87
|
-
|
88
|
-
lambda do |corrector|
|
89
|
-
redundant_receiver_and_other(node) do |receiver, other|
|
90
|
-
corrector.replace(node.source_range, replacement(receiver, other))
|
91
|
-
end
|
92
|
+
private
|
92
93
|
|
93
|
-
|
94
|
-
|
95
|
-
|
94
|
+
def register_offense(node, receiver, other)
|
95
|
+
add_offense(node, message: message(node, receiver, other)) do |corrector|
|
96
|
+
corrector.replace(node.source_range, replacement(receiver, other))
|
96
97
|
end
|
97
98
|
end
|
98
99
|
|
99
|
-
private
|
100
|
-
|
101
100
|
def ignore_if_node?(node)
|
102
101
|
node.elsif?
|
103
102
|
end
|
@@ -43,12 +43,15 @@ module RuboCop
|
|
43
43
|
#
|
44
44
|
# # good
|
45
45
|
# something if foo.present?
|
46
|
-
class Present <
|
46
|
+
class Present < Base
|
47
|
+
extend AutoCorrector
|
48
|
+
|
47
49
|
MSG_NOT_BLANK = 'Use `%<prefer>s` instead of `%<current>s`.'
|
48
50
|
MSG_EXISTS_AND_NOT_EMPTY = 'Use `%<prefer>s` instead of ' \
|
49
51
|
'`%<current>s`.'
|
50
52
|
MSG_UNLESS_BLANK = 'Use `if %<prefer>s` instead of ' \
|
51
53
|
'`%<current>s`.'
|
54
|
+
RESTRICT_ON_SEND = %i[!].freeze
|
52
55
|
|
53
56
|
def_node_matcher :exists_and_not_empty?, <<~PATTERN
|
54
57
|
(and
|
@@ -74,10 +77,11 @@ module RuboCop
|
|
74
77
|
return unless cop_config['NotBlank']
|
75
78
|
|
76
79
|
not_blank?(node) do |receiver|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
80
|
+
message = format(MSG_NOT_BLANK, prefer: replacement(receiver), current: node.source)
|
81
|
+
|
82
|
+
add_offense(node, message: message) do |corrector|
|
83
|
+
autocorrect(corrector, node)
|
84
|
+
end
|
81
85
|
end
|
82
86
|
end
|
83
87
|
|
@@ -87,10 +91,11 @@ module RuboCop
|
|
87
91
|
exists_and_not_empty?(node) do |var1, var2|
|
88
92
|
return unless var1 == var2
|
89
93
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
+
message = format(MSG_EXISTS_AND_NOT_EMPTY, prefer: replacement(var1), current: node.source)
|
95
|
+
|
96
|
+
add_offense(node, message: message) do |corrector|
|
97
|
+
autocorrect(corrector, node)
|
98
|
+
end
|
94
99
|
end
|
95
100
|
end
|
96
101
|
|
@@ -100,7 +105,9 @@ module RuboCop
|
|
100
105
|
exists_and_not_empty?(node) do |var1, var2|
|
101
106
|
return unless var1 == var2
|
102
107
|
|
103
|
-
add_offense(node, message: MSG_EXISTS_AND_NOT_EMPTY)
|
108
|
+
add_offense(node, message: MSG_EXISTS_AND_NOT_EMPTY) do |corrector|
|
109
|
+
autocorrect(corrector, node)
|
110
|
+
end
|
104
111
|
end
|
105
112
|
end
|
106
113
|
|
@@ -113,25 +120,24 @@ module RuboCop
|
|
113
120
|
range = unless_condition(node, method_call)
|
114
121
|
msg = format(MSG_UNLESS_BLANK, prefer: replacement(receiver),
|
115
122
|
current: range.source)
|
116
|
-
add_offense(
|
123
|
+
add_offense(range, message: msg) do |corrector|
|
124
|
+
autocorrect(corrector, node)
|
125
|
+
end
|
117
126
|
end
|
118
127
|
end
|
119
128
|
|
120
|
-
def autocorrect(node)
|
121
|
-
|
122
|
-
method_call, variable1 = unless_blank?(node)
|
123
|
-
|
124
|
-
if method_call
|
125
|
-
corrector.replace(node.loc.keyword, 'if')
|
126
|
-
range = method_call.loc.expression
|
127
|
-
else
|
128
|
-
variable1, _variable2 =
|
129
|
-
exists_and_not_empty?(node) || not_blank?(node)
|
130
|
-
range = node.loc.expression
|
131
|
-
end
|
129
|
+
def autocorrect(corrector, node)
|
130
|
+
method_call, variable1 = unless_blank?(node)
|
132
131
|
|
133
|
-
|
132
|
+
if method_call
|
133
|
+
corrector.replace(node.loc.keyword, 'if')
|
134
|
+
range = method_call.loc.expression
|
135
|
+
else
|
136
|
+
variable1, _variable2 = exists_and_not_empty?(node) || not_blank?(node)
|
137
|
+
range = node.loc.expression
|
134
138
|
end
|
139
|
+
|
140
|
+
corrector.replace(range, replacement(variable1))
|
135
141
|
end
|
136
142
|
|
137
143
|
private
|