rubocop 1.68.0 → 1.69.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 +41 -6
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +46 -0
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -4
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +15 -0
- data/lib/rubocop/cop/layout/line_length.rb +118 -4
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -35
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +16 -17
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +14 -6
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -3
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -5
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +1 -1
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +106 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -0
- data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +3 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/void.rb +3 -2
- data/lib/rubocop/cop/metrics/class_length.rb +7 -7
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
- data/lib/rubocop/cop/mixin/range_help.rb +0 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +0 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -11
- data/lib/rubocop/cop/naming/variable_name.rb +3 -4
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/security/compound_hash.rb +1 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +54 -25
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/array_intersect.rb +5 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +10 -2
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +19 -21
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/dig_chain.rb +89 -0
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -0
- data/lib/rubocop/cop/style/file_null.rb +73 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/for.rb +0 -1
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +1 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/hash_except.rb +19 -7
- data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +14 -5
- data/lib/rubocop/cop/style/inverse_methods.rb +0 -1
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +2 -2
- data/lib/rubocop/cop/style/lambda_call.rb +3 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +7 -11
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +4 -5
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -4
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +1 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
- data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +8 -13
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +36 -21
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +7 -6
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -0
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +8 -15
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +7 -5
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -1
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +13 -3
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -3
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +13 -12
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/variable_force.rb +4 -10
- data/lib/rubocop/cops_documentation_generator.rb +9 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +8 -0
- metadata +23 -14
@@ -32,6 +32,22 @@ module RuboCop
|
|
32
32
|
class UnreachableCode < Base
|
33
33
|
MSG = 'Unreachable code detected.'
|
34
34
|
|
35
|
+
def initialize(config = nil, options = nil)
|
36
|
+
super
|
37
|
+
@redefined = []
|
38
|
+
@instance_eval_count = 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def on_block(node)
|
42
|
+
@instance_eval_count += 1 if instance_eval_block?(node)
|
43
|
+
end
|
44
|
+
|
45
|
+
alias on_numblock on_block
|
46
|
+
|
47
|
+
def after_block(node)
|
48
|
+
@instance_eval_count -= 1 if instance_eval_block?(node)
|
49
|
+
end
|
50
|
+
|
35
51
|
def on_begin(node)
|
36
52
|
expressions = *node
|
37
53
|
|
@@ -46,19 +62,23 @@ module RuboCop
|
|
46
62
|
|
47
63
|
private
|
48
64
|
|
65
|
+
def redefinable_flow_method?(method)
|
66
|
+
%i[raise fail throw exit exit! abort].include? method
|
67
|
+
end
|
68
|
+
|
49
69
|
# @!method flow_command?(node)
|
50
70
|
def_node_matcher :flow_command?, <<~PATTERN
|
51
71
|
{
|
52
72
|
return next break retry redo
|
53
73
|
(send
|
54
74
|
{nil? (const {nil? cbase} :Kernel)}
|
55
|
-
|
75
|
+
#redefinable_flow_method?
|
56
76
|
...)
|
57
77
|
}
|
58
78
|
PATTERN
|
59
79
|
|
60
80
|
def flow_expression?(node)
|
61
|
-
return
|
81
|
+
return report_on_flow_command?(node) if flow_command?(node)
|
62
82
|
|
63
83
|
case node.type
|
64
84
|
when :begin, :kwbegin
|
@@ -68,6 +88,8 @@ module RuboCop
|
|
68
88
|
check_if(node)
|
69
89
|
when :case, :case_match
|
70
90
|
check_case(node)
|
91
|
+
when :def
|
92
|
+
register_redefinition(node)
|
71
93
|
else
|
72
94
|
false
|
73
95
|
end
|
@@ -88,6 +110,33 @@ module RuboCop
|
|
88
110
|
|
89
111
|
branches.all? { |branch| branch.body && flow_expression?(branch.body) }
|
90
112
|
end
|
113
|
+
|
114
|
+
def register_redefinition(node)
|
115
|
+
@redefined << node.method_name if redefinable_flow_method? node.method_name
|
116
|
+
false
|
117
|
+
end
|
118
|
+
|
119
|
+
def instance_eval_block?(node)
|
120
|
+
node.block_type? && node.method?(:instance_eval)
|
121
|
+
end
|
122
|
+
|
123
|
+
def report_on_flow_command?(node)
|
124
|
+
return true unless node.send_type?
|
125
|
+
|
126
|
+
# By the contract of this function, this case means that
|
127
|
+
# the method is called on `Kernel` in which case we
|
128
|
+
# always want to report a warning.
|
129
|
+
return true if node.receiver
|
130
|
+
|
131
|
+
# Inside an `instance_eval` we have no way to tell the
|
132
|
+
# type of `self` just by looking at the AST, so we can't
|
133
|
+
# tell if the give function that's called has been
|
134
|
+
# redefined or not, so to avoid false positives, we silence
|
135
|
+
# the warning.
|
136
|
+
return false if @instance_eval_count.positive?
|
137
|
+
|
138
|
+
!@redefined.include? node.method_name
|
139
|
+
end
|
91
140
|
end
|
92
141
|
end
|
93
142
|
end
|
@@ -39,6 +39,8 @@ module RuboCop
|
|
39
39
|
# end
|
40
40
|
#
|
41
41
|
# @example IgnoreNotImplementedMethods: true (default)
|
42
|
+
# # with default value of `NotImplementedExceptions: ['NotImplementedError']`
|
43
|
+
#
|
42
44
|
# # good
|
43
45
|
# def do_something(unused)
|
44
46
|
# raise NotImplementedError
|
@@ -48,6 +50,14 @@ module RuboCop
|
|
48
50
|
# fail "TODO"
|
49
51
|
# end
|
50
52
|
#
|
53
|
+
# @example IgnoreNotImplementedMethods: true
|
54
|
+
# # with `NotImplementedExceptions: ['AbstractMethodError']`
|
55
|
+
#
|
56
|
+
# # good
|
57
|
+
# def do_something(unused)
|
58
|
+
# raise AbstractMethodError
|
59
|
+
# end
|
60
|
+
#
|
51
61
|
# @example IgnoreNotImplementedMethods: false
|
52
62
|
# # bad
|
53
63
|
# def do_something(unused)
|
@@ -57,14 +67,13 @@ module RuboCop
|
|
57
67
|
# def do_something_else(unused)
|
58
68
|
# fail "TODO"
|
59
69
|
# end
|
60
|
-
#
|
61
70
|
class UnusedMethodArgument < Base
|
62
71
|
include UnusedArgument
|
63
72
|
extend AutoCorrector
|
64
73
|
|
65
74
|
# @!method not_implemented?(node)
|
66
75
|
def_node_matcher :not_implemented?, <<~PATTERN
|
67
|
-
{(send nil? :raise
|
76
|
+
{(send nil? :raise #allowed_exception_class? ...)
|
68
77
|
(send nil? :fail ...)}
|
69
78
|
PATTERN
|
70
79
|
|
@@ -115,6 +124,13 @@ module RuboCop
|
|
115
124
|
|
116
125
|
message
|
117
126
|
end
|
127
|
+
|
128
|
+
def allowed_exception_class?(node)
|
129
|
+
return false unless node.const_type?
|
130
|
+
|
131
|
+
allowed_class_names = Array(cop_config.fetch('NotImplementedExceptions', []))
|
132
|
+
allowed_class_names.include?(node.const_name)
|
133
|
+
end
|
118
134
|
end
|
119
135
|
end
|
120
136
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for calls to `defined?` with strings or symbols as the argument.
|
7
|
+
# Such calls will always return `'expression'`, you probably meant to
|
8
|
+
# check for the existence of a constant, method, or variable instead.
|
9
|
+
#
|
10
|
+
# `defined?` is part of the Ruby syntax and doesn't behave like normal methods.
|
11
|
+
# You can safely pass in what you are checking for directly, without encountering
|
12
|
+
# a `NameError`.
|
13
|
+
#
|
14
|
+
# When interpolation is used, oftentimes it is not possible to write the
|
15
|
+
# code with `defined?`. In these cases, switch to one of the more specific methods:
|
16
|
+
#
|
17
|
+
# * `class_variable_defined?`
|
18
|
+
# * `const_defined?`
|
19
|
+
# * `method_defined?`
|
20
|
+
# * `instance_variable_defined?`
|
21
|
+
# * `binding.local_variable_defined?`
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# defined?('FooBar')
|
27
|
+
# defined?(:FooBar)
|
28
|
+
# defined?(:foo_bar)
|
29
|
+
# defined?('foo_bar')
|
30
|
+
#
|
31
|
+
# # good
|
32
|
+
# defined?(FooBar)
|
33
|
+
# defined?(foo_bar)
|
34
|
+
#
|
35
|
+
# # bad - interpolation
|
36
|
+
# bar = 'Bar'
|
37
|
+
# defined?("Foo::#{bar}::Baz")
|
38
|
+
#
|
39
|
+
# # good
|
40
|
+
# bar = 'Bar'
|
41
|
+
# defined?(Foo) && Foo.const_defined?(bar) && Foo.const_get(bar).const_defined?(:Baz)
|
42
|
+
class UselessDefined < Base
|
43
|
+
MSG = 'Calling `defined?` with a %<type>s argument will always return a truthy value.'
|
44
|
+
TYPES = { str: 'string', dstr: 'string', sym: 'symbol', dsym: 'symbol' }.freeze
|
45
|
+
|
46
|
+
def on_defined?(node)
|
47
|
+
# NOTE: `defined?` always takes one argument. Anything else is a syntax error.
|
48
|
+
return unless (type = TYPES[node.first_argument.type])
|
49
|
+
|
50
|
+
add_offense(node, message: format(MSG, type: type))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -25,8 +25,12 @@ module RuboCop
|
|
25
25
|
# do_something_else
|
26
26
|
# end
|
27
27
|
class UselessElseWithoutRescue < Base
|
28
|
+
extend TargetRubyVersion
|
29
|
+
|
28
30
|
MSG = '`else` without `rescue` is useless.'
|
29
31
|
|
32
|
+
maximum_target_ruby_version 2.5
|
33
|
+
|
30
34
|
def on_new_investigation
|
31
35
|
processed_source.diagnostics.each do |diagnostic|
|
32
36
|
next unless diagnostic.reason == :useless_else
|
@@ -75,7 +75,7 @@ module RuboCop
|
|
75
75
|
def use_exception_variable_in_ensure?(resbody_node)
|
76
76
|
return false unless (exception_variable = resbody_node.exception_variable)
|
77
77
|
return false unless (ensure_node = resbody_node.each_ancestor(:ensure).first)
|
78
|
-
return false unless (ensure_body = ensure_node.
|
78
|
+
return false unless (ensure_body = ensure_node.branch)
|
79
79
|
|
80
80
|
ensure_body.each_descendant(:lvar).map(&:source).include?(exception_variable.source)
|
81
81
|
end
|
@@ -102,24 +102,18 @@ module RuboCop
|
|
102
102
|
when :op_asgn
|
103
103
|
process_binary_operator_assignment(node)
|
104
104
|
when *ASSIGNMENT_TYPES
|
105
|
-
|
106
|
-
process_assignment(node, rhs_node) if rhs_node
|
105
|
+
process_assignment(node, node.rhs) if node.rhs
|
107
106
|
end
|
108
107
|
end
|
109
108
|
|
110
109
|
def process_multiple_assignment(masgn_node)
|
111
|
-
|
112
|
-
|
113
|
-
mlhs_node.children.each_with_index do |lhs_node, index|
|
110
|
+
masgn_node.assignments.each_with_index do |lhs_node, index|
|
114
111
|
next unless ASSIGNMENT_TYPES.include?(lhs_node.type)
|
115
112
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
if mrhs_node.array_type? && rhs_node
|
120
|
-
process_assignment(lhs_variable_name, rhs_node)
|
113
|
+
if masgn_node.rhs.array_type? && (rhs_node = masgn_node.rhs.children[index])
|
114
|
+
process_assignment(lhs_node, rhs_node)
|
121
115
|
else
|
122
|
-
@local[
|
116
|
+
@local[lhs_node.name] = true
|
123
117
|
end
|
124
118
|
end
|
125
119
|
|
@@ -127,33 +121,28 @@ module RuboCop
|
|
127
121
|
end
|
128
122
|
|
129
123
|
def process_logical_operator_assignment(asgn_node)
|
130
|
-
|
131
|
-
return unless ASSIGNMENT_TYPES.include?(lhs_node.type)
|
124
|
+
return unless ASSIGNMENT_TYPES.include?(asgn_node.lhs.type)
|
132
125
|
|
133
|
-
process_assignment(
|
126
|
+
process_assignment(asgn_node.lhs, asgn_node.rhs)
|
134
127
|
|
135
128
|
throw :skip_children
|
136
129
|
end
|
137
130
|
|
138
131
|
def process_binary_operator_assignment(op_asgn_node)
|
139
|
-
lhs_node
|
132
|
+
lhs_node = op_asgn_node.lhs
|
140
133
|
return unless ASSIGNMENT_TYPES.include?(lhs_node.type)
|
141
134
|
|
142
|
-
|
143
|
-
@local[lhs_variable_name] = true
|
135
|
+
@local[lhs_node.name] = true
|
144
136
|
|
145
137
|
throw :skip_children
|
146
138
|
end
|
147
139
|
|
148
140
|
def process_assignment(asgn_node, rhs_node)
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
else
|
155
|
-
constructor?(rhs_node)
|
156
|
-
end
|
141
|
+
@local[asgn_node.name] = if rhs_node.variable?
|
142
|
+
@local[rhs_node.name]
|
143
|
+
else
|
144
|
+
constructor?(rhs_node)
|
145
|
+
end
|
157
146
|
end
|
158
147
|
|
159
148
|
def constructor?(node)
|
@@ -126,7 +126,7 @@ module RuboCop
|
|
126
126
|
|
127
127
|
def check_void_op(node, &block)
|
128
128
|
node = node.children.first while node.begin_type?
|
129
|
-
return unless node.
|
129
|
+
return unless node.call_type? && OPERATORS.include?(node.method_name)
|
130
130
|
return if block && yield(node)
|
131
131
|
|
132
132
|
add_offense(node.loc.selector,
|
@@ -196,7 +196,7 @@ module RuboCop
|
|
196
196
|
end
|
197
197
|
|
198
198
|
def check_ensure(node)
|
199
|
-
return unless (body = node.
|
199
|
+
return unless (body = node.branch)
|
200
200
|
# NOTE: the `begin` node case is already handled via `on_begin`
|
201
201
|
return if body.begin_type?
|
202
202
|
|
@@ -219,6 +219,7 @@ module RuboCop
|
|
219
219
|
if node.arguments.empty?
|
220
220
|
corrector.replace(node, node.receiver.source)
|
221
221
|
else
|
222
|
+
corrector.remove(node.loc.dot) if node.loc.dot
|
222
223
|
corrector.replace(
|
223
224
|
range_with_surrounding_space(range: node.loc.selector, side: :both,
|
224
225
|
newlines: false),
|
@@ -53,13 +53,13 @@ module RuboCop
|
|
53
53
|
def on_casgn(node)
|
54
54
|
parent = node.parent
|
55
55
|
|
56
|
-
if parent&.assignment?
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
56
|
+
block_node = if parent&.assignment?
|
57
|
+
parent.expression
|
58
|
+
elsif parent&.parent&.masgn_type?
|
59
|
+
parent.parent.expression
|
60
|
+
else
|
61
|
+
node.expression
|
62
|
+
end
|
63
63
|
|
64
64
|
return unless block_node.respond_to?(:class_definition?) && block_node.class_definition?
|
65
65
|
|
@@ -95,7 +95,7 @@ module RuboCop
|
|
95
95
|
def compound_assignment(node)
|
96
96
|
# Methods setter cannot be detected for multiple assignments
|
97
97
|
# and shorthand assigns, so we'll count them here instead
|
98
|
-
children = node.masgn_type? ? node.
|
98
|
+
children = node.masgn_type? ? node.assignments : node.children
|
99
99
|
|
100
100
|
will_be_miscounted = children.count do |child|
|
101
101
|
child.respond_to?(:setter_method?) && !child.setter_method?
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
extend NodePattern::Macros
|
10
10
|
include Util
|
11
11
|
|
12
|
-
FOLDABLE_TYPES = %i[array hash heredoc
|
12
|
+
FOLDABLE_TYPES = %i[array hash heredoc method_call].freeze
|
13
13
|
CLASSLIKE_TYPES = %i[class module].freeze
|
14
14
|
private_constant :FOLDABLE_TYPES, :CLASSLIKE_TYPES
|
15
15
|
|
@@ -148,8 +148,7 @@ module RuboCop
|
|
148
148
|
when :class, :module, :sclass, :block, :numblock, :def, :defs
|
149
149
|
node.body
|
150
150
|
when :casgn
|
151
|
-
|
152
|
-
extract_body(value)
|
151
|
+
extract_body(node.expression)
|
153
152
|
else
|
154
153
|
node
|
155
154
|
end
|
@@ -17,9 +17,7 @@ module RuboCop
|
|
17
17
|
alias on_and_asgn on_lvasgn
|
18
18
|
|
19
19
|
def on_send(node)
|
20
|
-
rhs = extract_rhs(node)
|
21
|
-
|
22
|
-
return unless rhs
|
20
|
+
return unless (rhs = extract_rhs(node))
|
23
21
|
|
24
22
|
check_assignment(node, rhs)
|
25
23
|
end
|
@@ -27,17 +25,11 @@ module RuboCop
|
|
27
25
|
module_function
|
28
26
|
|
29
27
|
def extract_rhs(node)
|
30
|
-
if node.
|
31
|
-
|
32
|
-
elsif node.op_asgn_type?
|
33
|
-
_lhs, _op, rhs = *node
|
34
|
-
elsif node.call_type?
|
35
|
-
rhs = node.last_argument
|
28
|
+
if node.call_type?
|
29
|
+
node.last_argument
|
36
30
|
elsif node.assignment?
|
37
|
-
|
31
|
+
node.expression
|
38
32
|
end
|
39
|
-
|
40
|
-
rhs
|
41
33
|
end
|
42
34
|
end
|
43
35
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Checks for code on multiple lines that could be rewritten on a single line
|
6
|
+
# without changing semantics or exceeding the `Max` parameter of `Layout/LineLength`.
|
7
|
+
module CheckSingleLineSuitability
|
8
|
+
def suitable_as_single_line?(node)
|
9
|
+
!too_long?(node) &&
|
10
|
+
!comment_within?(node) &&
|
11
|
+
safe_to_split?(node)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def too_long?(node)
|
17
|
+
lines = processed_source.lines[(node.first_line - 1)...node.last_line]
|
18
|
+
to_single_line(lines.join("\n")).length > max_line_length
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_single_line(source)
|
22
|
+
source
|
23
|
+
.gsub(/" *\\\n\s*'/, %q(" + ')) # Double quote, backslash, and then single quote
|
24
|
+
.gsub(/' *\\\n\s*"/, %q(' + ")) # Single quote, backslash, and then double quote
|
25
|
+
.gsub(/(["']) *\\\n\s*\1/, '') # Double or single quote, backslash, then same quote
|
26
|
+
.gsub(/\n\s*(?=(&)?\.\w)/, '') # Extra space within method chaining which includes `&.`
|
27
|
+
.gsub(/\s*\\?\n\s*/, ' ') # Any other line break, with or without backslash
|
28
|
+
end
|
29
|
+
|
30
|
+
def max_line_length
|
31
|
+
config.for_cop('Layout/LineLength')['Max']
|
32
|
+
end
|
33
|
+
|
34
|
+
def comment_within?(node)
|
35
|
+
comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
|
36
|
+
|
37
|
+
comment_line_numbers.any? do |comment_line_number|
|
38
|
+
comment_line_number >= node.first_line && comment_line_number <= node.last_line
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def safe_to_split?(node)
|
43
|
+
node.each_descendant(:if, :case, :kwbegin, :def, :defs).none? &&
|
44
|
+
node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
|
45
|
+
node.each_descendant(:begin, :sym).none? { |b| !b.single_line? }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Help methods for working with `Enumerable#dig` in cops.
|
6
|
+
# Used by `Style::DigChain` and `Style::SingleArgumentDig`
|
7
|
+
module DigHelp
|
8
|
+
extend NodePattern::Macros
|
9
|
+
|
10
|
+
# @!method dig?(node)
|
11
|
+
def_node_matcher :dig?, <<~PATTERN
|
12
|
+
(call _ :dig !{hash block_pass}+)
|
13
|
+
PATTERN
|
14
|
+
|
15
|
+
# @!method single_argument_dig?(node)
|
16
|
+
def_node_matcher :single_argument_dig?, <<~PATTERN
|
17
|
+
(send _ :dig $!splat)
|
18
|
+
PATTERN
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def dig_chain_enabled?
|
23
|
+
@config.for_cop('Style/DigChain')['Enabled']
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -121,12 +121,10 @@ module RuboCop
|
|
121
121
|
|
122
122
|
def indented_keyword_expression(node)
|
123
123
|
if node.for_type?
|
124
|
-
|
124
|
+
node.collection
|
125
125
|
else
|
126
|
-
|
126
|
+
node.children.first
|
127
127
|
end
|
128
|
-
|
129
|
-
expression
|
130
128
|
end
|
131
129
|
|
132
130
|
def argument_in_method_call(node, kind) # rubocop:todo Metrics/CyclomaticComplexity
|
@@ -187,12 +185,10 @@ module RuboCop
|
|
187
185
|
|
188
186
|
def assignment_rhs(node)
|
189
187
|
case node.type
|
190
|
-
when :casgn
|
191
|
-
when :
|
192
|
-
|
193
|
-
else _lhs, rhs = *node
|
188
|
+
when :casgn, :op_asgn then node.rhs
|
189
|
+
when :send, :csend then node.last_argument
|
190
|
+
else node.children.last
|
194
191
|
end
|
195
|
-
rhs
|
196
192
|
end
|
197
193
|
|
198
194
|
def not_for_this_cop?(node)
|
@@ -8,12 +8,28 @@ module RuboCop
|
|
8
8
|
@minimum_target_ruby_version
|
9
9
|
end
|
10
10
|
|
11
|
+
def required_maximum_ruby_version
|
12
|
+
@maximum_target_ruby_version
|
13
|
+
end
|
14
|
+
|
11
15
|
def minimum_target_ruby_version(version)
|
12
16
|
@minimum_target_ruby_version = version
|
13
17
|
end
|
14
18
|
|
19
|
+
def maximum_target_ruby_version(version)
|
20
|
+
@maximum_target_ruby_version = version
|
21
|
+
end
|
22
|
+
|
15
23
|
def support_target_ruby_version?(version)
|
16
|
-
|
24
|
+
# By default, no minimum or maximum versions of ruby are required
|
25
|
+
# to run any cop. In order to do a simple numerical comparison of
|
26
|
+
# the requested version against any requirements, we use 0 and
|
27
|
+
# Infinity as the default values to indicate no minimum (0) and no
|
28
|
+
# maximum (Infinity).
|
29
|
+
min = required_minimum_ruby_version || 0
|
30
|
+
max = required_maximum_ruby_version || Float::INFINITY
|
31
|
+
|
32
|
+
min <= version && max >= version
|
17
33
|
end
|
18
34
|
end
|
19
35
|
end
|
@@ -3,13 +3,13 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Naming
|
6
|
-
#
|
7
|
-
# to both instance and class methods.
|
6
|
+
# Avoid prefixing accessor method names with `get_` or `set_`.
|
7
|
+
# Applies to both instance and class methods.
|
8
8
|
#
|
9
|
-
# NOTE:
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# one.
|
9
|
+
# NOTE: Method names starting with `get_` or `set_` only register an offense
|
10
|
+
# when the methods match the expected arity for getters and setters respectively.
|
11
|
+
# Getters (`get_attribute`) must have no arguments to be registered,
|
12
|
+
# and setters (`set_attribute(value)`) must have exactly one.
|
13
13
|
#
|
14
14
|
# @example
|
15
15
|
# # bad
|
@@ -31,12 +31,11 @@ module RuboCop
|
|
31
31
|
PATTERN
|
32
32
|
|
33
33
|
def on_casgn(node)
|
34
|
-
if node.parent&.or_asgn_type?
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
34
|
+
value = if node.parent&.or_asgn_type?
|
35
|
+
node.parent.expression
|
36
|
+
else
|
37
|
+
node.expression
|
38
|
+
end
|
40
39
|
|
41
40
|
# We cannot know the result of method calls like
|
42
41
|
# NewClass = something_that_returns_a_class
|
@@ -46,7 +45,7 @@ module RuboCop
|
|
46
45
|
# SomeClass = Class.new(...)
|
47
46
|
# SomeClass = Struct.new(...)
|
48
47
|
return if allowed_assignment?(value)
|
49
|
-
return if SNAKE_CASE.match?(
|
48
|
+
return if SNAKE_CASE.match?(node.name)
|
50
49
|
|
51
50
|
add_offense(node.loc.name)
|
52
51
|
end
|
@@ -37,8 +37,6 @@ module RuboCop
|
|
37
37
|
#
|
38
38
|
# anything/using_snake_case.rake
|
39
39
|
class FileName < Base
|
40
|
-
include RangeHelp
|
41
|
-
|
42
40
|
MSG_SNAKE_CASE = 'The name of this source file (`%<basename>s`) should use snake_case.'
|
43
41
|
MSG_NO_DEFINITION = '`%<basename>s` should define a class or module called `%<namespace>s`.'
|
44
42
|
MSG_REGEX = '`%<basename>s` should match `%<regex>s`.'
|