rubocop 0.91.0 → 1.0.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 +1 -1
- data/config/default.yml +100 -54
- data/lib/rubocop.rb +10 -6
- data/lib/rubocop/cached_data.rb +2 -1
- data/lib/rubocop/cli/command/version.rb +1 -1
- data/lib/rubocop/comment_config.rb +9 -5
- data/lib/rubocop/config.rb +4 -0
- data/lib/rubocop/config_loader.rb +19 -2
- data/lib/rubocop/config_loader_resolver.rb +7 -5
- data/lib/rubocop/config_regeneration.rb +33 -0
- data/lib/rubocop/config_validator.rb +7 -6
- data/lib/rubocop/cop/badge.rb +9 -24
- data/lib/rubocop/cop/base.rb +16 -1
- data/lib/rubocop/cop/commissioner.rb +34 -20
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
- data/lib/rubocop/cop/layout/class_structure.rb +8 -1
- data/lib/rubocop/cop/layout/dot_position.rb +6 -9
- 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 +13 -8
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -2
- 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 +4 -13
- data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +0 -4
- 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/layout/trailing_whitespace.rb +37 -13
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +18 -1
- data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
- 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/hash_compare_by_identity.rb +37 -0
- 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/mixed_regexp_capture_types.rb +1 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
- 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/redundant_safe_navigation.rb +78 -0
- 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/to_json.rb +1 -1
- 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/block_length.rb +3 -1
- data/lib/rubocop/cop/metrics/class_length.rb +14 -6
- data/lib/rubocop/cop/metrics/parameter_lists.rb +4 -1
- 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/hash_transform_method.rb +1 -1
- 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/naming/binary_operator_parameter_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +15 -2
- data/lib/rubocop/cop/security/open.rb +12 -10
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +6 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
- data/lib/rubocop/cop/style/array_coercion.rb +4 -0
- data/lib/rubocop/cop/style/case_like_if.rb +20 -4
- data/lib/rubocop/cop/style/class_equality_comparison.rb +64 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +13 -11
- data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
- data/lib/rubocop/cop/style/date_time.rb +12 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +6 -2
- data/lib/rubocop/cop/style/for.rb +0 -4
- data/lib/rubocop/cop/style/format_string_token.rb +48 -3
- 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/method_call_with_args_parentheses.rb +10 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +6 -11
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +7 -11
- data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
- data/lib/rubocop/cop/style/mixin_usage.rb +7 -27
- 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/nested_ternary_operator.rb +2 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +12 -1
- data/lib/rubocop/cop/style/raise_args.rb +0 -3
- 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_begin.rb +36 -8
- data/lib/rubocop/cop/style/redundant_condition.rb +5 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
- data/lib/rubocop/cop/style/redundant_interpolation.rb +6 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +6 -3
- data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +39 -24
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -15
- data/lib/rubocop/cop/style/redundant_return.rb +17 -17
- data/lib/rubocop/cop/style/redundant_self.rb +10 -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/safe_navigation.rb +16 -4
- data/lib/rubocop/cop/style/string_concatenation.rb +14 -2
- data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -3
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +3 -1
- data/lib/rubocop/cop/util.rb +0 -1
- data/lib/rubocop/cop/variable_force/branch.rb +0 -4
- data/lib/rubocop/directive_comment.rb +32 -0
- data/lib/rubocop/ext/regexp_node.rb +20 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +12 -5
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/options.rb +22 -17
- data/lib/rubocop/result_cache.rb +8 -2
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +5 -5
- data/lib/rubocop/runner.rb +9 -5
- data/lib/rubocop/target_finder.rb +27 -26
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +61 -6
- metadata +14 -17
- data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
- data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -51,7 +51,12 @@ module RuboCop
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def single_variable_interpolation?(node)
|
54
|
-
node.children.one?
|
54
|
+
return false unless node.children.one?
|
55
|
+
|
56
|
+
first_child = node.children.first
|
57
|
+
|
58
|
+
variable_interpolation?(first_child) ||
|
59
|
+
first_child.send_type? && !first_child.operator_method?
|
55
60
|
end
|
56
61
|
|
57
62
|
def interpolation?(node)
|
@@ -104,9 +104,13 @@ module RuboCop
|
|
104
104
|
return offense(begin_node, 'a variable') if node.variable?
|
105
105
|
return offense(begin_node, 'a constant') if node.const_type?
|
106
106
|
|
107
|
+
return offense(begin_node, 'an interpolated expression') if interpolation?(begin_node)
|
108
|
+
|
107
109
|
check_send(begin_node, node) if node.call_type?
|
108
110
|
end
|
109
111
|
|
112
|
+
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
113
|
+
|
110
114
|
def check_send(begin_node, node)
|
111
115
|
return check_unary(begin_node, node) if node.unary_operation?
|
112
116
|
|
@@ -175,10 +179,9 @@ module RuboCop
|
|
175
179
|
def raised_to_power_negative_numeric?(begin_node, node)
|
176
180
|
return false unless node.numeric_type?
|
177
181
|
|
178
|
-
|
179
|
-
return false
|
182
|
+
next_sibling = begin_node.right_sibling
|
183
|
+
return false unless next_sibling
|
180
184
|
|
181
|
-
next_sibling = siblings[begin_node.sibling_index + 1]
|
182
185
|
base_value = node.children.first
|
183
186
|
|
184
187
|
base_value.negative? && next_sibling == :**
|
@@ -17,7 +17,9 @@ module RuboCop
|
|
17
17
|
# time = "8 o'clock"
|
18
18
|
# question = '"What did you say?"'
|
19
19
|
#
|
20
|
-
class RedundantPercentQ <
|
20
|
+
class RedundantPercentQ < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
21
23
|
MSG = 'Use `%<q_type>s` only for strings that contain both ' \
|
22
24
|
'single quotes and double quotes%<extra>s.'
|
23
25
|
DYNAMIC_MSG = ', or for dynamic strings that contain ' \
|
@@ -45,22 +47,18 @@ module RuboCop
|
|
45
47
|
check(node)
|
46
48
|
end
|
47
49
|
|
48
|
-
def autocorrect(node)
|
49
|
-
delimiter =
|
50
|
-
/^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
|
51
|
-
lambda do |corrector|
|
52
|
-
corrector.replace(node.loc.begin, delimiter)
|
53
|
-
corrector.replace(node.loc.end, delimiter)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
50
|
private
|
58
51
|
|
59
52
|
def check(node)
|
60
53
|
return unless start_with_percent_q_variant?(node)
|
61
54
|
return if interpolated_quotes?(node) || allowed_percent_q?(node)
|
62
55
|
|
63
|
-
add_offense(node)
|
56
|
+
add_offense(node) do |corrector|
|
57
|
+
delimiter = /^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
|
58
|
+
|
59
|
+
corrector.replace(node.loc.begin, delimiter)
|
60
|
+
corrector.replace(node.loc.end, delimiter)
|
61
|
+
end
|
64
62
|
end
|
65
63
|
|
66
64
|
def interpolated_quotes?(node)
|
@@ -22,32 +22,14 @@ module RuboCop
|
|
22
22
|
# # good
|
23
23
|
# r = /[ab]/
|
24
24
|
class RedundantRegexpCharacterClass < Base
|
25
|
-
include MatchRange
|
26
|
-
include RegexpLiteralHelp
|
27
25
|
extend AutoCorrector
|
28
26
|
|
27
|
+
REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS = '.*+?{}()|$'.chars.freeze
|
29
28
|
MSG_REDUNDANT_CHARACTER_CLASS = 'Redundant single-element character class, ' \
|
30
29
|
'`%<char_class>s` can be replaced with `%<element>s`.'
|
31
30
|
|
32
|
-
PATTERN = /
|
33
|
-
(
|
34
|
-
(?<!\\) # No \-prefix (i.e. not escaped)
|
35
|
-
\[ # Literal [
|
36
|
-
(?!\#\{) # Not (the start of) an interpolation
|
37
|
-
(?: # Either...
|
38
|
-
\\[^b] | # Any escaped character except b (which would change behaviour)
|
39
|
-
[^.*+?{}()|$] | # or one that doesn't require escaping outside the character class
|
40
|
-
\\[upP]\{[^}]+\} # or a unicode code-point or property
|
41
|
-
)
|
42
|
-
(?<!\\) # No \-prefix (i.e. not escaped)
|
43
|
-
\] # Literal ]
|
44
|
-
)
|
45
|
-
/x.freeze
|
46
|
-
|
47
31
|
def on_regexp(node)
|
48
32
|
each_redundant_character_class(node) do |loc|
|
49
|
-
next if whitespace_in_free_space_mode?(node, loc)
|
50
|
-
|
51
33
|
add_offense(
|
52
34
|
loc, message: format(
|
53
35
|
MSG_REDUNDANT_CHARACTER_CLASS,
|
@@ -63,19 +45,52 @@ module RuboCop
|
|
63
45
|
private
|
64
46
|
|
65
47
|
def each_redundant_character_class(node)
|
66
|
-
|
67
|
-
|
48
|
+
each_single_element_character_class(node) do |char_class|
|
49
|
+
next unless redundant_single_element_character_class?(node, char_class)
|
50
|
+
|
51
|
+
yield node.loc.begin.adjust(begin_pos: 1 + char_class.ts, end_pos: char_class.te)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def each_single_element_character_class(node)
|
56
|
+
node.parsed_tree&.each_expression do |expr|
|
57
|
+
next if expr.type != :set || expr.expressions.size != 1
|
58
|
+
next if expr.negative?
|
59
|
+
next if %i[set posixclass nonposixclass].include?(expr.expressions.first.type)
|
60
|
+
|
61
|
+
yield expr
|
68
62
|
end
|
69
63
|
end
|
70
64
|
|
65
|
+
def redundant_single_element_character_class?(node, char_class)
|
66
|
+
class_elem = char_class.expressions.first.text
|
67
|
+
|
68
|
+
non_redundant =
|
69
|
+
whitespace_in_free_space_mode?(node, class_elem) ||
|
70
|
+
backslash_b?(class_elem) ||
|
71
|
+
requires_escape_outside_char_class?(class_elem)
|
72
|
+
|
73
|
+
!non_redundant
|
74
|
+
end
|
75
|
+
|
71
76
|
def without_character_class(loc)
|
72
77
|
loc.source[1..-2]
|
73
78
|
end
|
74
79
|
|
75
|
-
def whitespace_in_free_space_mode?(node,
|
76
|
-
return false unless
|
80
|
+
def whitespace_in_free_space_mode?(node, elem)
|
81
|
+
return false unless node.extended?
|
82
|
+
|
83
|
+
/\s/.match?(elem)
|
84
|
+
end
|
85
|
+
|
86
|
+
def backslash_b?(elem)
|
87
|
+
# \b's behaviour is different inside and outside of a character class, matching word
|
88
|
+
# boundaries outside but backspace (0x08) when inside.
|
89
|
+
elem == '\b'
|
90
|
+
end
|
77
91
|
|
78
|
-
|
92
|
+
def requires_escape_outside_char_class?(elem)
|
93
|
+
REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS.include?(elem)
|
79
94
|
end
|
80
95
|
end
|
81
96
|
end
|
@@ -34,7 +34,6 @@ module RuboCop
|
|
34
34
|
# /[+\-]\d/
|
35
35
|
class RedundantRegexpEscape < Base
|
36
36
|
include RangeHelp
|
37
|
-
include RegexpLiteralHelp
|
38
37
|
extend AutoCorrector
|
39
38
|
|
40
39
|
MSG_REDUNDANT_ESCAPE = 'Redundant escape inside regexp literal'
|
@@ -59,9 +58,9 @@ module RuboCop
|
|
59
58
|
|
60
59
|
def allowed_escape?(node, char, within_character_class)
|
61
60
|
# Strictly speaking a few single-letter metachars are currently
|
62
|
-
# unnecessary to "escape", e.g.
|
61
|
+
# unnecessary to "escape", e.g. i, E, F, but enumerating them is
|
63
62
|
# rather difficult, and their behaviour could change over time with
|
64
|
-
# different versions of Ruby so that e.g. /\
|
63
|
+
# different versions of Ruby so that e.g. /\i/ != /i/
|
65
64
|
return true if /[[:alnum:]]/.match?(char)
|
66
65
|
return true if ALLOWED_ALWAYS_ESCAPES.include?(char) || delimiter?(node, char)
|
67
66
|
|
@@ -82,19 +81,13 @@ module RuboCop
|
|
82
81
|
end
|
83
82
|
|
84
83
|
def each_escape(node)
|
85
|
-
|
86
|
-
[
|
87
|
-
|
88
|
-
if
|
89
|
-
|
90
|
-
|
91
|
-
[nil, char_class_depth]
|
92
|
-
elsif previous == '['
|
93
|
-
[current, char_class_depth + 1]
|
94
|
-
elsif current == ']'
|
95
|
-
[current, char_class_depth - 1]
|
84
|
+
node.parsed_tree&.traverse&.reduce(0) do |char_class_depth, (event, expr)|
|
85
|
+
yield(expr.text[1], expr.ts, !char_class_depth.zero?) if expr.type == :escape
|
86
|
+
|
87
|
+
if expr.type == :set
|
88
|
+
char_class_depth + (event == :enter ? 1 : -1)
|
96
89
|
else
|
97
|
-
|
90
|
+
char_class_depth
|
98
91
|
end
|
99
92
|
end
|
100
93
|
end
|
@@ -47,8 +47,9 @@ module RuboCop
|
|
47
47
|
# return x, y
|
48
48
|
# end
|
49
49
|
#
|
50
|
-
class RedundantReturn <
|
50
|
+
class RedundantReturn < Base
|
51
51
|
include RangeHelp
|
52
|
+
extend AutoCorrector
|
52
53
|
|
53
54
|
MSG = 'Redundant `return` detected.'
|
54
55
|
MULTI_RETURN_MSG = 'To return multiple values, use an array.'
|
@@ -58,16 +59,6 @@ module RuboCop
|
|
58
59
|
end
|
59
60
|
alias on_defs on_def
|
60
61
|
|
61
|
-
def autocorrect(node)
|
62
|
-
lambda do |corrector|
|
63
|
-
if node.arguments?
|
64
|
-
correct_with_arguments(node, corrector)
|
65
|
-
else
|
66
|
-
correct_without_arguments(node, corrector)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
62
|
private
|
72
63
|
|
73
64
|
def correct_without_arguments(return_node, corrector)
|
@@ -108,8 +99,8 @@ module RuboCop
|
|
108
99
|
when :return then check_return_node(node)
|
109
100
|
when :case then check_case_node(node)
|
110
101
|
when :if then check_if_node(node)
|
111
|
-
when :rescue
|
112
|
-
|
102
|
+
when :rescue then check_rescue_node(node)
|
103
|
+
when :resbody then check_resbody_node(node)
|
113
104
|
when :ensure then check_ensure_node(node)
|
114
105
|
when :begin, :kwbegin
|
115
106
|
check_begin_node(node)
|
@@ -121,7 +112,13 @@ module RuboCop
|
|
121
112
|
return if cop_config['AllowMultipleReturnValues'] &&
|
122
113
|
node.children.size > 1
|
123
114
|
|
124
|
-
add_offense(node,
|
115
|
+
add_offense(node.loc.keyword, message: message(node)) do |corrector|
|
116
|
+
if node.arguments?
|
117
|
+
correct_with_arguments(node, corrector)
|
118
|
+
else
|
119
|
+
correct_without_arguments(node, corrector)
|
120
|
+
end
|
121
|
+
end
|
125
122
|
end
|
126
123
|
|
127
124
|
def check_case_node(node)
|
@@ -137,9 +134,12 @@ module RuboCop
|
|
137
134
|
end
|
138
135
|
|
139
136
|
def check_rescue_node(node)
|
140
|
-
node.
|
141
|
-
|
142
|
-
|
137
|
+
node.branches.each { |branch| check_branch(branch) }
|
138
|
+
check_branch(node.body) unless node.else?
|
139
|
+
end
|
140
|
+
|
141
|
+
def check_resbody_node(node)
|
142
|
+
check_branch(node.body)
|
143
143
|
end
|
144
144
|
|
145
145
|
def check_ensure_node(node)
|
@@ -41,7 +41,9 @@ module RuboCop
|
|
41
41
|
# self.bar == bar # Resolves name clash with argument of the block.
|
42
42
|
# end
|
43
43
|
# end
|
44
|
-
class RedundantSelf <
|
44
|
+
class RedundantSelf < Base
|
45
|
+
extend AutoCorrector
|
46
|
+
|
45
47
|
MSG = 'Redundant `self` detected.'
|
46
48
|
KERNEL_METHODS = Kernel.methods(false)
|
47
49
|
KEYWORDS = %i[alias and begin break case class def defined? do
|
@@ -106,20 +108,16 @@ module RuboCop
|
|
106
108
|
|
107
109
|
return if allowed_send_node?(node)
|
108
110
|
|
109
|
-
add_offense(node)
|
111
|
+
add_offense(node) do |corrector|
|
112
|
+
corrector.remove(node.receiver)
|
113
|
+
corrector.remove(node.loc.dot)
|
114
|
+
end
|
110
115
|
end
|
111
116
|
|
112
117
|
def on_block(node)
|
113
118
|
add_scope(node, @local_variables_scopes[node])
|
114
119
|
end
|
115
120
|
|
116
|
-
def autocorrect(node)
|
117
|
-
lambda do |corrector|
|
118
|
-
corrector.remove(node.receiver)
|
119
|
-
corrector.remove(node.loc.dot)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
121
|
private
|
124
122
|
|
125
123
|
def add_scope(node, local_variables = [])
|
@@ -131,6 +129,9 @@ module RuboCop
|
|
131
129
|
def allowed_send_node?(node)
|
132
130
|
@allowed_send_nodes.include?(node) ||
|
133
131
|
@local_variables_scopes[node].include?(node.method_name) ||
|
132
|
+
node.each_ancestor.any? do |ancestor|
|
133
|
+
@local_variables_scopes[ancestor].include?(node.method_name)
|
134
|
+
end ||
|
134
135
|
KERNEL_METHODS.include?(node.method_name)
|
135
136
|
end
|
136
137
|
|
@@ -49,8 +49,9 @@ module RuboCop
|
|
49
49
|
# # good
|
50
50
|
# arr.max_by(&:foo)
|
51
51
|
#
|
52
|
-
class RedundantSort <
|
52
|
+
class RedundantSort < Base
|
53
53
|
include RangeHelp
|
54
|
+
extend AutoCorrector
|
54
55
|
|
55
56
|
MSG = 'Use `%<suggestion>s` instead of '\
|
56
57
|
'`%<sorter>s...%<accessor_source>s`.'
|
@@ -82,35 +83,23 @@ module RuboCop
|
|
82
83
|
return
|
83
84
|
end
|
84
85
|
|
85
|
-
|
86
|
-
location: offense_range(sort_node, ancestor),
|
87
|
-
message: message(ancestor,
|
88
|
-
sorter,
|
89
|
-
accessor))
|
90
|
-
end
|
91
|
-
|
92
|
-
def autocorrect(node)
|
93
|
-
sort_node, sorter, accessor = redundant_sort?(node)
|
94
|
-
|
95
|
-
lambda do |corrector|
|
96
|
-
# Remove accessor, e.g. `first` or `[-1]`.
|
97
|
-
corrector.remove(
|
98
|
-
range_between(
|
99
|
-
accessor_start(node),
|
100
|
-
node.loc.expression.end_pos
|
101
|
-
)
|
102
|
-
)
|
86
|
+
message = message(ancestor, sorter, accessor)
|
103
87
|
|
104
|
-
|
105
|
-
corrector
|
106
|
-
sort_node.loc.selector,
|
107
|
-
suggestion(sorter, accessor, arg_value(node))
|
108
|
-
)
|
88
|
+
add_offense(offense_range(sort_node, ancestor), message: message) do |corrector|
|
89
|
+
autocorrect(corrector, ancestor, sort_node, sorter, accessor)
|
109
90
|
end
|
110
91
|
end
|
111
92
|
|
112
93
|
private
|
113
94
|
|
95
|
+
def autocorrect(corrector, node, sort_node, sorter, accessor)
|
96
|
+
# Remove accessor, e.g. `first` or `[-1]`.
|
97
|
+
corrector.remove(range_between(accessor_start(node), node.loc.expression.end_pos))
|
98
|
+
|
99
|
+
# Replace "sort" or "sort_by" with the appropriate min/max method.
|
100
|
+
corrector.replace(sort_node.loc.selector, suggestion(sorter, accessor, arg_value(node)))
|
101
|
+
end
|
102
|
+
|
114
103
|
def offense_range(sort_node, ancestor)
|
115
104
|
range_between(sort_node.loc.selector.begin_pos, ancestor.loc.expression.end_pos)
|
116
105
|
end
|
@@ -15,8 +15,9 @@ module RuboCop
|
|
15
15
|
#
|
16
16
|
# # good
|
17
17
|
# array.sort
|
18
|
-
class RedundantSortBy <
|
18
|
+
class RedundantSortBy < Base
|
19
19
|
include RangeHelp
|
20
|
+
extend AutoCorrector
|
20
21
|
|
21
22
|
MSG = 'Use `sort` instead of `sort_by { |%<var>s| %<var>s }`.'
|
22
23
|
|
@@ -28,17 +29,12 @@ module RuboCop
|
|
28
29
|
redundant_sort_by(node) do |send, var_name|
|
29
30
|
range = sort_by_range(send, node)
|
30
31
|
|
31
|
-
add_offense(
|
32
|
-
|
33
|
-
|
32
|
+
add_offense(range, message: format(MSG, var: var_name)) do |corrector|
|
33
|
+
corrector.replace(range, 'sort')
|
34
|
+
end
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
def autocorrect(node)
|
38
|
-
send = node.send_node
|
39
|
-
->(corrector) { corrector.replace(sort_by_range(send, node), 'sort') }
|
40
|
-
end
|
41
|
-
|
42
38
|
private
|
43
39
|
|
44
40
|
def sort_by_range(send, node)
|
@@ -70,10 +70,11 @@ module RuboCop
|
|
70
70
|
# rescue StandardError, SecurityError
|
71
71
|
# bar
|
72
72
|
# end
|
73
|
-
class RescueStandardError <
|
73
|
+
class RescueStandardError < Base
|
74
74
|
include RescueNode
|
75
75
|
include ConfigurableEnforcedStyle
|
76
76
|
include RangeHelp
|
77
|
+
extend AutoCorrector
|
77
78
|
|
78
79
|
MSG_IMPLICIT = 'Omit the error class when rescuing ' \
|
79
80
|
'`StandardError` by itself.'
|
@@ -94,28 +95,31 @@ module RuboCop
|
|
94
95
|
case style
|
95
96
|
when :implicit
|
96
97
|
rescue_standard_error?(node) do |error|
|
97
|
-
|
98
|
-
location: node.loc.keyword.join(error.loc.expression),
|
99
|
-
message: MSG_IMPLICIT)
|
98
|
+
offense_for_implicit_enforced_style(node, error)
|
100
99
|
end
|
101
100
|
when :explicit
|
102
101
|
rescue_without_error_class?(node) do
|
103
|
-
|
102
|
+
offense_for_exlicit_enforced_style(node)
|
104
103
|
end
|
105
104
|
end
|
106
105
|
end
|
107
106
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
107
|
+
private
|
108
|
+
|
109
|
+
def offense_for_implicit_enforced_style(node, error)
|
110
|
+
range = node.loc.keyword.join(error.loc.expression)
|
111
|
+
|
112
|
+
add_offense(range, message: MSG_IMPLICIT) do |corrector|
|
113
|
+
error = rescue_standard_error?(node)
|
114
|
+
range = range_between(node.loc.keyword.end_pos, error.loc.expression.end_pos)
|
115
|
+
|
116
|
+
corrector.remove(range)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def offense_for_exlicit_enforced_style(node)
|
121
|
+
add_offense(node.loc.keyword, message: MSG_EXPLICIT) do |corrector|
|
122
|
+
corrector.insert_after(node.loc.keyword, ' StandardError')
|
119
123
|
end
|
120
124
|
end
|
121
125
|
end
|