rubocop 0.56.0 → 0.57.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|