rubocop 0.47.1 → 0.48.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.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +28 -16
- data/config/default.yml +203 -115
- data/config/disabled.yml +0 -5
- data/config/enabled.yml +92 -8
- data/lib/rubocop.rb +24 -1
- data/lib/rubocop/ast/builder.rb +7 -2
- data/lib/rubocop/ast/node.rb +23 -20
- data/lib/rubocop/ast/node/and_node.rb +37 -0
- data/lib/rubocop/ast/node/array_node.rb +4 -1
- data/lib/rubocop/ast/node/case_node.rb +1 -0
- data/lib/rubocop/ast/node/ensure_node.rb +25 -0
- data/lib/rubocop/ast/node/hash_node.rb +10 -3
- data/lib/rubocop/ast/node/if_node.rb +2 -0
- data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +23 -0
- data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +35 -0
- data/lib/rubocop/ast/node/or_node.rb +37 -0
- data/lib/rubocop/ast/node/resbody_node.rb +25 -0
- data/lib/rubocop/ast/node/send_node.rb +190 -0
- data/lib/rubocop/ast/node/when_node.rb +1 -1
- data/lib/rubocop/ast/traversal.rb +15 -15
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +39 -15
- data/lib/rubocop/config_loader.rb +34 -13
- data/lib/rubocop/cop/bundler/ordered_gems.rb +23 -4
- data/lib/rubocop/cop/commissioner.rb +4 -0
- data/lib/rubocop/cop/cop.rb +5 -0
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +53 -0
- data/lib/rubocop/cop/lint/debugger.rb +8 -1
- data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -4
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +3 -1
- data/lib/rubocop/cop/lint/empty_ensure.rb +6 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +20 -18
- data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -3
- data/lib/rubocop/cop/lint/literal_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/multiple_compare.rb +5 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +26 -18
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +7 -8
- data/lib/rubocop/cop/lint/require_parentheses.rb +7 -13
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +7 -3
- data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -6
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +7 -8
- data/lib/rubocop/cop/lint/unneeded_disable.rb +35 -11
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +5 -2
- data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -6
- data/lib/rubocop/cop/lint/useless_assignment.rb +2 -1
- data/lib/rubocop/cop/lint/useless_comparison.rb +5 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +4 -4
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -2
- data/lib/rubocop/cop/metrics/line_length.rb +2 -9
- data/lib/rubocop/cop/metrics/parameter_lists.rb +4 -3
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +2 -2
- data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
- data/lib/rubocop/cop/mixin/array_hash_indentation.rb +2 -2
- data/lib/rubocop/cop/mixin/check_assignment.rb +6 -6
- data/lib/rubocop/cop/mixin/duplication.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/ignored_pattern.rb +27 -0
- data/lib/rubocop/cop/mixin/method_preference.rb +2 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +17 -29
- data/lib/rubocop/cop/mixin/on_method_def.rb +3 -3
- data/lib/rubocop/cop/mixin/percent_literal.rb +27 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +21 -0
- data/lib/rubocop/cop/mixin/safe_mode.rb +1 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -1
- data/lib/rubocop/cop/mixin/target_rails_version.rb +16 -0
- data/lib/rubocop/cop/mixin/unused_argument.rb +1 -1
- data/lib/rubocop/cop/offense.rb +3 -3
- data/lib/rubocop/cop/performance/casecmp.rb +1 -1
- data/lib/rubocop/cop/performance/detect.rb +2 -1
- data/lib/rubocop/cop/performance/double_start_end_with.rb +35 -1
- data/lib/rubocop/cop/performance/end_with.rb +3 -1
- data/lib/rubocop/cop/performance/flat_map.rb +6 -6
- data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -2
- data/lib/rubocop/cop/performance/range_include.rb +3 -1
- data/lib/rubocop/cop/performance/redundant_match.rb +6 -5
- data/lib/rubocop/cop/performance/regexp_match.rb +10 -3
- data/lib/rubocop/cop/performance/reverse_each.rb +2 -1
- data/lib/rubocop/cop/performance/size.rb +6 -11
- data/lib/rubocop/cop/performance/start_with.rb +3 -1
- data/lib/rubocop/cop/performance/string_replacement.rb +13 -18
- data/lib/rubocop/cop/performance/times_map.rb +4 -4
- data/lib/rubocop/cop/rails/action_filter.rb +42 -42
- data/lib/rubocop/cop/rails/active_support_aliases.rb +68 -0
- data/lib/rubocop/cop/rails/blank.rb +131 -0
- data/lib/rubocop/cop/rails/date.rb +25 -28
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +5 -7
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +7 -3
- data/lib/rubocop/cop/rails/exit.rb +9 -9
- data/lib/rubocop/cop/rails/file_path.rb +5 -14
- data/lib/rubocop/cop/rails/find_by.rb +8 -10
- data/lib/rubocop/cop/rails/find_each.rb +6 -9
- data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -0
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +15 -7
- data/lib/rubocop/cop/rails/output.rb +3 -5
- data/lib/rubocop/cop/rails/output_safety.rb +4 -8
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +25 -24
- data/lib/rubocop/cop/rails/present.rb +137 -0
- data/lib/rubocop/cop/rails/read_write_attribute.rb +9 -18
- data/lib/rubocop/cop/rails/relative_date_constant.rb +53 -0
- data/lib/rubocop/cop/rails/request_referer.rb +7 -4
- data/lib/rubocop/cop/rails/reversible_migration.rb +1 -2
- data/lib/rubocop/cop/rails/safe_navigation.rb +2 -1
- data/lib/rubocop/cop/rails/save_bang.rb +10 -10
- data/lib/rubocop/cop/rails/skips_model_validations.rb +23 -6
- data/lib/rubocop/cop/rails/time_zone.rb +20 -18
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +3 -2
- data/lib/rubocop/cop/rails/validation.rb +8 -11
- data/lib/rubocop/cop/registry.rb +3 -3
- data/lib/rubocop/cop/security/json_load.rb +1 -1
- data/lib/rubocop/cop/security/marshal_load.rb +5 -1
- data/lib/rubocop/cop/security/yaml_load.rb +3 -3
- data/lib/rubocop/cop/severity.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +5 -5
- data/lib/rubocop/cop/style/align_hash.rb +1 -1
- data/lib/rubocop/cop/style/align_parameters.rb +5 -5
- data/lib/rubocop/cop/style/and_or.rb +16 -31
- data/lib/rubocop/cop/style/attr.rb +14 -8
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +8 -11
- data/lib/rubocop/cop/style/block_delimiters.rb +11 -13
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +19 -23
- data/lib/rubocop/cop/style/case_indentation.rb +2 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_check.rb +5 -7
- data/lib/rubocop/cop/style/closing_parenthesis_indentation.rb +5 -4
- data/lib/rubocop/cop/style/collection_methods.rb +8 -8
- data/lib/rubocop/cop/style/colon_method_call.rb +2 -9
- data/lib/rubocop/cop/style/conditional_assignment.rb +38 -45
- data/lib/rubocop/cop/style/constant_name.rb +1 -1
- data/lib/rubocop/cop/style/documentation_method.rb +1 -0
- data/lib/rubocop/cop/style/dot_position.rb +3 -7
- data/lib/rubocop/cop/style/double_negation.rb +2 -1
- data/lib/rubocop/cop/style/each_with_object.rb +1 -1
- data/lib/rubocop/cop/style/empty_else.rb +2 -2
- data/lib/rubocop/cop/style/empty_line_after_magic_comment.rb +63 -0
- data/lib/rubocop/cop/style/empty_line_between_defs.rb +74 -4
- data/lib/rubocop/cop/style/empty_lines_around_begin_body.rb +42 -0
- data/lib/rubocop/cop/style/empty_lines_around_exception_handling_keywords.rb +127 -0
- data/lib/rubocop/cop/style/empty_literal.rb +17 -9
- data/lib/rubocop/cop/style/end_of_line.rb +25 -3
- data/lib/rubocop/cop/style/file_name.rb +1 -1
- data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
- data/lib/rubocop/cop/style/first_parameter_indentation.rb +17 -19
- data/lib/rubocop/cop/style/for.rb +2 -4
- data/lib/rubocop/cop/style/format_string.rb +5 -4
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +27 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
- data/lib/rubocop/cop/style/indent_assignment.rb +2 -2
- data/lib/rubocop/cop/style/indent_hash.rb +2 -1
- data/lib/rubocop/cop/style/indent_heredoc.rb +173 -0
- data/lib/rubocop/cop/style/indentation_width.rb +61 -29
- data/lib/rubocop/cop/style/inverse_methods.rb +130 -0
- data/lib/rubocop/cop/style/lambda_call.rb +15 -11
- data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +26 -14
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -16
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
- data/lib/rubocop/cop/style/missing_else.rb +4 -3
- data/lib/rubocop/cop/style/mixin_grouping.rb +97 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +38 -5
- data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +2 -3
- data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +38 -19
- data/lib/rubocop/cop/style/mutable_constant.rb +5 -1
- data/lib/rubocop/cop/style/negated_if.rb +73 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +21 -19
- data/lib/rubocop/cop/style/next.rb +5 -5
- data/lib/rubocop/cop/style/non_nil_check.rb +7 -10
- data/lib/rubocop/cop/style/not.rb +3 -4
- data/lib/rubocop/cop/style/numeric_literals.rb +25 -3
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
- data/lib/rubocop/cop/style/op_method.rb +2 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +6 -3
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +52 -6
- data/lib/rubocop/cop/style/perl_backrefs.rb +1 -1
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -9
- data/lib/rubocop/cop/style/raise_args.rb +28 -24
- data/lib/rubocop/cop/style/redundant_freeze.rb +5 -7
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -3
- data/lib/rubocop/cop/style/redundant_self.rb +17 -35
- data/lib/rubocop/cop/style/rescue_modifier.rb +2 -14
- data/lib/rubocop/cop/style/self_assignment.rb +3 -3
- data/lib/rubocop/cop/style/send.rb +4 -5
- data/lib/rubocop/cop/style/space_after_not.rb +7 -8
- data/lib/rubocop/cop/style/space_around_keyword.rb +8 -9
- data/lib/rubocop/cop/style/space_around_operators.rb +19 -15
- data/lib/rubocop/cop/style/space_before_first_arg.rb +17 -14
- data/lib/rubocop/cop/style/space_inside_brackets.rb +1 -1
- data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +3 -3
- data/lib/rubocop/cop/style/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +14 -14
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +10 -5
- data/lib/rubocop/cop/style/struct_inheritance.rb +4 -15
- data/lib/rubocop/cop/style/symbol_array.rb +31 -35
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -2
- data/lib/rubocop/cop/style/ternary_parentheses.rb +41 -13
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +6 -9
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +1 -2
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +12 -34
- data/lib/rubocop/cop/style/zero_length_predicate.rb +11 -4
- data/lib/rubocop/cop/team.rb +4 -1
- data/lib/rubocop/cop/util.rb +33 -26
- data/lib/rubocop/cop/variable_force.rb +13 -13
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -8
- data/lib/rubocop/cop/variable_force/branch.rb +318 -0
- data/lib/rubocop/cop/variable_force/branchable.rb +21 -0
- data/lib/rubocop/cop/variable_force/reference.rb +1 -3
- data/lib/rubocop/cop/variable_force/scope.rb +36 -20
- data/lib/rubocop/cop/variable_force/variable.rb +9 -8
- data/lib/rubocop/formatter/colorizable.rb +10 -10
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +2 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -2
- data/lib/rubocop/magic_comment.rb +20 -6
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/platform.rb +11 -0
- data/lib/rubocop/processed_source.rb +1 -1
- data/lib/rubocop/remote_config.rb +18 -6
- data/lib/rubocop/result_cache.rb +8 -8
- data/lib/rubocop/rspec/cop_helper.rb +2 -0
- data/lib/rubocop/rspec/shared_contexts.rb +20 -0
- data/lib/rubocop/rspec/shared_examples.rb +1 -1
- data/lib/rubocop/runner.rb +2 -2
- data/lib/rubocop/target_finder.rb +64 -6
- data/lib/rubocop/version.rb +2 -4
- metadata +27 -4
- data/lib/rubocop/cop/variable_force/locatable.rb +0 -200
@@ -46,9 +46,13 @@ module RuboCop
|
|
46
46
|
MSG = 'Empty `ensure` block detected.'.freeze
|
47
47
|
|
48
48
|
def on_ensure(node)
|
49
|
-
|
49
|
+
add_offense(node, :keyword) unless node.body
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
+
def autocorrect(node)
|
53
|
+
lambda do |corrector|
|
54
|
+
corrector.remove(node.loc.keyword)
|
55
|
+
end
|
52
56
|
end
|
53
57
|
end
|
54
58
|
end
|
@@ -29,11 +29,13 @@ module RuboCop
|
|
29
29
|
SHOVEL = '<<'.freeze
|
30
30
|
PERCENT = '%'.freeze
|
31
31
|
PERCENT_PERCENT = '%%'.freeze
|
32
|
-
STRING_TYPES =
|
32
|
+
STRING_TYPES = %i(str dstr).freeze
|
33
33
|
NAMED_INTERPOLATION = /%(?:<\w+>|\{\w+\})/
|
34
34
|
|
35
35
|
def on_send(node)
|
36
|
-
|
36
|
+
return unless offending_node?(node)
|
37
|
+
|
38
|
+
add_offense(node, :selector)
|
37
39
|
end
|
38
40
|
|
39
41
|
private
|
@@ -41,7 +43,7 @@ module RuboCop
|
|
41
43
|
def offending_node?(node)
|
42
44
|
return false unless called_on_string?(node)
|
43
45
|
return false unless method_with_format_args?(node)
|
44
|
-
return false if named_mode?(node) ||
|
46
|
+
return false if named_mode?(node) || splat_args?(node)
|
45
47
|
|
46
48
|
num_of_format_args, num_of_expected_fields = count_matches(node)
|
47
49
|
|
@@ -82,18 +84,14 @@ module RuboCop
|
|
82
84
|
!relevant_node.source.scan(NAMED_FIELD_REGEX).empty?
|
83
85
|
end
|
84
86
|
|
85
|
-
def
|
87
|
+
def splat_args?(node)
|
86
88
|
return false if percent?(node)
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
args.butfirst.any?(&:splat_type?)
|
90
|
+
node.arguments.butfirst.any?(&:splat_type?)
|
91
91
|
end
|
92
92
|
|
93
93
|
def heredoc?(node)
|
94
|
-
|
95
|
-
|
96
|
-
args.source[0, 2] == SHOVEL
|
94
|
+
node.first_argument.source[0, 2] == SHOVEL
|
97
95
|
end
|
98
96
|
|
99
97
|
def count_matches(node)
|
@@ -131,7 +129,7 @@ module RuboCop
|
|
131
129
|
node
|
132
130
|
.source
|
133
131
|
.scan(FIELD_REGEX)
|
134
|
-
.
|
132
|
+
.reject { |x| x.first == PERCENT_PERCENT }
|
135
133
|
.reduce(0) { |acc, elem| acc + (elem[2] =~ /\*/ ? 2 : 1) }
|
136
134
|
end
|
137
135
|
|
@@ -154,13 +152,13 @@ module RuboCop
|
|
154
152
|
end
|
155
153
|
|
156
154
|
def percent?(node)
|
157
|
-
|
155
|
+
receiver = node.receiver
|
158
156
|
|
159
|
-
percent = method_name == :% &&
|
160
|
-
(STRING_TYPES.include?(
|
161
|
-
|
157
|
+
percent = node.method_name == :% &&
|
158
|
+
(STRING_TYPES.include?(receiver.type) ||
|
159
|
+
node.first_argument.array_type?)
|
162
160
|
|
163
|
-
if percent && STRING_TYPES.include?(
|
161
|
+
if percent && STRING_TYPES.include?(receiver.type)
|
164
162
|
return false if heredoc?(node)
|
165
163
|
end
|
166
164
|
|
@@ -168,10 +166,14 @@ module RuboCop
|
|
168
166
|
end
|
169
167
|
|
170
168
|
def message(node)
|
171
|
-
_receiver, method_name, *_args = *node
|
172
169
|
num_args_for_format, num_expected_fields = count_matches(node)
|
173
170
|
|
174
|
-
method_name =
|
171
|
+
method_name = if node.method_name.to_s == PERCENT
|
172
|
+
'String#%'
|
173
|
+
else
|
174
|
+
node.method_name
|
175
|
+
end
|
176
|
+
|
175
177
|
format(MSG, num_args_for_format, method_name, num_expected_fields)
|
176
178
|
end
|
177
179
|
end
|
@@ -48,9 +48,7 @@ module RuboCop
|
|
48
48
|
MSG = 'Do not suppress exceptions.'.freeze
|
49
49
|
|
50
50
|
def on_resbody(node)
|
51
|
-
|
52
|
-
|
53
|
-
add_offense(node, :expression) unless body_node
|
51
|
+
add_offense(node, :expression) unless node.body
|
54
52
|
end
|
55
53
|
end
|
56
54
|
end
|
@@ -18,7 +18,7 @@ module RuboCop
|
|
18
18
|
# "result is 10"
|
19
19
|
class LiteralInInterpolation < Cop
|
20
20
|
MSG = 'Literal interpolation detected.'.freeze
|
21
|
-
COMPOSITE =
|
21
|
+
COMPOSITE = %i(array hash pair irange erange).freeze
|
22
22
|
|
23
23
|
def on_dstr(node)
|
24
24
|
node.each_child_node(:begin) do |begin_node|
|
@@ -22,7 +22,7 @@ module RuboCop
|
|
22
22
|
# x < y && y < z
|
23
23
|
# 10 <= x && x <= 20
|
24
24
|
class MultipleCompare < Cop
|
25
|
-
MSG = 'Use `&&` operator to compare multiple
|
25
|
+
MSG = 'Use the `&&` operator to compare multiple values.'.freeze
|
26
26
|
|
27
27
|
def_node_matcher :multiple_compare?, <<-PATTERN
|
28
28
|
(send (send _ {:< :> :<= :>=} $_) {:< :> :<= :>=} _)
|
@@ -30,13 +30,15 @@ module RuboCop
|
|
30
30
|
|
31
31
|
def on_send(node)
|
32
32
|
return unless multiple_compare?(node)
|
33
|
+
|
33
34
|
add_offense(node, :expression)
|
34
35
|
end
|
35
36
|
|
36
37
|
def autocorrect(node)
|
38
|
+
center = multiple_compare?(node)
|
39
|
+
new_center = "#{center.source} && #{center.source}"
|
40
|
+
|
37
41
|
lambda do |corrector|
|
38
|
-
center = multiple_compare?(node)
|
39
|
-
new_center = "#{center.source} && #{center.source}"
|
40
42
|
corrector.replace(center.source_range, new_center)
|
41
43
|
end
|
42
44
|
end
|
@@ -3,11 +3,16 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This cop checks for non-local
|
7
|
-
# It
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
6
|
+
# This cop checks for non-local exits from iterators without a return
|
7
|
+
# value. It registers an offense under these conditions:
|
8
|
+
#
|
9
|
+
# - No value is returned,
|
10
|
+
# - the block is preceded by a method chain,
|
11
|
+
# - the block has arguments,
|
12
|
+
# - the method which receives the block is not `define_method`
|
13
|
+
# or `define_singleton_method`,
|
14
|
+
# - the return is not contained in an inner scope, e.g. a lambda or a
|
15
|
+
# method definition.
|
11
16
|
#
|
12
17
|
# @example
|
13
18
|
#
|
@@ -40,17 +45,19 @@ module RuboCop
|
|
40
45
|
|
41
46
|
def on_return(return_node)
|
42
47
|
return if return_value?(return_node)
|
43
|
-
return_node.each_ancestor(:block) do |block_node|
|
44
|
-
send_node, args_node, _body_node = *block_node
|
45
48
|
|
46
|
-
|
47
|
-
break if
|
49
|
+
return_node.each_ancestor(:block, :def, :defs) do |node|
|
50
|
+
break if scoped_node?(node)
|
51
|
+
|
52
|
+
send_node, args_node, _body_node = *node
|
53
|
+
|
48
54
|
# if a proc is passed to `Module#define_method` or
|
49
55
|
# `Object#define_singleton_method`, `return` will not cause a
|
50
56
|
# non-local exit error
|
51
57
|
break if define_method?(send_node)
|
52
58
|
|
53
59
|
next if args_node.children.empty?
|
60
|
+
|
54
61
|
if chained_send?(send_node)
|
55
62
|
add_offense(return_node, :keyword)
|
56
63
|
break
|
@@ -58,19 +65,20 @@ module RuboCop
|
|
58
65
|
end
|
59
66
|
end
|
60
67
|
|
61
|
-
|
62
|
-
!return_node.children.empty?
|
63
|
-
end
|
68
|
+
private
|
64
69
|
|
65
|
-
def
|
66
|
-
|
67
|
-
!receiver_node.nil?
|
70
|
+
def scoped_node?(node)
|
71
|
+
node.def_type? || node.defs_type? || node.lambda?
|
68
72
|
end
|
69
73
|
|
70
|
-
def
|
71
|
-
|
72
|
-
%i(define_method define_singleton_method).include? selector
|
74
|
+
def return_value?(return_node)
|
75
|
+
!return_node.children.empty?
|
73
76
|
end
|
77
|
+
|
78
|
+
def_node_matcher :chained_send?, '(send !nil ...)'
|
79
|
+
def_node_matcher :define_method?, <<-PATTERN
|
80
|
+
(send _ {:define_method :define_singleton_method} _)
|
81
|
+
PATTERN
|
74
82
|
end
|
75
83
|
end
|
76
84
|
end
|
@@ -21,23 +21,22 @@ module RuboCop
|
|
21
21
|
MSG = '`(...)` interpreted as grouped expression.'.freeze
|
22
22
|
|
23
23
|
def on_send(node)
|
24
|
-
|
25
|
-
return
|
26
|
-
return if operator?(method_name) || node.asgn_method_call?
|
24
|
+
return unless node.arguments.one?
|
25
|
+
return if node.operator_method? || node.setter_method?
|
27
26
|
|
28
|
-
|
29
|
-
return unless first_arg.source.start_with?('(')
|
27
|
+
return unless node.first_argument.source.start_with?('(')
|
30
28
|
|
31
29
|
space_length = spaces_before_left_parenthesis(node)
|
32
30
|
return unless space_length > 0
|
33
31
|
|
34
|
-
add_offense(nil, space_range(
|
32
|
+
add_offense(nil, space_range(node.first_argument.source_range,
|
33
|
+
space_length))
|
35
34
|
end
|
36
35
|
|
37
36
|
private
|
38
37
|
|
39
38
|
def spaces_before_left_parenthesis(node)
|
40
|
-
receiver
|
39
|
+
receiver = node.receiver
|
41
40
|
receiver_length = if receiver
|
42
41
|
receiver.source.length
|
43
42
|
else
|
@@ -46,7 +45,7 @@ module RuboCop
|
|
46
45
|
without_receiver = node.source[receiver_length..-1]
|
47
46
|
|
48
47
|
# Escape question mark if any.
|
49
|
-
method_regexp = Regexp.escape(method_name)
|
48
|
+
method_regexp = Regexp.escape(node.method_name)
|
50
49
|
|
51
50
|
match = without_receiver.match(/^\s*\.?\s*#{method_regexp}(\s+)\(/)
|
52
51
|
match ? match.captures[0].length : 0
|
@@ -30,21 +30,19 @@ module RuboCop
|
|
30
30
|
'precedence.'.freeze
|
31
31
|
|
32
32
|
def on_send(node)
|
33
|
-
|
33
|
+
return if !node.arguments? || node.parenthesized?
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
elsif method_name.to_s.end_with?('?')
|
40
|
-
check_predicate(args.last, node)
|
35
|
+
if node.first_argument.if_type? && node.first_argument.ternary?
|
36
|
+
check_ternary(node.first_argument, node)
|
37
|
+
elsif node.predicate_method?
|
38
|
+
check_predicate(node.last_argument, node)
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
42
|
private
|
45
43
|
|
46
44
|
def check_ternary(ternary, node)
|
47
|
-
return unless
|
45
|
+
return unless ternary.condition.operator_keyword?
|
48
46
|
|
49
47
|
range = range_between(node.source_range.begin_pos,
|
50
48
|
ternary.condition.source_range.end_pos)
|
@@ -53,14 +51,10 @@ module RuboCop
|
|
53
51
|
end
|
54
52
|
|
55
53
|
def check_predicate(predicate, node)
|
56
|
-
return unless
|
54
|
+
return unless predicate.operator_keyword?
|
57
55
|
|
58
56
|
add_offense(node, :expression)
|
59
57
|
end
|
60
|
-
|
61
|
-
def offense?(node)
|
62
|
-
[:and, :or].include?(node.type)
|
63
|
-
end
|
64
58
|
end
|
65
59
|
end
|
66
60
|
end
|
@@ -29,8 +29,6 @@ module RuboCop
|
|
29
29
|
MSG = 'Do not chain ordinary method call' \
|
30
30
|
' after safe navigation operator.'.freeze
|
31
31
|
|
32
|
-
ADDITIONAL_NIL_METHODS = %i(present? blank? try).freeze
|
33
|
-
|
34
32
|
def_node_matcher :bad_method?, <<-PATTERN
|
35
33
|
(send (csend ...) $_ ...)
|
36
34
|
PATTERN
|
@@ -42,12 +40,14 @@ module RuboCop
|
|
42
40
|
return if nil_methods.include?(method)
|
43
41
|
|
44
42
|
loc = node.loc.dot || :selector
|
43
|
+
|
45
44
|
add_offense(node, loc)
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
48
|
def autocorrect(node)
|
50
49
|
dot = node.loc.dot
|
50
|
+
|
51
51
|
return unless dot
|
52
52
|
|
53
53
|
lambda do |corrector|
|
@@ -58,7 +58,11 @@ module RuboCop
|
|
58
58
|
private
|
59
59
|
|
60
60
|
def nil_methods
|
61
|
-
nil.methods +
|
61
|
+
nil.methods + whitelist
|
62
|
+
end
|
63
|
+
|
64
|
+
def whitelist
|
65
|
+
cop_config['Whitelist'].map(&:to_sym)
|
62
66
|
end
|
63
67
|
end
|
64
68
|
end
|
@@ -31,6 +31,8 @@ module RuboCop
|
|
31
31
|
# handle_exception
|
32
32
|
# end
|
33
33
|
class ShadowedException < Cop
|
34
|
+
include RescueNode
|
35
|
+
|
34
36
|
MSG = 'Do not shadow rescued Exceptions.'.freeze
|
35
37
|
|
36
38
|
def on_rescue(node)
|
@@ -68,12 +70,6 @@ module RuboCop
|
|
68
70
|
range_between(first_rescue.loc.expression.begin_pos, end_pos)
|
69
71
|
end
|
70
72
|
|
71
|
-
def rescue_modifier?(node)
|
72
|
-
node && node.rescue_type? &&
|
73
|
-
(node.parent.nil? || !(node.parent.kwbegin_type? ||
|
74
|
-
node.parent.ensure_type?))
|
75
|
-
end
|
76
|
-
|
77
73
|
def contains_multiple_levels_of_exceptions?(group)
|
78
74
|
if group.size > 1 && group.include?(Exception)
|
79
75
|
# Treat `Exception` as the highest level exception unless `nil` was
|
@@ -25,21 +25,20 @@ module RuboCop
|
|
25
25
|
def on_dstr(node)
|
26
26
|
node.each_child_node(:begin) do |begin_node|
|
27
27
|
final_node = begin_node.children.last
|
28
|
-
next unless final_node && final_node.send_type?
|
29
28
|
|
30
|
-
|
31
|
-
|
29
|
+
next unless final_node && final_node.send_type? &&
|
30
|
+
final_node.method?(:to_s) && !final_node.arguments?
|
32
31
|
|
33
|
-
add_offense(
|
34
|
-
final_node,
|
35
|
-
:selector,
|
36
|
-
receiver ? MSG_DEFAULT : MSG_SELF
|
37
|
-
)
|
32
|
+
add_offense(final_node, :selector)
|
38
33
|
end
|
39
34
|
end
|
40
35
|
|
41
36
|
private
|
42
37
|
|
38
|
+
def message(node)
|
39
|
+
node.receiver ? MSG_DEFAULT : MSG_SELF
|
40
|
+
end
|
41
|
+
|
43
42
|
def autocorrect(node)
|
44
43
|
lambda do |corrector|
|
45
44
|
receiver, _method_name, *_args = *node
|
@@ -70,7 +70,8 @@ module RuboCop
|
|
70
70
|
range_with_surrounding_space(range, :right, false)
|
71
71
|
end
|
72
72
|
|
73
|
-
def each_unneeded_disable(cop_disabled_line_ranges, offenses, comments
|
73
|
+
def each_unneeded_disable(cop_disabled_line_ranges, offenses, comments,
|
74
|
+
&block)
|
74
75
|
disabled_ranges = cop_disabled_line_ranges[COP_NAME] || [0..0]
|
75
76
|
|
76
77
|
cop_disabled_line_ranges.each do |cop, line_ranges|
|
@@ -78,16 +79,23 @@ module RuboCop
|
|
78
79
|
yield comment, cop
|
79
80
|
end
|
80
81
|
|
81
|
-
line_ranges
|
82
|
-
|
82
|
+
each_line_range(line_ranges, disabled_ranges, offenses, comments,
|
83
|
+
cop, &block)
|
84
|
+
end
|
85
|
+
end
|
83
86
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
+
def each_line_range(line_ranges, disabled_ranges, offenses, comments,
|
88
|
+
cop)
|
89
|
+
line_ranges.each_with_index do |line_range, ix|
|
90
|
+
comment = comments.find { |c| c.loc.line == line_range.begin }
|
87
91
|
|
88
|
-
|
89
|
-
|
92
|
+
unless all_disabled?(comment)
|
93
|
+
next if ignore_offense?(disabled_ranges, line_range)
|
90
94
|
end
|
95
|
+
|
96
|
+
unneeded_cop = find_unneeded(comment, offenses, cop, line_range,
|
97
|
+
line_ranges[ix + 1])
|
98
|
+
yield comment, unneeded_cop if unneeded_cop
|
91
99
|
end
|
92
100
|
end
|
93
101
|
|
@@ -99,13 +107,29 @@ module RuboCop
|
|
99
107
|
# the end of the previous range, it means that the cop was
|
100
108
|
# already disabled by an earlier comment. So it's unneeded
|
101
109
|
# whether there are offenses or not.
|
102
|
-
|
110
|
+
unneeded_comment = comments.find do |c|
|
111
|
+
c.loc.line == range.begin &&
|
112
|
+
# Comments disabling all cops don't count since it's reasonable
|
113
|
+
# to disable a few select cops first and then all cops further
|
114
|
+
# down in the code.
|
115
|
+
!all_disabled?(c)
|
116
|
+
end
|
117
|
+
yield unneeded_comment if unneeded_comment
|
103
118
|
end
|
104
119
|
end
|
105
120
|
|
106
|
-
def find_unneeded(comment, offenses, cop, line_range)
|
121
|
+
def find_unneeded(comment, offenses, cop, line_range, next_line_range)
|
107
122
|
if all_disabled?(comment)
|
108
|
-
'all
|
123
|
+
# If there's a disable all comment followed by a comment
|
124
|
+
# specifically disabling `cop`, we don't report the `all`
|
125
|
+
# comment. If the disable all comment is truly unneeded, we will
|
126
|
+
# detect that when examining the comments of another cop, and we
|
127
|
+
# get the full line range for the disable all.
|
128
|
+
if (next_line_range.nil? ||
|
129
|
+
line_range.last != next_line_range.first) &&
|
130
|
+
offenses.none? { |o| line_range.cover?(o.line) }
|
131
|
+
'all'
|
132
|
+
end
|
109
133
|
else
|
110
134
|
cop_offenses = offenses.select { |o| o.cop_name == cop }
|
111
135
|
cop if cop_offenses.none? { |o| line_range.cover?(o.line) }
|