rubocop 0.91.0 → 0.91.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/README.md +1 -1
- data/config/default.yml +9 -1
- data/lib/rubocop.rb +1 -1
- data/lib/rubocop/comment_config.rb +9 -5
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +4 -13
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +14 -8
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +10 -1
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -18
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -2
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +23 -3
- data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -4
- data/lib/rubocop/cop/lint/identity_comparison.rb +5 -3
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -5
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
- data/lib/rubocop/cop/lint/useless_times.rb +11 -2
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +25 -16
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
- data/lib/rubocop/cop/mixin/rescue_node.rb +1 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
- data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
- data/lib/rubocop/cop/style/combinable_loops.rb +5 -10
- data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +15 -6
- data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -4
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -6
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
- data/lib/rubocop/cop/style/multiline_when_then.rb +1 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +3 -0
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -9
- data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -3
- data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
- data/lib/rubocop/cop/style/redundant_return.rb +17 -17
- data/lib/rubocop/cop/style/redundant_self.rb +7 -9
- data/lib/rubocop/cop/style/redundant_sort.rb +13 -24
- data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
- data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -2
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
- data/lib/rubocop/cop/util.rb +0 -1
- data/lib/rubocop/directive_comment.rb +32 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +3 -3
- data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -33,10 +33,8 @@ module RuboCop
|
|
33
33
|
def on_rescue(node)
|
34
34
|
return if rescue_modifier?(node)
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
resbodies.each_with_object(Set.new) do |resbody, previous|
|
39
|
-
rescued_exceptions = rescued_exceptions(resbody)
|
36
|
+
node.resbody_branches.each_with_object(Set.new) do |resbody, previous|
|
37
|
+
rescued_exceptions = resbody.exceptions
|
40
38
|
|
41
39
|
rescued_exceptions.each do |exception|
|
42
40
|
add_offense(exception) unless previous.add?(exception)
|
@@ -26,9 +26,11 @@ module RuboCop
|
|
26
26
|
return unless compare_between_object_id_by_double_equal?(node)
|
27
27
|
|
28
28
|
add_offense(node) do |corrector|
|
29
|
-
receiver = node.receiver.receiver
|
30
|
-
argument = node.first_argument.receiver
|
31
|
-
|
29
|
+
receiver = node.receiver.receiver
|
30
|
+
argument = node.first_argument.receiver
|
31
|
+
return unless receiver && argument
|
32
|
+
|
33
|
+
replacement = "#{receiver.source}.equal?(#{argument.source})"
|
32
34
|
|
33
35
|
corrector.replace(node, replacement)
|
34
36
|
end
|
@@ -58,12 +58,9 @@ module RuboCop
|
|
58
58
|
PATTERN
|
59
59
|
|
60
60
|
def on_class(node)
|
61
|
-
check_node(node.
|
62
|
-
end
|
63
|
-
|
64
|
-
def on_module(node)
|
65
|
-
check_node(node.children[1]) # module body
|
61
|
+
check_node(node.body)
|
66
62
|
end
|
63
|
+
alias on_module on_class
|
67
64
|
|
68
65
|
private
|
69
66
|
|
@@ -56,19 +56,29 @@ module RuboCop
|
|
56
56
|
|
57
57
|
private
|
58
58
|
|
59
|
+
def previous_line_blank?(range)
|
60
|
+
processed_source.buffer.source_line(range.line - 1).blank?
|
61
|
+
end
|
62
|
+
|
59
63
|
def comment_range_with_surrounding_space(range)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
64
|
+
if previous_line_blank?(range)
|
65
|
+
# When the previous line is blank, it should be retained
|
66
|
+
range_with_surrounding_space(range: range, side: :right)
|
67
|
+
else
|
68
|
+
# Eat the entire comment, the preceding space, and the preceding
|
69
|
+
# newline if there is one.
|
70
|
+
original_begin = range.begin_pos
|
71
|
+
range = range_with_surrounding_space(range: range,
|
72
|
+
side: :left,
|
73
|
+
newlines: true)
|
74
|
+
|
75
|
+
range_with_surrounding_space(range: range,
|
76
|
+
side: :right,
|
77
|
+
# Special for a comment that
|
78
|
+
# begins the file: remove
|
79
|
+
# the newline at the end.
|
80
|
+
newlines: original_begin.zero?)
|
81
|
+
end
|
72
82
|
end
|
73
83
|
|
74
84
|
def directive_range_in_list(range, ranges)
|
@@ -45,18 +45,28 @@ module RuboCop
|
|
45
45
|
return if processed_source.blank?
|
46
46
|
|
47
47
|
offenses = processed_source.comment_config.extra_enabled_comments
|
48
|
-
offenses.each
|
48
|
+
offenses.each { |comment, cop_names| register_offense(comment, cop_names) }
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def register_offense(comment, cop_names)
|
54
|
+
directive = DirectiveComment.new(comment)
|
55
|
+
|
56
|
+
cop_names.each do |name|
|
49
57
|
add_offense(
|
50
58
|
range_of_offense(comment, name),
|
51
59
|
message: format(MSG, cop: all_or_name(name))
|
52
60
|
) do |corrector|
|
53
|
-
|
61
|
+
if directive.match?(cop_names)
|
62
|
+
corrector.remove(range_with_surrounding_space(range: directive.range, side: :right))
|
63
|
+
else
|
64
|
+
corrector.remove(range_with_comma(comment, name))
|
65
|
+
end
|
54
66
|
end
|
55
67
|
end
|
56
68
|
end
|
57
69
|
|
58
|
-
private
|
59
|
-
|
60
70
|
def range_of_offense(comment, name)
|
61
71
|
start_pos = comment_start(comment) + cop_name_indention(comment, name)
|
62
72
|
range_between(start_pos, start_pos + name.size)
|
@@ -75,8 +75,7 @@ module RuboCop
|
|
75
75
|
|
76
76
|
def rescued_groups_for(rescues)
|
77
77
|
rescues.map do |group|
|
78
|
-
|
79
|
-
evaluate_exceptions(rescue_group)
|
78
|
+
evaluate_exceptions(group)
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
@@ -117,14 +116,15 @@ module RuboCop
|
|
117
116
|
$VERBOSE = old_verbose
|
118
117
|
end
|
119
118
|
|
120
|
-
def evaluate_exceptions(
|
121
|
-
|
122
|
-
|
119
|
+
def evaluate_exceptions(group)
|
120
|
+
rescued_exceptions = group.exceptions
|
121
|
+
|
122
|
+
if rescued_exceptions.any?
|
123
123
|
rescued_exceptions.each_with_object([]) do |exception, converted|
|
124
124
|
begin
|
125
125
|
silence_warnings do
|
126
126
|
# Avoid printing deprecation warnings about constants
|
127
|
-
converted << Kernel.const_get(exception)
|
127
|
+
converted << Kernel.const_get(exception.source)
|
128
128
|
end
|
129
129
|
rescue NameError
|
130
130
|
converted << nil
|
@@ -159,16 +159,12 @@ module RuboCop
|
|
159
159
|
end
|
160
160
|
|
161
161
|
def preceded_by_continue_statement?(break_statement)
|
162
|
-
|
162
|
+
break_statement.left_siblings.any? do |sibling|
|
163
163
|
next if sibling.loop_keyword? || loop_method?(sibling)
|
164
164
|
|
165
165
|
sibling.each_descendant(:next, :redo).any?
|
166
166
|
end
|
167
167
|
end
|
168
|
-
|
169
|
-
def left_siblings_of(node)
|
170
|
-
node.parent.children[0, node.sibling_index]
|
171
|
-
end
|
172
168
|
end
|
173
169
|
end
|
174
170
|
end
|
@@ -131,12 +131,10 @@ module RuboCop
|
|
131
131
|
MSG = 'Useless `%<current>s` access modifier.'
|
132
132
|
|
133
133
|
def on_class(node)
|
134
|
-
check_node(node.
|
135
|
-
end
|
136
|
-
|
137
|
-
def on_module(node)
|
138
|
-
check_node(node.children[1]) # module body
|
134
|
+
check_node(node.body)
|
139
135
|
end
|
136
|
+
alias on_module on_class
|
137
|
+
alias on_sclass on_class
|
140
138
|
|
141
139
|
def on_block(node)
|
142
140
|
return unless eval_call?(node)
|
@@ -144,10 +142,6 @@ module RuboCop
|
|
144
142
|
check_node(node.body)
|
145
143
|
end
|
146
144
|
|
147
|
-
def on_sclass(node)
|
148
|
-
check_node(node.children[1]) # singleton class body
|
149
|
-
end
|
150
|
-
|
151
145
|
private
|
152
146
|
|
153
147
|
def autocorrect(corrector, node)
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
add_offense(node, message: format(MSG, count: count)) do |corrector|
|
50
50
|
next unless own_line?(node)
|
51
51
|
|
52
|
-
if count
|
52
|
+
if never_process?(count, node)
|
53
53
|
remove_node(corrector, node)
|
54
54
|
elsif !proc_name.empty?
|
55
55
|
autocorrect_block_pass(corrector, node, proc_name)
|
@@ -61,6 +61,10 @@ module RuboCop
|
|
61
61
|
|
62
62
|
private
|
63
63
|
|
64
|
+
def never_process?(count, node)
|
65
|
+
count < 1 || node.block_type? && node.body.nil?
|
66
|
+
end
|
67
|
+
|
64
68
|
def remove_node(corrector, node)
|
65
69
|
corrector.remove(range_by_whole_lines(node.loc.expression, include_final_newline: true))
|
66
70
|
end
|
@@ -82,7 +86,12 @@ module RuboCop
|
|
82
86
|
def fix_indentation(source, range)
|
83
87
|
# Cleanup indentation in a multiline block
|
84
88
|
source_lines = source.split("\n")
|
85
|
-
|
89
|
+
|
90
|
+
source_lines[1..-1].each do |line|
|
91
|
+
next if line.empty?
|
92
|
+
|
93
|
+
line[range] = ''
|
94
|
+
end
|
86
95
|
source_lines.join("\n")
|
87
96
|
end
|
88
97
|
|
@@ -81,40 +81,49 @@ module RuboCop
|
|
81
81
|
private
|
82
82
|
|
83
83
|
def assignment?(node)
|
84
|
+
return compound_assignment(node) if node.masgn_type? || node.shorthand_asgn?
|
85
|
+
|
84
86
|
node.for_type? ||
|
85
|
-
node.op_asgn_type? ||
|
86
87
|
(node.respond_to?(:setter_method?) && node.setter_method?) ||
|
87
|
-
|
88
|
+
simple_assignment?(node) ||
|
89
|
+
argument?(node)
|
88
90
|
end
|
89
91
|
|
90
|
-
def
|
91
|
-
|
92
|
+
def compound_assignment(node)
|
93
|
+
# Methods setter can not be detected for multiple assignments
|
94
|
+
# and shorthand assigns, so we'll count them here instead
|
95
|
+
children = node.masgn_type? ? node.children[0].children : node.children
|
92
96
|
|
93
|
-
|
94
|
-
|
95
|
-
|
97
|
+
will_be_miscounted = children.count do |child|
|
98
|
+
child.respond_to?(:setter_method?) &&
|
99
|
+
!child.setter_method?
|
96
100
|
end
|
101
|
+
@assignment += will_be_miscounted
|
97
102
|
|
98
|
-
|
103
|
+
false
|
99
104
|
end
|
100
105
|
|
101
|
-
def
|
102
|
-
|
106
|
+
def simple_assignment?(node)
|
107
|
+
if !node.equals_asgn?
|
108
|
+
false
|
109
|
+
elsif node.lvasgn_type?
|
110
|
+
reset_on_lvasgn(node)
|
111
|
+
capturing_variable?(node.children.first)
|
112
|
+
else
|
113
|
+
true
|
114
|
+
end
|
103
115
|
end
|
104
116
|
|
105
|
-
|
106
|
-
|
107
|
-
def assignment_doubled_in_ast?(node)
|
108
|
-
node.masgn_type? || node.or_asgn_type? || node.and_asgn_type?
|
117
|
+
def capturing_variable?(name)
|
118
|
+
name && !/^_/.match?(name)
|
109
119
|
end
|
110
120
|
|
111
121
|
def branch?(node)
|
112
122
|
BRANCH_NODES.include?(node.type)
|
113
123
|
end
|
114
124
|
|
115
|
-
# TODO: move to rubocop-ast
|
116
125
|
def argument?(node)
|
117
|
-
ARGUMENT_TYPES.include?(node.type)
|
126
|
+
ARGUMENT_TYPES.include?(node.type) && capturing_variable?(node.children.first)
|
118
127
|
end
|
119
128
|
|
120
129
|
def condition?(node)
|
@@ -8,9 +8,9 @@ module RuboCop
|
|
8
8
|
include ConfigurableFormatting
|
9
9
|
|
10
10
|
FORMATS = {
|
11
|
-
snake_case: /(?:[
|
12
|
-
normalcase: /(?:_\D*|[
|
13
|
-
non_integer: /[
|
11
|
+
snake_case: /(?:[[[:lower:]]_]|_\d+)$/,
|
12
|
+
normalcase: /(?:_\D*|[[[:upper:]][[:lower:]]]\d*)$/,
|
13
|
+
non_integer: /[[[:upper:]][[:lower:]]_]$/
|
14
14
|
}.freeze
|
15
15
|
end
|
16
16
|
end
|
@@ -57,10 +57,11 @@ module RuboCop
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def first_line_comment(node)
|
60
|
-
comment =
|
61
|
-
|
60
|
+
comment = processed_source.find_comment { |c| c.loc.line == node.loc.line }
|
61
|
+
return unless comment
|
62
62
|
|
63
|
-
|
63
|
+
comment_source = comment.loc.expression.source
|
64
|
+
comment_source unless comment_disables_cop?(comment_source)
|
64
65
|
end
|
65
66
|
|
66
67
|
def parenthesize?(node)
|
@@ -80,6 +81,11 @@ module RuboCop
|
|
80
81
|
|
81
82
|
config.for_cop('Layout/LineLength')['Max']
|
82
83
|
end
|
84
|
+
|
85
|
+
def comment_disables_cop?(comment)
|
86
|
+
regexp_pattern = "# rubocop : (disable|todo) ([^,],)* (all|#{cop_name})"
|
87
|
+
Regexp.new(regexp_pattern.gsub(' ', '\s*')).match?(comment)
|
88
|
+
end
|
83
89
|
end
|
84
90
|
end
|
85
91
|
end
|
@@ -16,32 +16,20 @@ module RuboCop
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def find_visibility_start(node)
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
node.left_siblings
|
20
|
+
.reverse
|
21
|
+
.find(&method(:visibility_block?))
|
22
22
|
end
|
23
23
|
|
24
24
|
# Navigate to find the last protected method
|
25
25
|
def find_visibility_end(node)
|
26
26
|
possible_visibilities = VISIBILITY_SCOPES - [node_visibility(node)]
|
27
|
-
right =
|
27
|
+
right = node.right_siblings
|
28
28
|
right.find do |child_node|
|
29
29
|
possible_visibilities.include?(node_visibility(child_node))
|
30
30
|
end || right.last
|
31
31
|
end
|
32
32
|
|
33
|
-
def left_siblings_of(node)
|
34
|
-
siblings_of(node)[0, node.sibling_index]
|
35
|
-
end
|
36
|
-
|
37
|
-
def right_siblings_of(node)
|
38
|
-
siblings_of(node)[node.sibling_index..-1]
|
39
|
-
end
|
40
|
-
|
41
|
-
def siblings_of(node)
|
42
|
-
node.parent.children
|
43
|
-
end
|
44
|
-
|
45
33
|
def_node_matcher :visibility_block?, <<~PATTERN
|
46
34
|
(send nil? { :private :protected :public })
|
47
35
|
PATTERN
|
@@ -53,14 +53,16 @@ module RuboCop
|
|
53
53
|
MSG = 'Combine this loop with the previous loop.'
|
54
54
|
|
55
55
|
def on_block(node)
|
56
|
+
return unless node.parent&.begin_type?
|
56
57
|
return unless collection_looping_method?(node)
|
57
58
|
|
58
|
-
|
59
|
-
add_offense(node) if same_collection_looping?(node, sibling)
|
59
|
+
add_offense(node) if same_collection_looping?(node, node.left_sibling)
|
60
60
|
end
|
61
61
|
|
62
62
|
def on_for(node)
|
63
|
-
|
63
|
+
return unless node.parent&.begin_type?
|
64
|
+
|
65
|
+
sibling = node.left_sibling
|
64
66
|
add_offense(node) if sibling&.for_type? && node.collection == sibling.collection
|
65
67
|
end
|
66
68
|
|
@@ -71,13 +73,6 @@ module RuboCop
|
|
71
73
|
method_name.match?(/^each/) || method_name.match?(/_each$/)
|
72
74
|
end
|
73
75
|
|
74
|
-
def left_sibling_of(node)
|
75
|
-
return unless node.parent&.begin_type?
|
76
|
-
|
77
|
-
index = node.sibling_index - 1
|
78
|
-
node.parent.children[index] if index >= 0
|
79
|
-
end
|
80
|
-
|
81
76
|
def same_collection_looping?(node, sibling)
|
82
77
|
sibling&.block_type? &&
|
83
78
|
sibling.send_node.method?(node.method_name) &&
|
@@ -33,13 +33,17 @@ module RuboCop
|
|
33
33
|
# class X # :nodoc:
|
34
34
|
# y
|
35
35
|
# end
|
36
|
-
class CommentedKeyword <
|
36
|
+
class CommentedKeyword < Base
|
37
37
|
MSG = 'Do not place comments on the same line as the ' \
|
38
38
|
'`%<keyword>s` keyword.'
|
39
39
|
|
40
|
-
def
|
40
|
+
def on_new_investigation
|
41
41
|
processed_source.comments.each do |comment|
|
42
|
-
|
42
|
+
next unless (match = line(comment).match(/(?<keyword>\S+).*#/))
|
43
|
+
|
44
|
+
if offensive?(comment)
|
45
|
+
add_offense(comment, message: format(MSG, keyword: match[:keyword]))
|
46
|
+
end
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
@@ -62,11 +66,6 @@ module RuboCop
|
|
62
66
|
ALLOWED_COMMENT_REGEXES.none? { |r| r.match?(line) }
|
63
67
|
end
|
64
68
|
|
65
|
-
def message(comment)
|
66
|
-
keyword = line(comment).match(/(\S+).*#/)[1]
|
67
|
-
format(MSG, keyword: keyword)
|
68
|
-
end
|
69
|
-
|
70
69
|
def line(comment)
|
71
70
|
comment.location.expression.source_line
|
72
71
|
end
|