rubocop 1.68.0 → 1.69.1
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 +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
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for the deprecated use of keyword arguments as a default in `Hash.new`.
|
7
|
+
#
|
8
|
+
# This usage raises a warning in Ruby 3.3 and results in an error in Ruby 3.4.
|
9
|
+
# In Ruby 3.4, keyword arguments will instead be used to change the behavior of a hash.
|
10
|
+
# For example, the capacity option can be passed to create a hash with a certain size
|
11
|
+
# if you know it in advance, for better performance.
|
12
|
+
#
|
13
|
+
# NOTE: The following corner case may result in a false negative when upgrading from Ruby 3.3
|
14
|
+
# or earlier, but it is intentionally not detected to respect the expected usage in Ruby 3.4.
|
15
|
+
#
|
16
|
+
# [source,ruby]
|
17
|
+
# ----
|
18
|
+
# Hash.new(capacity: 42)
|
19
|
+
# ----
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# Hash.new(key: :value)
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# Hash.new({key: :value})
|
28
|
+
#
|
29
|
+
class HashNewWithKeywordArgumentsAsDefault < Base
|
30
|
+
extend AutoCorrector
|
31
|
+
|
32
|
+
MSG = 'Use a hash literal instead of keyword arguments.'
|
33
|
+
RESTRICT_ON_SEND = %i[new].freeze
|
34
|
+
|
35
|
+
# @!method hash_new(node)
|
36
|
+
def_node_matcher :hash_new, <<~PATTERN
|
37
|
+
(send (const {nil? (cbase)} :Hash) :new $[hash !braces?])
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
def on_send(node)
|
41
|
+
return unless (first_argument = hash_new(node))
|
42
|
+
|
43
|
+
if first_argument.pairs.one?
|
44
|
+
key = first_argument.pairs.first.key
|
45
|
+
return if key.respond_to?(:value) && key.value == :capacity
|
46
|
+
end
|
47
|
+
|
48
|
+
add_offense(first_argument) do |corrector|
|
49
|
+
corrector.wrap(first_argument, '{', '}')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -24,14 +24,17 @@ module RuboCop
|
|
24
24
|
MSG = 'Interpolation in single quoted string detected. ' \
|
25
25
|
'Use double quoted strings if you need interpolation.'
|
26
26
|
|
27
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
27
28
|
def on_str(node)
|
28
29
|
return if node.parent&.regexp_type?
|
29
30
|
return unless /(?<!\\)#\{.*\}/.match?(node.source)
|
30
31
|
return if heredoc?(node)
|
31
32
|
return unless node.loc.begin && node.loc.end
|
33
|
+
return unless valid_syntax?(node)
|
32
34
|
|
33
35
|
add_offense(node) { |corrector| autocorrect(corrector, node) }
|
34
36
|
end
|
37
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
35
38
|
|
36
39
|
private
|
37
40
|
|
@@ -49,6 +52,12 @@ module RuboCop
|
|
49
52
|
def heredoc?(node)
|
50
53
|
node.loc.is_a?(Parser::Source::Map::Heredoc) || (node.parent && heredoc?(node.parent))
|
51
54
|
end
|
55
|
+
|
56
|
+
def valid_syntax?(node)
|
57
|
+
double_quoted_string = node.source.gsub(/\A'|'\z/, '"')
|
58
|
+
|
59
|
+
parse(double_quoted_string).valid_syntax?
|
60
|
+
end
|
52
61
|
end
|
53
62
|
end
|
54
63
|
end
|
@@ -26,6 +26,9 @@ module RuboCop
|
|
26
26
|
#
|
27
27
|
class ItWithoutArgumentsInBlock < Base
|
28
28
|
include NodePattern::Macros
|
29
|
+
extend TargetRubyVersion
|
30
|
+
|
31
|
+
maximum_target_ruby_version 3.3
|
29
32
|
|
30
33
|
MSG = '`it` calls without arguments will refer to the first block param in Ruby 3.4; ' \
|
31
34
|
'use `it()` or `self.it`.'
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
traverse_node(node.condition) do |asgn_node|
|
41
41
|
next unless asgn_node.loc.operator
|
42
42
|
|
43
|
-
rhs = asgn_node.
|
43
|
+
rhs = asgn_node.rhs
|
44
44
|
next if !all_literals?(rhs) || parallel_assignment_with_splat_operator?(rhs)
|
45
45
|
|
46
46
|
range = offense_range(asgn_node, rhs)
|
@@ -36,12 +36,9 @@ module RuboCop
|
|
36
36
|
|
37
37
|
def on_irange(node)
|
38
38
|
return unless node.children.compact.all?(&:str_type?)
|
39
|
+
return if node.begin.nil? || node.end.nil?
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
return if range_start.nil? || range_end.nil?
|
43
|
-
|
44
|
-
add_offense(node) if unsafe_range?(range_start.value, range_end.value)
|
41
|
+
add_offense(node) if unsafe_range?(node.begin.value, node.end.value)
|
45
42
|
end
|
46
43
|
alias on_erange on_irange
|
47
44
|
|
@@ -95,7 +95,7 @@ module RuboCop
|
|
95
95
|
MSG = 'Method definitions must not be nested. Use `lambda` instead.'
|
96
96
|
|
97
97
|
def on_def(node)
|
98
|
-
subject, = *node
|
98
|
+
subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
99
99
|
return if node.defs_type? && subject.variable?
|
100
100
|
|
101
101
|
def_ancestor = node.each_ancestor(:def, :defs).first
|
@@ -95,7 +95,7 @@ module RuboCop
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def allowable_use_with_if?(if_node)
|
98
|
-
if_node.condition.
|
98
|
+
if_node.condition.operator_keyword? || if_node.else_branch
|
99
99
|
end
|
100
100
|
|
101
101
|
def register_offense(node, exist_node)
|
@@ -59,11 +59,13 @@ module RuboCop
|
|
59
59
|
#
|
60
60
|
class NonDeterministicRequireOrder < Base
|
61
61
|
extend AutoCorrector
|
62
|
+
extend TargetRubyVersion
|
62
63
|
|
63
64
|
MSG = 'Sort files before requiring them.'
|
64
65
|
|
66
|
+
maximum_target_ruby_version 2.7
|
67
|
+
|
65
68
|
def on_block(node)
|
66
|
-
return if target_ruby_version >= 3.0
|
67
69
|
return unless node.body
|
68
70
|
return unless unsorted_dir_loop?(node.send_node)
|
69
71
|
|
@@ -75,7 +77,6 @@ module RuboCop
|
|
75
77
|
end
|
76
78
|
|
77
79
|
def on_numblock(node)
|
78
|
-
return if target_ruby_version >= 3.0
|
79
80
|
return unless node.body
|
80
81
|
return unless unsorted_dir_loop?(node.send_node)
|
81
82
|
|
@@ -87,7 +88,6 @@ module RuboCop
|
|
87
88
|
end
|
88
89
|
|
89
90
|
def on_block_pass(node)
|
90
|
-
return if target_ruby_version >= 3.0
|
91
91
|
return unless method_require?(node)
|
92
92
|
return unless unsorted_dir_pass?(node.parent)
|
93
93
|
|
@@ -33,8 +33,7 @@ module RuboCop
|
|
33
33
|
NUMBERED_PARAMETER_RANGE = (1..9).freeze
|
34
34
|
|
35
35
|
def on_lvasgn(node)
|
36
|
-
|
37
|
-
return unless /\A_(\d+)\z/ =~ lhs
|
36
|
+
return unless /\A_(\d+)\z/ =~ node.name
|
38
37
|
|
39
38
|
number = Regexp.last_match(1).to_i
|
40
39
|
template = NUMBERED_PARAMETER_RANGE.include?(number) ? NUM_PARAM_MSG : LVAR_MSG
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Certain numeric operations have a constant result, usually 0 or 1.
|
7
|
+
# Subtracting a number from itself or multiplying it by 0 will always return 0.
|
8
|
+
# Additionally, a variable modulo 0 or itself will always return 0.
|
9
|
+
# Dividing a number by itself or raising it to the power of 0 will always return 1.
|
10
|
+
# As such, they can be replaced with that result.
|
11
|
+
# These are probably leftover from debugging, or are mistakes.
|
12
|
+
# Other numeric operations that are similarly leftover from debugging or mistakes
|
13
|
+
# are handled by Lint/UselessNumericOperation.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# x - x
|
19
|
+
# x * 0
|
20
|
+
# x % 1
|
21
|
+
# x % x
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# 0
|
25
|
+
#
|
26
|
+
# # bad
|
27
|
+
# x -= x
|
28
|
+
# x *= 0
|
29
|
+
# x %= 1
|
30
|
+
# x %= x
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# x = 0
|
34
|
+
#
|
35
|
+
# # bad
|
36
|
+
# x / x
|
37
|
+
# x ** 0
|
38
|
+
#
|
39
|
+
# # good
|
40
|
+
# 1
|
41
|
+
#
|
42
|
+
# # bad
|
43
|
+
# x /= x
|
44
|
+
# x **= 0
|
45
|
+
#
|
46
|
+
# # good
|
47
|
+
# x = 1
|
48
|
+
#
|
49
|
+
class NumericOperationWithConstantResult < Base
|
50
|
+
extend AutoCorrector
|
51
|
+
MSG = 'Numeric operation with a constant result detected.'
|
52
|
+
RESTRICT_ON_SEND = %i[- * / % **].freeze
|
53
|
+
|
54
|
+
# @!method operation_with_constant_result?(node)
|
55
|
+
def_node_matcher :operation_with_constant_result?,
|
56
|
+
'(send (send nil? $_) $_ ({int | send nil?} $_))'
|
57
|
+
|
58
|
+
# @!method abbreviated_assignment_with_constant_result?(node)
|
59
|
+
def_node_matcher :abbreviated_assignment_with_constant_result?,
|
60
|
+
'(op-asgn (lvasgn $_) $_ ({int | lvar} $_))'
|
61
|
+
|
62
|
+
def on_send(node)
|
63
|
+
return unless operation_with_constant_result?(node)
|
64
|
+
|
65
|
+
variable, operation, number = operation_with_constant_result?(node)
|
66
|
+
result = constant_result?(variable, operation, number)
|
67
|
+
return unless result
|
68
|
+
|
69
|
+
add_offense(node) do |corrector|
|
70
|
+
corrector.replace(node, result.to_s)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def on_op_asgn(node)
|
75
|
+
return unless abbreviated_assignment_with_constant_result?(node)
|
76
|
+
|
77
|
+
variable, operation, number = abbreviated_assignment_with_constant_result?(node)
|
78
|
+
result = constant_result?(variable, operation, number)
|
79
|
+
return unless result
|
80
|
+
|
81
|
+
add_offense(node) do |corrector|
|
82
|
+
corrector.replace(node, "#{variable} = #{result}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# rubocop :disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
89
|
+
def constant_result?(variable, operation, number)
|
90
|
+
if number.to_s == '0'
|
91
|
+
return 0 if operation == :*
|
92
|
+
return 1 if operation == :**
|
93
|
+
elsif number.to_s == '1'
|
94
|
+
return 0 if operation == :%
|
95
|
+
elsif number == variable
|
96
|
+
return 0 if %i[- %].include?(operation)
|
97
|
+
return 1 if operation == :/
|
98
|
+
end
|
99
|
+
# If we weren't able to find any matches, return false so we can bail out.
|
100
|
+
false
|
101
|
+
end
|
102
|
+
# rubocop :enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -27,8 +27,7 @@ module RuboCop
|
|
27
27
|
MSG = 'Avoid using or-assignment with constants.'
|
28
28
|
|
29
29
|
def on_or_asgn(node)
|
30
|
-
|
31
|
-
return unless lhs&.casgn_type?
|
30
|
+
return unless node.lhs&.casgn_type?
|
32
31
|
|
33
32
|
add_offense(node.loc.operator) do |corrector|
|
34
33
|
next if node.each_ancestor(:def, :defs).any?
|
@@ -111,7 +111,7 @@ module RuboCop
|
|
111
111
|
range_between(start + begin_pos - 1, start + end_pos)
|
112
112
|
end
|
113
113
|
|
114
|
-
# If the list of cops is comma-separated, but without
|
114
|
+
# If the list of cops is comma-separated, but without an empty space after the comma,
|
115
115
|
# we should **not** remove the prepending empty space, thus begin_pos += 1
|
116
116
|
def range_with_comma_after(comment, start, begin_pos, end_pos)
|
117
117
|
begin_pos += 1 if comment.source[end_pos + 1] != ' '
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Checks for redundant safe navigation calls.
|
7
7
|
# Use cases where a constant, named in camel case for classes and modules is `nil` are rare,
|
8
8
|
# and an offense is not detected when the receiver is a constant. The detection also applies
|
9
|
-
# to literal receivers, except for `nil`.
|
9
|
+
# to `self`, and to literal receivers, except for `nil`.
|
10
10
|
#
|
11
11
|
# For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`,
|
12
12
|
# and `equal?` methods are checked by default.
|
@@ -29,6 +29,9 @@ module RuboCop
|
|
29
29
|
# # bad
|
30
30
|
# CamelCaseConst&.do_something
|
31
31
|
#
|
32
|
+
# # good
|
33
|
+
# CamelCaseConst.do_something
|
34
|
+
#
|
32
35
|
# # bad
|
33
36
|
# do_something if attrs&.respond_to?(:[])
|
34
37
|
#
|
@@ -41,9 +44,6 @@ module RuboCop
|
|
41
44
|
# end
|
42
45
|
#
|
43
46
|
# # good
|
44
|
-
# CamelCaseConst.do_something
|
45
|
-
#
|
46
|
-
# # good
|
47
47
|
# while node.is_a?(BeginNode)
|
48
48
|
# node = node.parent
|
49
49
|
# end
|
@@ -67,6 +67,12 @@ module RuboCop
|
|
67
67
|
# foo.to_f
|
68
68
|
# foo.to_s
|
69
69
|
#
|
70
|
+
# # bad
|
71
|
+
# self&.foo
|
72
|
+
#
|
73
|
+
# # good
|
74
|
+
# self.foo
|
75
|
+
#
|
70
76
|
# @example AllowedMethods: [nil_safe_method]
|
71
77
|
# # bad
|
72
78
|
# do_something if attrs&.nil_safe_method(:[])
|
@@ -133,7 +139,7 @@ module RuboCop
|
|
133
139
|
def assume_receiver_instance_exists?(receiver)
|
134
140
|
return true if receiver.const_type? && !receiver.short_name.match?(SNAKE_CASE)
|
135
141
|
|
136
|
-
receiver.literal? && !receiver.nil_type?
|
142
|
+
receiver.self_type? || (receiver.literal? && !receiver.nil_type?)
|
137
143
|
end
|
138
144
|
|
139
145
|
def check?(node)
|
@@ -141,8 +147,7 @@ module RuboCop
|
|
141
147
|
return false unless parent
|
142
148
|
|
143
149
|
condition?(parent, node) ||
|
144
|
-
parent.
|
145
|
-
parent.or_type? ||
|
150
|
+
parent.operator_keyword? ||
|
146
151
|
(parent.send_type? && parent.negation_method?)
|
147
152
|
end
|
148
153
|
|
@@ -135,10 +135,10 @@ module RuboCop
|
|
135
135
|
grandparent.array_type? && grandparent.children.size > 1
|
136
136
|
end
|
137
137
|
|
138
|
+
# rubocop:disable Metrics/AbcSize
|
138
139
|
def replacement_range_and_content(node)
|
139
|
-
variable
|
140
|
-
|
141
|
-
expression = loc.expression
|
140
|
+
variable = node.children.first
|
141
|
+
expression = node.source_range
|
142
142
|
|
143
143
|
if array_new?(variable)
|
144
144
|
expression = node.parent.source_range if node.parent.array_type?
|
@@ -148,16 +148,17 @@ module RuboCop
|
|
148
148
|
elsif redundant_brackets?(node)
|
149
149
|
[expression, remove_brackets(variable)]
|
150
150
|
else
|
151
|
-
[loc.operator, '']
|
151
|
+
[node.loc.operator, '']
|
152
152
|
end
|
153
153
|
end
|
154
|
+
# rubocop:enable Metrics/AbcSize
|
154
155
|
|
155
156
|
def array_splat?(node)
|
156
157
|
node.children.first.array_type?
|
157
158
|
end
|
158
159
|
|
159
160
|
def method_argument?(node)
|
160
|
-
node.parent.
|
161
|
+
node.parent.call_type?
|
161
162
|
end
|
162
163
|
|
163
164
|
def part_of_an_array?(node)
|
@@ -171,7 +172,7 @@ module RuboCop
|
|
171
172
|
parent = node.parent
|
172
173
|
grandparent = node.parent.parent
|
173
174
|
|
174
|
-
parent.when_type? ||
|
175
|
+
parent.when_type? || method_argument?(node) || part_of_an_array?(node) ||
|
175
176
|
grandparent&.resbody_type?
|
176
177
|
end
|
177
178
|
|
@@ -196,7 +197,7 @@ module RuboCop
|
|
196
197
|
def use_percent_literal_array_argument?(node)
|
197
198
|
argument = node.children.first
|
198
199
|
|
199
|
-
node
|
200
|
+
method_argument?(node) &&
|
200
201
|
(argument.percent_literal?(:string) || argument.percent_literal?(:symbol))
|
201
202
|
end
|
202
203
|
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Checks if `include` or `prepend` is called in `refine` block.
|
7
7
|
# These methods are deprecated and should be replaced with `Refinement#import_methods`.
|
8
8
|
#
|
9
|
-
# It emulates deprecation warnings in Ruby 3.1.
|
9
|
+
# It emulates deprecation warnings in Ruby 3.1. Functionality has been removed in Ruby 3.2.
|
10
10
|
#
|
11
11
|
# @safety
|
12
12
|
# This cop's autocorrection is unsafe because `include M` will affect the included class
|
@@ -42,15 +42,11 @@ module RuboCop
|
|
42
42
|
INVALID_TYPES = %i[array dstr float hash nil int str sym].freeze
|
43
43
|
|
44
44
|
def on_resbody(node)
|
45
|
-
|
46
|
-
return if rescued.nil?
|
47
|
-
|
48
|
-
exceptions = *rescued
|
49
|
-
invalid_exceptions = invalid_exceptions(exceptions)
|
45
|
+
invalid_exceptions = invalid_exceptions(node.exceptions)
|
50
46
|
return if invalid_exceptions.empty?
|
51
47
|
|
52
48
|
add_offense(
|
53
|
-
node.loc.keyword.join(
|
49
|
+
node.loc.keyword.join(node.children.first.source_range),
|
54
50
|
message: format(MSG, invalid_exceptions: invalid_exceptions.map(&:source).join(', '))
|
55
51
|
) do |corrector|
|
56
52
|
autocorrect(corrector, node)
|
@@ -58,7 +54,7 @@ module RuboCop
|
|
58
54
|
end
|
59
55
|
|
60
56
|
def autocorrect(corrector, node)
|
61
|
-
rescued
|
57
|
+
rescued = node.children.first
|
62
58
|
range = node.loc.keyword.end.join(rescued.source_range.end)
|
63
59
|
|
64
60
|
corrector.replace(range, correction(*rescued))
|
@@ -83,6 +83,8 @@ module RuboCop
|
|
83
83
|
def find_consistent_parts(grouped_operands)
|
84
84
|
csend_in_and, csend_in_or, send_in_and, send_in_or = most_left_indices(grouped_operands)
|
85
85
|
|
86
|
+
return if csend_in_and && csend_in_or && csend_in_and < csend_in_or
|
87
|
+
|
86
88
|
if csend_in_and
|
87
89
|
['.', (send_in_and ? [send_in_and, csend_in_and].min : csend_in_and) + 1]
|
88
90
|
elsif send_in_or && csend_in_or
|
@@ -43,23 +43,21 @@ module RuboCop
|
|
43
43
|
alias on_csend on_send
|
44
44
|
|
45
45
|
def on_lvasgn(node)
|
46
|
-
|
47
|
-
return unless rhs
|
46
|
+
return unless node.rhs
|
48
47
|
|
49
48
|
rhs_type = ASSIGNMENT_TYPE_TO_RHS_TYPE[node.type]
|
50
49
|
|
51
|
-
add_offense(node) if rhs.type == rhs_type && rhs.source == lhs.to_s
|
50
|
+
add_offense(node) if node.rhs.type == rhs_type && node.rhs.source == node.lhs.to_s
|
52
51
|
end
|
53
52
|
alias on_ivasgn on_lvasgn
|
54
53
|
alias on_cvasgn on_lvasgn
|
55
54
|
alias on_gvasgn on_lvasgn
|
56
55
|
|
57
56
|
def on_casgn(node)
|
58
|
-
|
59
|
-
return unless rhs&.const_type?
|
57
|
+
return unless node.rhs&.const_type?
|
60
58
|
|
61
|
-
|
62
|
-
|
59
|
+
add_offense(node) if node.namespace == node.rhs.namespace &&
|
60
|
+
node.short_name == node.rhs.short_name
|
63
61
|
end
|
64
62
|
|
65
63
|
def on_masgn(node)
|
@@ -67,15 +65,15 @@ module RuboCop
|
|
67
65
|
end
|
68
66
|
|
69
67
|
def on_or_asgn(node)
|
70
|
-
|
71
|
-
add_offense(node) if rhs_matches_lhs?(rhs, lhs)
|
68
|
+
add_offense(node) if rhs_matches_lhs?(node.rhs, node.lhs)
|
72
69
|
end
|
73
70
|
alias on_and_asgn on_or_asgn
|
74
71
|
|
75
72
|
private
|
76
73
|
|
77
74
|
def multiple_self_assignment?(node)
|
78
|
-
lhs
|
75
|
+
lhs = node.lhs
|
76
|
+
rhs = node.rhs
|
79
77
|
return false unless rhs.array_type?
|
80
78
|
return false unless lhs.children.size == rhs.children.size
|
81
79
|
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
67
67
|
def on_rescue(node)
|
68
68
|
return if rescue_modifier?(node)
|
69
69
|
|
70
|
-
|
70
|
+
rescues = node.resbody_branches
|
71
71
|
rescued_groups = rescued_groups_for(rescues)
|
72
72
|
|
73
73
|
rescue_group_rescues_multiple_levels = rescued_groups.any? do |group|
|
@@ -58,6 +58,9 @@ module RuboCop
|
|
58
58
|
Regexp::Parser.parse(text.value)&.each_expression do |expr|
|
59
59
|
detect_offenses(text, expr)
|
60
60
|
end
|
61
|
+
rescue Regexp::Parser::ParserError
|
62
|
+
# Upon encountering an invalid regular expression,
|
63
|
+
# we aim to proceed and identify any remaining potential offenses.
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|