rubocop 0.56.0 → 0.57.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/README.md +3 -4
- data/assets/output.html.erb +1 -1
- data/bin/console +9 -0
- data/config/default.yml +23 -3
- data/config/disabled.yml +2 -2
- data/config/enabled.yml +29 -13
- data/{bin → exe}/rubocop +0 -0
- data/lib/rubocop.rb +6 -2
- data/lib/rubocop/ast/node.rb +3 -1
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +26 -5
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_loader_resolver.rb +4 -2
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -1
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +130 -0
- data/lib/rubocop/cop/layout/dot_position.rb +2 -6
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +0 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +2 -2
- data/lib/rubocop/cop/layout/indent_heredoc.rb +29 -5
- data/lib/rubocop/cop/layout/indentation_consistency.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/leading_blank_lines.rb +53 -0
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +11 -2
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +4 -3
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/mixin/array_syntax.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +3 -7
- data/lib/rubocop/cop/rails/assert_not.rb +1 -1
- data/lib/rubocop/cop/rails/bulk_change_table.rb +272 -0
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +1 -1
- data/lib/rubocop/cop/rails/file_path.rb +40 -10
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +1 -1
- data/lib/rubocop/cop/rails/time_zone.rb +3 -3
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +111 -0
- data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -1
- data/lib/rubocop/cop/style/command_literal.rb +1 -5
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +30 -7
- data/lib/rubocop/cop/style/mixin_grouping.rb +8 -3
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +26 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/unneeded_condition.rb +73 -0
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +13 -0
- data/lib/rubocop/cop/variable_force.rb +16 -17
- data/lib/rubocop/options.rb +15 -5
- data/lib/rubocop/result_cache.rb +3 -3
- data/lib/rubocop/string_util.rb +2 -147
- data/lib/rubocop/token.rb +2 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +28 -9
- data/lib/rubocop/cop/lint/splat_keyword_arguments.rb +0 -36
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Layout
|
6
|
+
#
|
7
|
+
# Checks the indentation of here document closings.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# class Foo
|
13
|
+
# def bar
|
14
|
+
# <<~SQL
|
15
|
+
# 'Hi'
|
16
|
+
# SQL
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# class Foo
|
22
|
+
# def bar
|
23
|
+
# <<~SQL
|
24
|
+
# 'Hi'
|
25
|
+
# SQL
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# # bad
|
30
|
+
#
|
31
|
+
# # heredoc contents is before closing heredoc.
|
32
|
+
# foo arg,
|
33
|
+
# <<~EOS
|
34
|
+
# Hi
|
35
|
+
# EOS
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
# foo arg,
|
39
|
+
# <<~EOS
|
40
|
+
# Hi
|
41
|
+
# EOS
|
42
|
+
#
|
43
|
+
# # good
|
44
|
+
# foo arg,
|
45
|
+
# <<~EOS
|
46
|
+
# Hi
|
47
|
+
# EOS
|
48
|
+
#
|
49
|
+
class ClosingHeredocIndentation < Cop
|
50
|
+
include Heredoc
|
51
|
+
|
52
|
+
MSG = '`%<closing>s` is not aligned with `%<opening>s`.'.freeze
|
53
|
+
MSG_ARG = '`%<closing>s` is not aligned with `%<opening>s` or ' \
|
54
|
+
'beginning of method definition.'.freeze
|
55
|
+
|
56
|
+
def on_heredoc(node)
|
57
|
+
if node.loc.heredoc_body.source.empty? ||
|
58
|
+
contents_indentation(node) >= closing_indentation(node)
|
59
|
+
return if opening_indentation(node) == closing_indentation(node)
|
60
|
+
return if node.argument? &&
|
61
|
+
opening_indentation(
|
62
|
+
find_node_used_heredoc_argument(node.parent)
|
63
|
+
) == closing_indentation(node)
|
64
|
+
end
|
65
|
+
|
66
|
+
add_offense(node, location: :heredoc_end)
|
67
|
+
end
|
68
|
+
|
69
|
+
def autocorrect(node)
|
70
|
+
lambda do |corrector|
|
71
|
+
corrector.replace(node.loc.heredoc_end, indented_end(node))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def opening_indentation(node)
|
78
|
+
indent_level(heredoc_opening(node))
|
79
|
+
end
|
80
|
+
|
81
|
+
def contents_indentation(node)
|
82
|
+
source_lines = node.loc.heredoc_body.source.split("\n")
|
83
|
+
|
84
|
+
source_lines.reject(&:empty?).map do |line|
|
85
|
+
indent_level(line)
|
86
|
+
end.min
|
87
|
+
end
|
88
|
+
|
89
|
+
def closing_indentation(node)
|
90
|
+
indent_level(heredoc_closing(node))
|
91
|
+
end
|
92
|
+
|
93
|
+
def heredoc_opening(node)
|
94
|
+
node.loc.expression.source_line
|
95
|
+
end
|
96
|
+
|
97
|
+
def heredoc_closing(node)
|
98
|
+
node.loc.heredoc_end.source_line
|
99
|
+
end
|
100
|
+
|
101
|
+
def indented_end(node)
|
102
|
+
closing_indent = closing_indentation(node)
|
103
|
+
opening_indent = opening_indentation(node)
|
104
|
+
closing_text = heredoc_closing(node)
|
105
|
+
closing_text.gsub(/^\s{#{closing_indent}}/, ' ' * opening_indent)
|
106
|
+
end
|
107
|
+
|
108
|
+
def find_node_used_heredoc_argument(node)
|
109
|
+
if node.parent && node.parent.send_type?
|
110
|
+
find_node_used_heredoc_argument(node.parent)
|
111
|
+
else
|
112
|
+
node
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def message(node)
|
117
|
+
format(
|
118
|
+
node.argument? ? MSG_ARG : MSG,
|
119
|
+
closing: heredoc_closing(node).strip,
|
120
|
+
opening: heredoc_opening(node).strip
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
def indent_level(source_line)
|
125
|
+
source_line[/\A */].length
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -89,12 +89,8 @@ module RuboCop
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def selector_range(node)
|
92
|
-
|
93
|
-
|
94
|
-
else
|
95
|
-
# l.(1) has no selector, so we use the opening parenthesis instead
|
96
|
-
node.loc.begin
|
97
|
-
end
|
92
|
+
# l.(1) has no selector, so we use the opening parenthesis instead
|
93
|
+
node.loc.selector || node.loc.begin
|
98
94
|
end
|
99
95
|
end
|
100
96
|
end
|
@@ -13,12 +13,12 @@ module RuboCop
|
|
13
13
|
# name = "RuboCop"
|
14
14
|
# # Some comment and an empty line
|
15
15
|
#
|
16
|
-
# website += "/
|
16
|
+
# website += "/rubocop-hq/rubocop" unless cond
|
17
17
|
# puts "rubocop" if debug
|
18
18
|
#
|
19
19
|
# # bad for any configuration
|
20
20
|
# set_app("RuboCop")
|
21
|
-
# website = "https://github.com/
|
21
|
+
# website = "https://github.com/rubocop-hq/rubocop"
|
22
22
|
class ExtraSpacing < Cop
|
23
23
|
include PrecedingFollowingAlignment
|
24
24
|
include RangeHelp
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
# In Ruby 2.3 or newer, squiggly heredocs (`<<~`) should be used. If you
|
9
9
|
# use the older rubies, you should introduce some library to your project
|
10
10
|
# (e.g. ActiveSupport, Powerpack or Unindent).
|
11
|
-
# Note: When `Metrics/LineLength`'s `AllowHeredoc` is false(not default),
|
11
|
+
# Note: When `Metrics/LineLength`'s `AllowHeredoc` is false (not default),
|
12
12
|
# this cop does not add any offenses for long here documents to
|
13
13
|
# avoid `Metrics/LineLength`'s offenses.
|
14
14
|
#
|
@@ -193,15 +193,24 @@ module RuboCop
|
|
193
193
|
return if target_ruby_version < 2.3
|
194
194
|
lambda do |corrector|
|
195
195
|
if heredoc_indent_type(node) == '~'
|
196
|
-
corrector
|
196
|
+
adjust_squiggly(corrector, node)
|
197
197
|
else
|
198
|
-
|
199
|
-
corrected = heredoc_beginning.sub(/<<-?/, '<<~')
|
200
|
-
corrector.replace(node.loc.expression, corrected)
|
198
|
+
adjust_minus(corrector, node)
|
201
199
|
end
|
202
200
|
end
|
203
201
|
end
|
204
202
|
|
203
|
+
def adjust_squiggly(corrector, node)
|
204
|
+
corrector.replace(node.loc.heredoc_body, indented_body(node))
|
205
|
+
corrector.replace(node.loc.heredoc_end, indented_end(node))
|
206
|
+
end
|
207
|
+
|
208
|
+
def adjust_minus(corrector, node)
|
209
|
+
heredoc_beginning = node.loc.expression.source
|
210
|
+
corrected = heredoc_beginning.sub(/<<-?/, '<<~')
|
211
|
+
corrector.replace(node.loc.expression, corrected)
|
212
|
+
end
|
213
|
+
|
205
214
|
def correct_by_library(node)
|
206
215
|
lambda do |corrector|
|
207
216
|
corrector.replace(node.loc.heredoc_body, indented_body(node))
|
@@ -230,6 +239,17 @@ module RuboCop
|
|
230
239
|
body.gsub(/^\s{#{body_indent_level}}/, ' ' * correct_indent_level)
|
231
240
|
end
|
232
241
|
|
242
|
+
def indented_end(node)
|
243
|
+
end_ = heredoc_end(node)
|
244
|
+
end_indent_level = indent_level(end_)
|
245
|
+
correct_indent_level = base_indent_level(node)
|
246
|
+
if end_indent_level < correct_indent_level
|
247
|
+
end_.gsub(/^\s{#{end_indent_level}}/, ' ' * correct_indent_level)
|
248
|
+
else
|
249
|
+
end_
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
233
253
|
def base_indent_level(node)
|
234
254
|
base_line_num = node.loc.expression.line
|
235
255
|
base_line = processed_source.lines[base_line_num - 1]
|
@@ -255,6 +275,10 @@ module RuboCop
|
|
255
275
|
def heredoc_body(node)
|
256
276
|
node.loc.heredoc_body.source.scrub
|
257
277
|
end
|
278
|
+
|
279
|
+
def heredoc_end(node)
|
280
|
+
node.loc.heredoc_end.source.scrub
|
281
|
+
end
|
258
282
|
end
|
259
283
|
end
|
260
284
|
end
|
@@ -144,7 +144,7 @@ module RuboCop
|
|
144
144
|
# the AccessModifierIndentation cop. This cop uses them as dividers
|
145
145
|
# in rails mode. Then consistency is checked only within each
|
146
146
|
# section delimited by a modifier node.
|
147
|
-
if child.send_type? && child.
|
147
|
+
if child.send_type? && child.bare_access_modifier?
|
148
148
|
children_to_check << [] if style == :rails
|
149
149
|
else
|
150
150
|
children_to_check.last << child
|
@@ -173,7 +173,7 @@ module RuboCop
|
|
173
173
|
end
|
174
174
|
|
175
175
|
def special_modifier?(node)
|
176
|
-
node.
|
176
|
+
node.bare_access_modifier? && SPECIAL_MODIFIERS.include?(node.source)
|
177
177
|
end
|
178
178
|
|
179
179
|
def indentation_consistency_style
|
@@ -307,7 +307,7 @@ module RuboCop
|
|
307
307
|
return unless body_node.begin_type?
|
308
308
|
|
309
309
|
starting_node = body_node.children.first
|
310
|
-
starting_node.send_type? && starting_node.
|
310
|
+
starting_node.send_type? && starting_node.bare_access_modifier?
|
311
311
|
end
|
312
312
|
|
313
313
|
def configured_indentation_width
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Layout
|
6
|
+
# This cop checks for unnecessary leading blank lines at the beginning
|
7
|
+
# of a file.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# # (start of file)
|
13
|
+
#
|
14
|
+
# class Foo
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# # (start of file)
|
19
|
+
#
|
20
|
+
# # a comment
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# # (start of file)
|
24
|
+
# class Foo
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# # (start of file)
|
29
|
+
# # a comment
|
30
|
+
class LeadingBlankLines < Cop
|
31
|
+
MSG = 'Unnecessary blank line at the beginning of the source.'.freeze
|
32
|
+
|
33
|
+
def investigate(processed_source)
|
34
|
+
token = processed_source.tokens[0]
|
35
|
+
return unless token && token.line > 1
|
36
|
+
|
37
|
+
add_offense(processed_source.tokens[0],
|
38
|
+
location: processed_source.tokens[0].pos)
|
39
|
+
end
|
40
|
+
|
41
|
+
def autocorrect(node)
|
42
|
+
range = Parser::Source::Range.new(processed_source.raw_source,
|
43
|
+
0,
|
44
|
+
node.begin_pos)
|
45
|
+
|
46
|
+
lambda do |corrector|
|
47
|
+
corrector.remove(range)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -111,10 +111,14 @@ module RuboCop
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def left_ref_bracket(node, tokens)
|
114
|
-
|
114
|
+
current_token = tokens.reverse.find(&:left_ref_bracket?)
|
115
|
+
previous_token = previous_token(current_token)
|
116
|
+
|
117
|
+
if node.method?(:[]=) ||
|
118
|
+
previous_token && !previous_token.right_bracket?
|
115
119
|
tokens.find(&:left_ref_bracket?)
|
116
120
|
else
|
117
|
-
|
121
|
+
current_token
|
118
122
|
end
|
119
123
|
end
|
120
124
|
|
@@ -131,6 +135,11 @@ module RuboCop
|
|
131
135
|
end
|
132
136
|
end
|
133
137
|
|
138
|
+
def previous_token(current_token)
|
139
|
+
index = processed_source.tokens.index(current_token)
|
140
|
+
index.nil? || index.zero? ? nil : processed_source.tokens[index - 1]
|
141
|
+
end
|
142
|
+
|
134
143
|
def empty_config
|
135
144
|
cop_config['EnforcedStyleForEmptyBrackets']
|
136
145
|
end
|
@@ -116,7 +116,7 @@ module RuboCop
|
|
116
116
|
end
|
117
117
|
|
118
118
|
def check_send(node, cur_vis)
|
119
|
-
if node.
|
119
|
+
if node.bare_access_modifier? && !node.method?(:module_function)
|
120
120
|
@last_access_modifier = node
|
121
121
|
return node.method_name
|
122
122
|
elsif (methods = private_class_method(node))
|
@@ -22,12 +22,13 @@ module RuboCop
|
|
22
22
|
MSG_SELF = 'Use `self` instead of `Object#to_s` in ' \
|
23
23
|
'interpolation.'.freeze
|
24
24
|
|
25
|
+
def_node_matcher :to_s_without_args?, '(send _ :to_s)'
|
26
|
+
|
25
27
|
def on_dstr(node)
|
26
28
|
node.each_child_node(:begin) do |begin_node|
|
27
29
|
final_node = begin_node.children.last
|
28
30
|
|
29
|
-
next unless final_node
|
30
|
-
final_node.method?(:to_s) && !final_node.arguments?
|
31
|
+
next unless to_s_without_args?(final_node)
|
31
32
|
|
32
33
|
add_offense(final_node, location: :selector)
|
33
34
|
end
|
@@ -35,7 +36,7 @@ module RuboCop
|
|
35
36
|
|
36
37
|
def autocorrect(node)
|
37
38
|
lambda do |corrector|
|
38
|
-
receiver
|
39
|
+
receiver = node.receiver
|
39
40
|
corrector.replace(
|
40
41
|
node.source_range,
|
41
42
|
if receiver
|
@@ -134,7 +134,7 @@ module RuboCop
|
|
134
134
|
|
135
135
|
if node.begin_type?
|
136
136
|
check_scope(node)
|
137
|
-
elsif node.send_type? && node.
|
137
|
+
elsif node.send_type? && node.bare_access_modifier?
|
138
138
|
add_offense(node, message: format(MSG, current: node.method_name))
|
139
139
|
end
|
140
140
|
end
|
@@ -147,7 +147,7 @@ module RuboCop
|
|
147
147
|
|
148
148
|
def check_child_nodes(node, unused, cur_vis)
|
149
149
|
node.child_nodes.each do |child|
|
150
|
-
if child.send_type? && child.
|
150
|
+
if child.send_type? && child.bare_access_modifier?
|
151
151
|
cur_vis, unused =
|
152
152
|
check_new_visibility(child, unused, child.method_name, cur_vis)
|
153
153
|
elsif method_definition?(child)
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def bracketed_array_of?(element_type, node)
|
11
|
-
return false unless node.square_brackets? && node.values.
|
11
|
+
return false unless node.square_brackets? && !node.values.empty?
|
12
12
|
|
13
13
|
node.values.all? { |value| value.type == element_type }
|
14
14
|
end
|
@@ -63,17 +63,13 @@ module RuboCop
|
|
63
63
|
def range_by_whole_lines(range, include_final_newline: false)
|
64
64
|
buffer = @processed_source.buffer
|
65
65
|
|
66
|
-
begin_pos = range.begin_pos
|
67
|
-
begin_offset = range.column
|
68
|
-
begin_of_first_line = begin_pos - begin_offset
|
69
|
-
|
70
66
|
last_line = buffer.source_line(range.last_line)
|
71
|
-
end_pos = range.end_pos
|
72
67
|
end_offset = last_line.length - range.last_column
|
73
68
|
end_offset += 1 if include_final_newline
|
74
|
-
end_of_last_line = end_pos + end_offset
|
75
69
|
|
76
|
-
|
70
|
+
range
|
71
|
+
.adjust(begin_pos: -range.column, end_pos: end_offset)
|
72
|
+
.intersect(buffer.source_range)
|
77
73
|
end
|
78
74
|
|
79
75
|
## Helpers for above range methods. Do not use inside Cops.
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
16
16
|
class AssertNot < RuboCop::Cop::Cop
|
17
17
|
MSG = 'Prefer `assert_not` over `assert !`.'.freeze
|
18
18
|
|
19
|
-
def_node_matcher :offensive?, '(send nil? :assert (send ... :!))'
|
19
|
+
def_node_matcher :offensive?, '(send nil? :assert (send ... :!) ...)'
|
20
20
|
|
21
21
|
def on_send(node)
|
22
22
|
add_offense(node) if offensive?(node)
|