rubocop-rails 2.17.0 → 2.17.3
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 +4 -4
- data/lib/rubocop/cop/mixin/active_record_helper.rb +2 -2
- data/lib/rubocop/cop/mixin/index_method.rb +1 -1
- data/lib/rubocop/cop/mixin/migrations_helper.rb +1 -1
- data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +15 -10
- data/lib/rubocop/cop/rails/action_controller_test_case.rb +1 -1
- data/lib/rubocop/cop/rails/action_order.rb +39 -3
- data/lib/rubocop/cop/rails/application_controller.rb +1 -1
- data/lib/rubocop/cop/rails/application_job.rb +1 -1
- data/lib/rubocop/cop/rails/application_mailer.rb +1 -1
- data/lib/rubocop/cop/rails/application_record.rb +1 -1
- data/lib/rubocop/cop/rails/content_tag.rb +1 -1
- data/lib/rubocop/cop/rails/dot_separated_keys.rb +1 -1
- data/lib/rubocop/cop/rails/duration_arithmetic.rb +2 -2
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +16 -6
- data/lib/rubocop/cop/rails/file_path.rb +3 -3
- data/lib/rubocop/cop/rails/freeze_time.rb +7 -5
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -1
- data/lib/rubocop/cop/rails/helper_instance_variable.rb +1 -1
- data/lib/rubocop/cop/rails/http_status.rb +1 -6
- data/lib/rubocop/cop/rails/i18n_lazy_lookup.rb +2 -0
- data/lib/rubocop/cop/rails/index_by.rb +1 -1
- data/lib/rubocop/cop/rails/index_with.rb +1 -1
- data/lib/rubocop/cop/rails/mailer_name.rb +3 -3
- data/lib/rubocop/cop/rails/migration_class_name.rb +1 -1
- data/lib/rubocop/cop/rails/output.rb +1 -1
- data/lib/rubocop/cop/rails/pluck.rb +29 -10
- data/lib/rubocop/cop/rails/require_dependency.rb +1 -1
- data/lib/rubocop/cop/rails/root_pathname_methods.rb +18 -7
- data/lib/rubocop/cop/rails/short_i18n.rb +1 -1
- data/lib/rubocop/cop/rails/skips_model_validations.rb +1 -1
- data/lib/rubocop/cop/rails/time_zone_assignment.rb +1 -1
- data/lib/rubocop/cop/rails/to_s_with_argument.rb +38 -1
- data/lib/rubocop/cop/rails/where_not_with_multiple_conditions.rb +1 -1
- data/lib/rubocop/rails/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1cd420a9b6ec0e14a26063533cf9db61a81a43e44bec26a8b98e577cf761e49
|
4
|
+
data.tar.gz: 73918575c04e0f9ee8390d3efc0a4eb49b1cb4093695ecbafddbf995c406869d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93fffc6d3f6cbb781692725c13eb6f049e3106f2fb7ccb43a48fdf7c0d85a189914740d2ef743b0642eaa94ae0fc584ec1a32be53095a12167b3c02db2b035d4
|
7
|
+
data.tar.gz: 05ac2a5767f2c65437629fa623b3b4506547227c5b608a7ebc4e29a91b831e794ac6ee7c62a55b1573f3b228d40b6aaaedbda1fb7b81481c51f9c0df6884f389
|
data/config/default.yml
CHANGED
@@ -73,7 +73,7 @@ Rails/ActionControllerFlashBeforeRender:
|
|
73
73
|
StyleGuide: 'https://rails.rubystyle.guide/#flash-before-render'
|
74
74
|
Reference: 'https://api.rubyonrails.org/classes/ActionController/FlashBeforeRender.html'
|
75
75
|
Enabled: 'pending'
|
76
|
-
|
76
|
+
SafeAutoCorrect: false
|
77
77
|
VersionAdded: '2.16'
|
78
78
|
|
79
79
|
Rails/ActionControllerTestCase:
|
@@ -81,7 +81,7 @@ Rails/ActionControllerTestCase:
|
|
81
81
|
StyleGuide: 'https://rails.rubystyle.guide/#integration-testing'
|
82
82
|
Reference: 'https://api.rubyonrails.org/classes/ActionController/TestCase.html'
|
83
83
|
Enabled: 'pending'
|
84
|
-
|
84
|
+
SafeAutoCorrect: false
|
85
85
|
VersionAdded: '2.14'
|
86
86
|
Include:
|
87
87
|
- '**/test/**/*.rb'
|
@@ -540,7 +540,7 @@ Rails/I18nLazyLookup:
|
|
540
540
|
Enabled: pending
|
541
541
|
VersionAdded: '2.14'
|
542
542
|
Include:
|
543
|
-
- 'controllers
|
543
|
+
- 'app/controllers/**/*.rb'
|
544
544
|
|
545
545
|
Rails/I18nLocaleAssignment:
|
546
546
|
Description: 'Prefer the usage of `I18n.with_locale` instead of manually updating `I18n.locale` value.'
|
@@ -873,7 +873,7 @@ Rails/RootJoinChain:
|
|
873
873
|
Rails/RootPathnameMethods:
|
874
874
|
Description: 'Use `Rails.root` IO methods instead of passing it to `File`.'
|
875
875
|
Enabled: pending
|
876
|
-
|
876
|
+
SafeAutoCorrect: false
|
877
877
|
VersionAdded: '2.16'
|
878
878
|
|
879
879
|
Rails/RootPublicPath:
|
@@ -10,8 +10,8 @@ module RuboCop
|
|
10
10
|
|
11
11
|
def_node_matcher :active_record?, <<~PATTERN
|
12
12
|
{
|
13
|
-
(const nil? :ApplicationRecord)
|
14
|
-
(const (const nil? :ActiveRecord) :Base)
|
13
|
+
(const {nil? cbase} :ApplicationRecord)
|
14
|
+
(const (const {nil? cbase} :ActiveRecord) :Base)
|
15
15
|
}
|
16
16
|
PATTERN
|
17
17
|
|
@@ -134,7 +134,7 @@ module RuboCop
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def self.from_hash_brackets_map(node, match)
|
137
|
-
new(match, node.children.last,
|
137
|
+
new(match, node.children.last, "#{node.receiver.source}[".length, ']'.length)
|
138
138
|
end
|
139
139
|
|
140
140
|
def strip_prefix_and_suffix(node, corrector)
|
@@ -37,14 +37,14 @@ module RuboCop
|
|
37
37
|
^(send (send nil? :flash) :[]= ...)
|
38
38
|
PATTERN
|
39
39
|
|
40
|
-
def_node_search :
|
41
|
-
(send nil? :
|
40
|
+
def_node_search :render?, <<~PATTERN
|
41
|
+
(send nil? :render ...)
|
42
42
|
PATTERN
|
43
43
|
|
44
44
|
def_node_search :action_controller?, <<~PATTERN
|
45
45
|
{
|
46
|
-
(const nil? :ApplicationController)
|
47
|
-
(const (const nil? :ActionController) :Base)
|
46
|
+
(const {nil? cbase} :ApplicationController)
|
47
|
+
(const (const {nil? cbase} :ActionController) :Base)
|
48
48
|
}
|
49
49
|
PATTERN
|
50
50
|
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
53
53
|
def on_send(flash_node)
|
54
54
|
return unless flash_assignment?(flash_node)
|
55
55
|
|
56
|
-
return
|
56
|
+
return unless followed_by_render?(flash_node)
|
57
57
|
|
58
58
|
return unless instance_method_or_block?(flash_node)
|
59
59
|
|
@@ -66,13 +66,18 @@ module RuboCop
|
|
66
66
|
|
67
67
|
private
|
68
68
|
|
69
|
-
def
|
69
|
+
def followed_by_render?(flash_node)
|
70
70
|
flash_assigment_node = find_ancestor(flash_node, type: :send)
|
71
|
-
context = flash_assigment_node
|
71
|
+
context = flash_assigment_node
|
72
|
+
if (if_node = context.each_ancestor(:if).first)
|
73
|
+
context = if_node
|
74
|
+
elsif context.right_siblings.empty?
|
75
|
+
return true
|
76
|
+
end
|
77
|
+
context = context.right_siblings
|
72
78
|
|
73
|
-
|
74
|
-
|
75
|
-
index > flash_index && redirect_to?(node)
|
79
|
+
context.compact.any? do |node|
|
80
|
+
render?(node)
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
@@ -6,7 +6,8 @@ module RuboCop
|
|
6
6
|
# Enforces consistent ordering of the standard Rails RESTful controller actions.
|
7
7
|
#
|
8
8
|
# The cop is configurable and can enforce any ordering of the standard actions.
|
9
|
-
# All other methods are ignored.
|
9
|
+
# All other methods are ignored. So, the actions specified in `ExpectedOrder` should be
|
10
|
+
# defined before actions not specified.
|
10
11
|
#
|
11
12
|
# [source,yaml]
|
12
13
|
# ----
|
@@ -35,6 +36,7 @@ module RuboCop
|
|
35
36
|
extend AutoCorrector
|
36
37
|
include VisibilityHelp
|
37
38
|
include DefNode
|
39
|
+
include RangeHelp
|
38
40
|
|
39
41
|
MSG = 'Action `%<current>s` should appear before `%<previous>s`.'
|
40
42
|
|
@@ -71,9 +73,43 @@ module RuboCop
|
|
71
73
|
current: current.method_name
|
72
74
|
)
|
73
75
|
add_offense(current, message: message) do |corrector|
|
74
|
-
|
75
|
-
|
76
|
+
current = correction_target(current)
|
77
|
+
previous = correction_target(previous)
|
78
|
+
|
79
|
+
swap_range(corrector, current, previous)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def correction_target(def_node)
|
84
|
+
range_with_comments_and_lines(def_node.each_ancestor(:if).first || def_node)
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_range(range1, range2)
|
88
|
+
range1.with(
|
89
|
+
begin_pos: [range1.begin_pos, range2.begin_pos].min,
|
90
|
+
end_pos: [range1.end_pos, range2.end_pos].max
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
def range_with_comments(node)
|
95
|
+
ranges = [
|
96
|
+
node,
|
97
|
+
*processed_source.ast_with_comments[node]
|
98
|
+
].map do |element|
|
99
|
+
element.location.expression
|
76
100
|
end
|
101
|
+
ranges.reduce do |result, range|
|
102
|
+
add_range(result, range)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def range_with_comments_and_lines(node)
|
107
|
+
range_by_whole_lines(range_with_comments(node), include_final_newline: true)
|
108
|
+
end
|
109
|
+
|
110
|
+
def swap_range(corrector, range1, range2)
|
111
|
+
corrector.insert_before(range2, range1.source)
|
112
|
+
corrector.remove(range1)
|
77
113
|
end
|
78
114
|
end
|
79
115
|
end
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
|
26
26
|
MSG = 'Controllers should subclass `ApplicationController`.'
|
27
27
|
SUPERCLASS = 'ApplicationController'
|
28
|
-
BASE_PATTERN = '(const (const nil? :ActionController) :Base)'
|
28
|
+
BASE_PATTERN = '(const (const {nil? cbase} :ActionController) :Base)'
|
29
29
|
|
30
30
|
# rubocop:disable Layout/ClassStructure
|
31
31
|
include RuboCop::Cop::EnforceSuperclass
|
@@ -28,7 +28,7 @@ module RuboCop
|
|
28
28
|
|
29
29
|
MSG = 'Jobs should subclass `ApplicationJob`.'
|
30
30
|
SUPERCLASS = 'ApplicationJob'
|
31
|
-
BASE_PATTERN = '(const (const nil? :ActiveJob) :Base)'
|
31
|
+
BASE_PATTERN = '(const (const {nil? cbase} :ActiveJob) :Base)'
|
32
32
|
|
33
33
|
# rubocop:disable Layout/ClassStructure
|
34
34
|
include RuboCop::Cop::EnforceSuperclass
|
@@ -28,7 +28,7 @@ module RuboCop
|
|
28
28
|
|
29
29
|
MSG = 'Mailers should subclass `ApplicationMailer`.'
|
30
30
|
SUPERCLASS = 'ApplicationMailer'
|
31
|
-
BASE_PATTERN = '(const (const nil? :ActionMailer) :Base)'
|
31
|
+
BASE_PATTERN = '(const (const {nil? cbase} :ActionMailer) :Base)'
|
32
32
|
|
33
33
|
# rubocop:disable Layout/ClassStructure
|
34
34
|
include RuboCop::Cop::EnforceSuperclass
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
MSG = 'Models should subclass `ApplicationRecord`.'
|
31
31
|
SUPERCLASS = 'ApplicationRecord'
|
32
|
-
BASE_PATTERN = '(const (const nil? :ActiveRecord) :Base)'
|
32
|
+
BASE_PATTERN = '(const (const {nil? cbase} :ActiveRecord) :Base)'
|
33
33
|
|
34
34
|
# rubocop:disable Layout/ClassStructure
|
35
35
|
include RuboCop::Cop::EnforceSuperclass
|
@@ -81,7 +81,7 @@ module RuboCop
|
|
81
81
|
def allowed_name?(argument)
|
82
82
|
return false unless argument.str_type? || argument.sym_type?
|
83
83
|
|
84
|
-
!/^[a-zA-Z
|
84
|
+
!/^[a-zA-Z-][a-zA-Z\-0-9]*$/.match?(argument.value)
|
85
85
|
end
|
86
86
|
|
87
87
|
def correction_range(node)
|
@@ -24,7 +24,7 @@ module RuboCop
|
|
24
24
|
TRANSLATE_METHODS = %i[translate t].freeze
|
25
25
|
|
26
26
|
def_node_matcher :translate_with_scope?, <<~PATTERN
|
27
|
-
(send {nil? (const nil? :I18n)} {:translate :t} ${sym_type? str_type?}
|
27
|
+
(send {nil? (const {nil? cbase} :I18n)} {:translate :t} ${sym_type? str_type?}
|
28
28
|
(hash <$(pair (sym :scope) ${array_type? sym_type?}) ...>)
|
29
29
|
)
|
30
30
|
PATTERN
|
@@ -70,8 +70,8 @@ module RuboCop
|
|
70
70
|
# @return [Boolean] true if matches
|
71
71
|
def_node_matcher :time_current?, <<~PATTERN
|
72
72
|
{
|
73
|
-
(send (const
|
74
|
-
(send (send (const
|
73
|
+
(send (const {nil? cbase} :Time) :current)
|
74
|
+
(send (send (const {nil? cbase} :Time) :zone) :now)
|
75
75
|
}
|
76
76
|
PATTERN
|
77
77
|
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
53
53
|
method_name = node.method_name
|
54
54
|
static_name = static_method_name(method_name)
|
55
55
|
return unless static_name
|
56
|
-
return
|
56
|
+
return unless dynamic_find_by_arguments?(node)
|
57
57
|
|
58
58
|
message = format(MSG, static_name: static_name, method: method_name)
|
59
59
|
add_offense(node, message: message) do |corrector|
|
@@ -65,12 +65,8 @@ module RuboCop
|
|
65
65
|
private
|
66
66
|
|
67
67
|
def autocorrect(corrector, node)
|
68
|
-
keywords = column_keywords(node.method_name)
|
69
|
-
|
70
|
-
return if keywords.size != node.arguments.size
|
71
|
-
|
72
68
|
autocorrect_method_name(corrector, node)
|
73
|
-
autocorrect_argument_keywords(corrector, node,
|
69
|
+
autocorrect_argument_keywords(corrector, node, column_keywords(node.method_name))
|
74
70
|
end
|
75
71
|
|
76
72
|
def allowed_invocation?(node)
|
@@ -120,6 +116,20 @@ module RuboCop
|
|
120
116
|
|
121
117
|
match[2] ? 'find_by!' : 'find_by'
|
122
118
|
end
|
119
|
+
|
120
|
+
def dynamic_find_by_arguments?(node)
|
121
|
+
dynamic_find_by_arguments_count?(node) && dynamic_find_by_arguments_type?(node)
|
122
|
+
end
|
123
|
+
|
124
|
+
def dynamic_find_by_arguments_count?(node)
|
125
|
+
column_keywords(node.method_name).size == node.arguments.size
|
126
|
+
end
|
127
|
+
|
128
|
+
def dynamic_find_by_arguments_type?(node)
|
129
|
+
node.arguments.none? do |argument|
|
130
|
+
IGNORED_ARGUMENT_TYPES.include?(argument.type)
|
131
|
+
end
|
132
|
+
end
|
123
133
|
end
|
124
134
|
end
|
125
135
|
end
|
@@ -34,15 +34,15 @@ module RuboCop
|
|
34
34
|
RESTRICT_ON_SEND = %i[join].freeze
|
35
35
|
|
36
36
|
def_node_matcher :file_join_nodes?, <<~PATTERN
|
37
|
-
(send (const nil? :File) :join ...)
|
37
|
+
(send (const {nil? cbase} :File) :join ...)
|
38
38
|
PATTERN
|
39
39
|
|
40
40
|
def_node_search :rails_root_nodes?, <<~PATTERN
|
41
|
-
(send (const nil? :Rails) :root)
|
41
|
+
(send (const {nil? cbase} :Rails) :root)
|
42
42
|
PATTERN
|
43
43
|
|
44
44
|
def_node_matcher :rails_root_join_nodes?, <<~PATTERN
|
45
|
-
(send
|
45
|
+
(send #rails_root_nodes? :join ...)
|
46
46
|
PATTERN
|
47
47
|
|
48
48
|
def on_dstr(node)
|
@@ -29,17 +29,17 @@ module RuboCop
|
|
29
29
|
|
30
30
|
MSG = 'Use `freeze_time` instead of `travel_to`.'
|
31
31
|
NOW_METHODS = %i[now new current].freeze
|
32
|
-
|
32
|
+
CONVERT_METHODS = %i[to_time in_time_zone].freeze
|
33
33
|
RESTRICT_ON_SEND = %i[travel_to].freeze
|
34
34
|
|
35
35
|
# @!method time_now?(node)
|
36
36
|
def_node_matcher :time_now?, <<~PATTERN
|
37
|
-
(const nil? {:Time :DateTime})
|
37
|
+
(const {nil? cbase} {:Time :DateTime})
|
38
38
|
PATTERN
|
39
39
|
|
40
40
|
# @!method zoned_time_now?(node)
|
41
41
|
def_node_matcher :zoned_time_now?, <<~PATTERN
|
42
|
-
(send (const nil? :Time) :zone)
|
42
|
+
(send (const {nil? cbase} :Time) :zone)
|
43
43
|
PATTERN
|
44
44
|
|
45
45
|
def on_send(node)
|
@@ -63,9 +63,11 @@ module RuboCop
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def current_time_with_convert?(node, method_name)
|
66
|
-
return false unless
|
66
|
+
return false unless CONVERT_METHODS.include?(method_name)
|
67
|
+
|
68
|
+
child_node, child_method_name, time_argument = *node.children
|
69
|
+
return if time_argument
|
67
70
|
|
68
|
-
child_node, child_method_name = *node.children
|
69
71
|
current_time?(child_node, child_method_name)
|
70
72
|
end
|
71
73
|
end
|
@@ -37,7 +37,7 @@ module RuboCop
|
|
37
37
|
RESTRICT_ON_SEND = %i[has_many has_one].freeze
|
38
38
|
|
39
39
|
def_node_search :active_resource_class?, <<~PATTERN
|
40
|
-
(const (const nil? :ActiveResource) :Base)
|
40
|
+
(const (const {nil? cbase} :ActiveResource) :Base)
|
41
41
|
PATTERN
|
42
42
|
|
43
43
|
def_node_matcher :association_without_options?, <<~PATTERN
|
@@ -12,7 +12,6 @@ module RuboCop
|
|
12
12
|
# render plain: 'foo/bar', status: 304
|
13
13
|
# redirect_to root_url, status: 301
|
14
14
|
# head 200
|
15
|
-
# get '/foobar', to: redirect('/foobar/baz', status: 301)
|
16
15
|
#
|
17
16
|
# # good
|
18
17
|
# render :foo, status: :ok
|
@@ -20,7 +19,6 @@ module RuboCop
|
|
20
19
|
# render plain: 'foo/bar', status: :not_modified
|
21
20
|
# redirect_to root_url, status: :moved_permanently
|
22
21
|
# head :ok
|
23
|
-
# get '/foobar', to: redirect('/foobar/baz', status: :moved_permanently)
|
24
22
|
#
|
25
23
|
# @example EnforcedStyle: numeric
|
26
24
|
# # bad
|
@@ -29,7 +27,6 @@ module RuboCop
|
|
29
27
|
# render plain: 'foo/bar', status: :not_modified
|
30
28
|
# redirect_to root_url, status: :moved_permanently
|
31
29
|
# head :ok
|
32
|
-
# get '/foobar', to: redirect('/foobar/baz', status: :moved_permanently)
|
33
30
|
#
|
34
31
|
# # good
|
35
32
|
# render :foo, status: 200
|
@@ -37,20 +34,18 @@ module RuboCop
|
|
37
34
|
# render plain: 'foo/bar', status: 304
|
38
35
|
# redirect_to root_url, status: 301
|
39
36
|
# head 200
|
40
|
-
# get '/foobar', to: redirect('/foobar/baz', status: 301)
|
41
37
|
#
|
42
38
|
class HttpStatus < Base
|
43
39
|
include ConfigurableEnforcedStyle
|
44
40
|
extend AutoCorrector
|
45
41
|
|
46
|
-
RESTRICT_ON_SEND = %i[render redirect_to head
|
42
|
+
RESTRICT_ON_SEND = %i[render redirect_to head].freeze
|
47
43
|
|
48
44
|
def_node_matcher :http_status, <<~PATTERN
|
49
45
|
{
|
50
46
|
(send nil? {:render :redirect_to} _ $hash)
|
51
47
|
(send nil? {:render :redirect_to} $hash)
|
52
48
|
(send nil? :head ${int sym} ...)
|
53
|
-
(send nil? :redirect _ $hash)
|
54
49
|
}
|
55
50
|
PATTERN
|
56
51
|
|
@@ -34,8 +34,8 @@ module RuboCop
|
|
34
34
|
|
35
35
|
def_node_matcher :mailer_base_class?, <<~PATTERN
|
36
36
|
{
|
37
|
-
(const (const nil? :ActionMailer) :Base)
|
38
|
-
(const nil? :ApplicationMailer)
|
37
|
+
(const (const {nil? cbase} :ActionMailer) :Base)
|
38
|
+
(const {nil? cbase} :ApplicationMailer)
|
39
39
|
}
|
40
40
|
PATTERN
|
41
41
|
|
@@ -44,7 +44,7 @@ module RuboCop
|
|
44
44
|
PATTERN
|
45
45
|
|
46
46
|
def_node_matcher :class_new_definition?, <<~PATTERN
|
47
|
-
(send (const nil? :Class) :new #mailer_base_class?)
|
47
|
+
(send (const {nil? cbase} :Class) :new #mailer_base_class?)
|
48
48
|
PATTERN
|
49
49
|
|
50
50
|
def on_class(node)
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
basename = basename_without_timestamp_and_suffix(processed_source.file_path)
|
31
31
|
|
32
|
-
class_identifier = node.identifier
|
32
|
+
class_identifier = node.identifier.location.name
|
33
33
|
camelized_basename = camelize(basename)
|
34
34
|
return if class_identifier.source.casecmp(camelized_basename).zero?
|
35
35
|
|
@@ -26,34 +26,53 @@ module RuboCop
|
|
26
26
|
minimum_target_rails_version 5.0
|
27
27
|
|
28
28
|
def_node_matcher :pluck_candidate?, <<~PATTERN
|
29
|
-
({block numblock} (send _ {:map :collect}) $_argument (send
|
29
|
+
({block numblock} (send _ {:map :collect}) $_argument (send lvar :[] $_key))
|
30
30
|
PATTERN
|
31
31
|
|
32
32
|
def on_block(node)
|
33
|
-
pluck_candidate?(node) do |argument,
|
33
|
+
pluck_candidate?(node) do |argument, key|
|
34
|
+
next unless use_one_block_argument?(argument)
|
35
|
+
|
34
36
|
match = if node.block_type?
|
35
|
-
argument.children.first.source
|
37
|
+
block_argument = argument.children.first.source
|
38
|
+
use_block_argument_in_key?(block_argument, key)
|
36
39
|
else # numblock
|
37
|
-
argument == 1 &&
|
40
|
+
argument == 1 && use_block_argument_in_key?('_1', key)
|
38
41
|
end
|
39
42
|
next unless match
|
40
43
|
|
41
|
-
|
42
|
-
message = message(replacement, node)
|
43
|
-
|
44
|
-
add_offense(offense_range(node), message: message) do |corrector|
|
45
|
-
corrector.replace(offense_range(node), replacement)
|
46
|
-
end
|
44
|
+
register_offense(node, key)
|
47
45
|
end
|
48
46
|
end
|
49
47
|
alias on_numblock on_block
|
50
48
|
|
51
49
|
private
|
52
50
|
|
51
|
+
def use_one_block_argument?(argument)
|
52
|
+
return true if argument == 1 # Checks for numbered argument `_1`.
|
53
|
+
|
54
|
+
argument.respond_to?(:one?) && argument.one?
|
55
|
+
end
|
56
|
+
|
57
|
+
def use_block_argument_in_key?(block_argument, key)
|
58
|
+
return false if block_argument == key.source
|
59
|
+
|
60
|
+
key.each_descendant(:lvar).none? { |lvar| block_argument == lvar.source }
|
61
|
+
end
|
62
|
+
|
53
63
|
def offense_range(node)
|
54
64
|
node.send_node.loc.selector.join(node.loc.end)
|
55
65
|
end
|
56
66
|
|
67
|
+
def register_offense(node, key)
|
68
|
+
replacement = "pluck(#{key.source})"
|
69
|
+
message = message(replacement, node)
|
70
|
+
|
71
|
+
add_offense(offense_range(node), message: message) do |corrector|
|
72
|
+
corrector.replace(offense_range(node), replacement)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
57
76
|
def message(replacement, node)
|
58
77
|
current = offense_range(node).source
|
59
78
|
|
@@ -26,7 +26,7 @@ module RuboCop
|
|
26
26
|
RESTRICT_ON_SEND = %i[require_dependency].freeze
|
27
27
|
|
28
28
|
def_node_matcher :require_dependency_call?, <<~PATTERN
|
29
|
-
(send {nil? (const
|
29
|
+
(send {nil? (const {nil? cbase} :Kernel)} :require_dependency _)
|
30
30
|
PATTERN
|
31
31
|
|
32
32
|
def on_send(node)
|
@@ -163,12 +163,11 @@ module RuboCop
|
|
163
163
|
def on_send(node)
|
164
164
|
evidence(node) do |method, path, args, rails_root|
|
165
165
|
add_offense(node, message: format(MSG, method: method, rails_root: rails_root.source)) do |corrector|
|
166
|
-
if dir_glob?(node)
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
end
|
166
|
+
replacement = if dir_glob?(node)
|
167
|
+
build_path_glob_replacement(path, method)
|
168
|
+
else
|
169
|
+
build_path_replacement(path, method, args)
|
170
|
+
end
|
172
171
|
|
173
172
|
corrector.replace(node, replacement)
|
174
173
|
end
|
@@ -184,7 +183,7 @@ module RuboCop
|
|
184
183
|
yield(method, path, args, rails_root)
|
185
184
|
end
|
186
185
|
|
187
|
-
def
|
186
|
+
def build_path_glob_replacement(path, method)
|
188
187
|
receiver = range_between(path.loc.expression.begin_pos, path.children.first.loc.selector.end_pos).source
|
189
188
|
|
190
189
|
argument = if path.arguments.one?
|
@@ -196,6 +195,18 @@ module RuboCop
|
|
196
195
|
"#{receiver}.#{method}(#{argument})"
|
197
196
|
end
|
198
197
|
|
198
|
+
def build_path_replacement(path, method, args)
|
199
|
+
path_replacement = path.source
|
200
|
+
if path.arguments? && !path.parenthesized_call?
|
201
|
+
path_replacement[' '] = '('
|
202
|
+
path_replacement << ')'
|
203
|
+
end
|
204
|
+
|
205
|
+
replacement = "#{path_replacement}.#{method}"
|
206
|
+
replacement += "(#{args.map(&:source).join(', ')})" unless args.empty?
|
207
|
+
replacement
|
208
|
+
end
|
209
|
+
|
199
210
|
def include_interpolation?(arguments)
|
200
211
|
arguments.any? do |argument|
|
201
212
|
argument.children.any? { |child| child.respond_to?(:begin_type?) && child.begin_type? }
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
RESTRICT_ON_SEND = PREFERRED_METHODS.keys.freeze
|
50
50
|
|
51
51
|
def_node_matcher :long_i18n?, <<~PATTERN
|
52
|
-
(send {nil? (const nil? :I18n)} ${:translate :localize} ...)
|
52
|
+
(send {nil? (const {nil? cbase} :I18n)} ${:translate :localize} ...)
|
53
53
|
PATTERN
|
54
54
|
|
55
55
|
def on_send(node)
|
@@ -21,6 +21,37 @@ module RuboCop
|
|
21
21
|
extend AutoCorrector
|
22
22
|
extend TargetRailsVersion
|
23
23
|
|
24
|
+
# These types are defined by the following files in ActiveSupport:
|
25
|
+
# lib/active_support/core_ext/array/conversions.rb
|
26
|
+
# lib/active_support/core_ext/date/conversions.rb
|
27
|
+
# lib/active_support/core_ext/date_time/conversions.rb
|
28
|
+
# lib/active_support/core_ext/numeric/conversions.rb
|
29
|
+
# lib/active_support/core_ext/range/conversions.rb
|
30
|
+
# lib/active_support/core_ext/time/conversions.rb
|
31
|
+
# lib/active_support/time_with_zone.rb
|
32
|
+
EXTENDED_FORMAT_TYPES = Set.new(
|
33
|
+
%i[
|
34
|
+
currency
|
35
|
+
db
|
36
|
+
delimited
|
37
|
+
human
|
38
|
+
human_size
|
39
|
+
inspect
|
40
|
+
iso8601
|
41
|
+
long
|
42
|
+
long_ordinal
|
43
|
+
nsec
|
44
|
+
number
|
45
|
+
percentage
|
46
|
+
phone
|
47
|
+
rfc822
|
48
|
+
rounded
|
49
|
+
short
|
50
|
+
time
|
51
|
+
usec
|
52
|
+
]
|
53
|
+
)
|
54
|
+
|
24
55
|
MSG = 'Use `to_formatted_s` instead.'
|
25
56
|
|
26
57
|
RESTRICT_ON_SEND = %i[to_s].freeze
|
@@ -28,13 +59,19 @@ module RuboCop
|
|
28
59
|
minimum_target_rails_version 7.0
|
29
60
|
|
30
61
|
def on_send(node)
|
31
|
-
return
|
62
|
+
return unless rails_extended_to_s?(node)
|
32
63
|
|
33
64
|
add_offense(node.loc.selector) do |corrector|
|
34
65
|
corrector.replace(node.loc.selector, 'to_formatted_s')
|
35
66
|
end
|
36
67
|
end
|
37
68
|
alias on_csend on_send
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def rails_extended_to_s?(node)
|
73
|
+
node.first_argument&.sym_type? && EXTENDED_FORMAT_TYPES.include?(node.first_argument.value)
|
74
|
+
end
|
38
75
|
end
|
39
76
|
end
|
40
77
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.17.
|
4
|
+
version: 2.17.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-11-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|