rubocop 1.19.0 → 1.23.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +129 -21
- data/lib/rubocop/config.rb +5 -0
- data/lib/rubocop/config_loader.rb +5 -3
- data/lib/rubocop/config_validator.rb +9 -1
- data/lib/rubocop/cop/base.rb +3 -3
- data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
- data/lib/rubocop/cop/bundler/gem_filename.rb +103 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +45 -21
- data/lib/rubocop/cop/bundler/ordered_gems.rb +3 -12
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +11 -10
- data/lib/rubocop/cop/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/date_assignment.rb +2 -10
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -10
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +3 -12
- data/lib/rubocop/cop/gemspec/require_mfa.rb +146 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +31 -24
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -10
- data/lib/rubocop/cop/generator.rb +14 -8
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +60 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/assignment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
- data/lib/rubocop/cop/layout/class_structure.rb +2 -1
- data/lib/rubocop/cop/layout/dot_position.rb +34 -5
- data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +22 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +7 -4
- data/lib/rubocop/cop/layout/end_alignment.rb +2 -3
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +9 -7
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -3
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +3 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -0
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -5
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +15 -4
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
- data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_comment.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +11 -5
- data/lib/rubocop/cop/layout/space_inside_parens.rb +74 -28
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +111 -0
- data/lib/rubocop/cop/lint/ambiguous_range.rb +11 -11
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +7 -5
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +18 -5
- data/lib/rubocop/cop/lint/boolean_symbol.rb +5 -0
- data/lib/rubocop/cop/lint/debugger.rb +2 -4
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/deprecated_constants.rb +3 -2
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +24 -1
- data/lib/rubocop/cop/lint/else_layout.rb +10 -6
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +12 -3
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +67 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +5 -0
- data/lib/rubocop/cop/lint/loop.rb +4 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +5 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +16 -2
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +4 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +10 -0
- data/lib/rubocop/cop/lint/raise_exception.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +5 -4
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +50 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/triple_quotes.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +8 -3
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -3
- data/lib/rubocop/cop/lint/useless_method_definition.rb +3 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +117 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/lint/useless_times.rb +4 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +6 -0
- data/lib/rubocop/cop/metrics/parameter_lists.rb +5 -2
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +57 -34
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +5 -2
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +23 -1
- data/lib/rubocop/cop/mixin/gemspec_help.rb +30 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
- data/lib/rubocop/cop/mixin/heredoc.rb +1 -3
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -2
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +9 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +11 -3
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +9 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_body.rb +1 -1
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +0 -3
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +37 -4
- data/lib/rubocop/cop/naming/inclusive_language.rb +9 -9
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +5 -4
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +7 -0
- data/lib/rubocop/cop/security/io_methods.rb +49 -0
- data/lib/rubocop/cop/security/json_load.rb +8 -7
- data/lib/rubocop/cop/security/open.rb +4 -0
- data/lib/rubocop/cop/security/yaml_load.rb +4 -0
- data/lib/rubocop/cop/style/accessor_grouping.rb +2 -2
- data/lib/rubocop/cop/style/and_or.rb +5 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +13 -2
- data/lib/rubocop/cop/style/array_coercion.rb +21 -3
- data/lib/rubocop/cop/style/ascii_comments.rb +0 -3
- data/lib/rubocop/cop/style/block_delimiters.rb +23 -6
- data/lib/rubocop/cop/style/case_equality.rb +6 -9
- data/lib/rubocop/cop/style/case_like_if.rb +5 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +9 -0
- data/lib/rubocop/cop/style/collection_compact.rb +7 -5
- data/lib/rubocop/cop/style/collection_methods.rb +8 -6
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/comment_annotation.rb +25 -39
- data/lib/rubocop/cop/style/commented_keyword.rb +9 -4
- data/lib/rubocop/cop/style/date_time.rb +5 -0
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +23 -8
- data/lib/rubocop/cop/style/double_negation.rb +27 -6
- data/lib/rubocop/cop/style/empty_method.rb +2 -2
- data/lib/rubocop/cop/style/encoding.rb +26 -15
- data/lib/rubocop/cop/style/explicit_block_argument.rb +21 -11
- data/lib/rubocop/cop/style/float_division.rb +10 -2
- data/lib/rubocop/cop/style/format_string_token.rb +2 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +7 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +4 -0
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +11 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +5 -0
- data/lib/rubocop/cop/style/hash_except.rb +4 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -6
- data/lib/rubocop/cop/style/hash_transform_values.rb +4 -6
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -16
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +18 -4
- data/lib/rubocop/cop/style/infinite_loop.rb +4 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +9 -2
- data/lib/rubocop/cop/style/lambda_call.rb +1 -1
- data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +6 -6
- data/lib/rubocop/cop/style/module_function.rb +8 -9
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +73 -6
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_unless.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +2 -2
- data/lib/rubocop/cop/style/not.rb +2 -2
- data/lib/rubocop/cop/style/numbered_parameters.rb +46 -0
- data/lib/rubocop/cop/style/numbered_parameters_limit.rb +50 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
- data/lib/rubocop/cop/style/numeric_predicate.rb +5 -0
- data/lib/rubocop/cop/style/open_struct_use.rb +69 -0
- data/lib/rubocop/cop/style/optional_arguments.rb +4 -0
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +14 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -2
- data/lib/rubocop/cop/style/percent_q_literals.rb +2 -2
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -4
- data/lib/rubocop/cop/style/quoted_symbols.rb +21 -7
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +19 -9
- data/lib/rubocop/cop/style/redundant_begin.rb +25 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +4 -0
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +12 -3
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -3
- data/lib/rubocop/cop/style/redundant_self.rb +10 -0
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +4 -3
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +23 -28
- data/lib/rubocop/cop/style/redundant_sort.rb +51 -18
- data/lib/rubocop/cop/style/regexp_literal.rb +3 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +139 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +5 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +13 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +4 -0
- data/lib/rubocop/cop/style/static_class.rb +5 -5
- data/lib/rubocop/cop/style/string_chars.rb +4 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +5 -1
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +4 -0
- data/lib/rubocop/cop/style/swap_values.rb +4 -2
- data/lib/rubocop/cop/style/symbol_array.rb +3 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +26 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +19 -0
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +3 -3
- data/lib/rubocop/cop/style/yoda_condition.rb +24 -7
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -0
- data/lib/rubocop/cop/util.rb +15 -4
- data/lib/rubocop/cops_documentation_generator.rb +17 -5
- data/lib/rubocop/formatter/html_formatter.rb +5 -2
- data/lib/rubocop/formatter/json_formatter.rb +4 -1
- data/lib/rubocop/magic_comment.rb +44 -15
- data/lib/rubocop/options.rb +126 -112
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +1 -1
- data/lib/rubocop/result_cache.rb +3 -3
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/rspec/parallel_formatter.rb +90 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/runner.rb +2 -3
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +1 -1
- data/lib/rubocop.rb +14 -2
- metadata +20 -5
@@ -33,6 +33,27 @@ module RuboCop
|
|
33
33
|
# g = ( a + 3 )
|
34
34
|
# y()
|
35
35
|
#
|
36
|
+
# @example EnforcedStyle: compact
|
37
|
+
# # The `compact` style enforces that parentheses have a space at the
|
38
|
+
# # beginning with the exception that successive parentheses are allowed.
|
39
|
+
# # Note: Empty parentheses should not have spaces.
|
40
|
+
#
|
41
|
+
# # bad
|
42
|
+
# f(3)
|
43
|
+
# g = (a + 3)
|
44
|
+
# y( )
|
45
|
+
# g( f( x ) )
|
46
|
+
# g( f( x( 3 ) ), 5 )
|
47
|
+
# g( ( ( 3 + 5 ) * f) ** x, 5 )
|
48
|
+
#
|
49
|
+
# # good
|
50
|
+
# f( 3 )
|
51
|
+
# g = ( a + 3 )
|
52
|
+
# y()
|
53
|
+
# g( f( x ))
|
54
|
+
# g( f( x( 3 )), 5 )
|
55
|
+
# g((( 3 + 5 ) * f ) ** x, 5 )
|
56
|
+
#
|
36
57
|
class SpaceInsideParens < Base
|
37
58
|
include SurroundingSpace
|
38
59
|
include RangeHelp
|
@@ -45,14 +66,13 @@ module RuboCop
|
|
45
66
|
def on_new_investigation
|
46
67
|
tokens = processed_source.sorted_tokens
|
47
68
|
|
48
|
-
|
69
|
+
case style
|
70
|
+
when :space
|
49
71
|
process_with_space_style(tokens)
|
72
|
+
when :compact
|
73
|
+
process_with_compact_style(tokens)
|
50
74
|
else
|
51
|
-
|
52
|
-
add_offense(range) do |corrector|
|
53
|
-
corrector.remove(range)
|
54
|
-
end
|
55
|
-
end
|
75
|
+
correct_extraneous_space(tokens)
|
56
76
|
end
|
57
77
|
end
|
58
78
|
|
@@ -60,20 +80,23 @@ module RuboCop
|
|
60
80
|
|
61
81
|
def process_with_space_style(tokens)
|
62
82
|
tokens.each_cons(2) do |token1, token2|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
83
|
+
correct_extraneous_space_in_empty_parens(token1, token2)
|
84
|
+
correct_missing_space(token1, token2)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def process_with_compact_style(tokens)
|
89
|
+
tokens.each_cons(2) do |token1, token2|
|
90
|
+
correct_extraneous_space_in_empty_parens(token1, token2)
|
91
|
+
if !left_parens?(token1, token2) && !right_parens?(token1, token2)
|
92
|
+
correct_missing_space(token1, token2)
|
93
|
+
else
|
94
|
+
correct_extaneus_space_between_consecutive_parens(token1, token2)
|
72
95
|
end
|
73
96
|
end
|
74
97
|
end
|
75
98
|
|
76
|
-
def
|
99
|
+
def correct_extraneous_space(tokens)
|
77
100
|
tokens.each_cons(2) do |token1, token2|
|
78
101
|
next unless parens?(token1, token2)
|
79
102
|
|
@@ -82,36 +105,59 @@ module RuboCop
|
|
82
105
|
next if token2.comment?
|
83
106
|
next unless same_line?(token1, token2) && token1.space_after?
|
84
107
|
|
85
|
-
|
108
|
+
range = range_between(token1.end_pos, token2.begin_pos)
|
109
|
+
add_offense(range) do |corrector|
|
110
|
+
corrector.remove(range)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def correct_extaneus_space_between_consecutive_parens(token1, token2)
|
116
|
+
return if range_between(token1.end_pos, token2.begin_pos).source != ' '
|
117
|
+
|
118
|
+
range = range_between(token1.end_pos, token2.begin_pos)
|
119
|
+
add_offense(range) do |corrector|
|
120
|
+
corrector.remove(range)
|
86
121
|
end
|
87
122
|
end
|
88
123
|
|
89
|
-
def
|
124
|
+
def correct_extraneous_space_in_empty_parens(token1, token2)
|
90
125
|
return unless token1.left_parens? && token2.right_parens?
|
91
126
|
|
92
127
|
return if range_between(token1.begin_pos, token2.end_pos).source == '()'
|
93
128
|
|
94
|
-
|
129
|
+
range = range_between(token1.end_pos, token2.begin_pos)
|
130
|
+
add_offense(range) do |corrector|
|
131
|
+
corrector.remove(range)
|
132
|
+
end
|
95
133
|
end
|
96
134
|
|
97
|
-
def
|
135
|
+
def correct_missing_space(token1, token2)
|
98
136
|
return if can_be_ignored?(token1, token2)
|
99
137
|
|
100
|
-
if token1.left_parens?
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
end
|
138
|
+
range = if token1.left_parens?
|
139
|
+
range_between(token2.begin_pos, token2.begin_pos + 1)
|
140
|
+
elsif token2.right_parens?
|
141
|
+
range_between(token2.begin_pos, token2.end_pos)
|
142
|
+
end
|
106
143
|
|
107
|
-
|
108
|
-
|
144
|
+
add_offense(range, message: MSG_SPACE) do |corrector|
|
145
|
+
corrector.insert_before(range, ' ')
|
146
|
+
end
|
109
147
|
end
|
110
148
|
|
111
149
|
def parens?(token1, token2)
|
112
150
|
token1.left_parens? || token2.right_parens?
|
113
151
|
end
|
114
152
|
|
153
|
+
def left_parens?(token1, token2)
|
154
|
+
token1.left_parens? && token2.left_parens?
|
155
|
+
end
|
156
|
+
|
157
|
+
def right_parens?(token1, token2)
|
158
|
+
token1.right_parens? && token2.right_parens?
|
159
|
+
end
|
160
|
+
|
115
161
|
def can_be_ignored?(token1, token2)
|
116
162
|
return true unless parens?(token1, token2)
|
117
163
|
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
107
107
|
current_token = tokens.reverse.find(&:left_ref_bracket?)
|
108
108
|
previous_token = previous_token(current_token)
|
109
109
|
|
110
|
-
if node.method?(:[]=) || previous_token && !previous_token.right_bracket?
|
110
|
+
if node.method?(:[]=) || (previous_token && !previous_token.right_bracket?)
|
111
111
|
tokens.find(&:left_ref_bracket?)
|
112
112
|
else
|
113
113
|
current_token
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop looks for expressions containing multiple binary operators
|
7
|
+
# where precedence is ambiguous due to lack of parentheses. For example,
|
8
|
+
# in `1 + 2 * 3`, the multiplication will happen before the addition, but
|
9
|
+
# lexically it appears that the addition will happen first.
|
10
|
+
#
|
11
|
+
# The cop does not consider unary operators (ie. `!a` or `-b`) or comparison
|
12
|
+
# operators (ie. `a =~ b`) because those are not ambiguous.
|
13
|
+
#
|
14
|
+
# NOTE: Ranges are handled by `Lint/AmbiguousRange`.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# # bad
|
18
|
+
# a + b * c
|
19
|
+
# a || b && c
|
20
|
+
# a ** b + c
|
21
|
+
#
|
22
|
+
# # good (different precedence)
|
23
|
+
# a + (b * c)
|
24
|
+
# a || (b && c)
|
25
|
+
# (a ** b) + c
|
26
|
+
#
|
27
|
+
# # good (same precedence)
|
28
|
+
# a + b + c
|
29
|
+
# a * b / c % d
|
30
|
+
class AmbiguousOperatorPrecedence < Base
|
31
|
+
extend AutoCorrector
|
32
|
+
|
33
|
+
# See https://ruby-doc.org/core-3.0.2/doc/syntax/precedence_rdoc.html
|
34
|
+
PRECEDENCE = [
|
35
|
+
%i[**],
|
36
|
+
%i[* / %],
|
37
|
+
%i[+ -],
|
38
|
+
%i[<< >>],
|
39
|
+
%i[&],
|
40
|
+
%i[| ^],
|
41
|
+
%i[&&],
|
42
|
+
%i[||]
|
43
|
+
].freeze
|
44
|
+
RESTRICT_ON_SEND = PRECEDENCE.flatten.freeze
|
45
|
+
MSG = 'Wrap expressions with varying precedence with parentheses to avoid ambiguity.'
|
46
|
+
|
47
|
+
def on_new_investigation
|
48
|
+
# Cache the precedence of each node being investigated
|
49
|
+
# so that we only need to calculate it once
|
50
|
+
@node_precedences = {}
|
51
|
+
super
|
52
|
+
end
|
53
|
+
|
54
|
+
def on_and(node)
|
55
|
+
return unless (parent = node.parent)
|
56
|
+
|
57
|
+
return if parent.begin_type? # if the `and` is in a `begin`, it's parenthesized already
|
58
|
+
return unless parent.or_type?
|
59
|
+
|
60
|
+
add_offense(node) do |corrector|
|
61
|
+
autocorrect(corrector, node)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def on_send(node)
|
66
|
+
return if node.parenthesized?
|
67
|
+
|
68
|
+
return unless (parent = node.parent)
|
69
|
+
return unless operator?(parent)
|
70
|
+
return unless greater_precedence?(node, parent)
|
71
|
+
|
72
|
+
add_offense(node) do |corrector|
|
73
|
+
autocorrect(corrector, node)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def precedence(node)
|
80
|
+
@node_precedences.fetch(node) do
|
81
|
+
PRECEDENCE.index { |operators| operators.include?(operator_name(node)) }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def operator?(node)
|
86
|
+
(node.send_type? && RESTRICT_ON_SEND.include?(node.method_name)) || node.operator_keyword?
|
87
|
+
end
|
88
|
+
|
89
|
+
def greater_precedence?(node1, node2)
|
90
|
+
node1_precedence = precedence(node1)
|
91
|
+
node2_precedence = precedence(node2)
|
92
|
+
return false unless node1_precedence && node2_precedence
|
93
|
+
|
94
|
+
node2_precedence > node1_precedence
|
95
|
+
end
|
96
|
+
|
97
|
+
def operator_name(node)
|
98
|
+
if node.send_type?
|
99
|
+
node.method_name
|
100
|
+
else
|
101
|
+
node.operator.to_sym
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def autocorrect(corrector, node)
|
106
|
+
corrector.wrap(node, '(', ')')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -8,13 +8,7 @@ module RuboCop
|
|
8
8
|
# Ranges have quite low precedence, which leads to unexpected behaviour when
|
9
9
|
# using a range with other operators. This cop avoids that by making ranges
|
10
10
|
# explicit by requiring parenthesis around complex range boundaries (anything
|
11
|
-
# that is not a
|
12
|
-
#
|
13
|
-
# NOTE: The cop auto-corrects by wrapping the entire boundary in parentheses, which
|
14
|
-
# makes the outcome more explicit but is possible to not be the intention of the
|
15
|
-
# programmer. For this reason, this cop's auto-correct is marked as unsafe (it
|
16
|
-
# will not change the behaviour of the code, but will not necessarily match the
|
17
|
-
# intent of the program).
|
11
|
+
# that is not a literal: numerics, strings, symbols, etc.).
|
18
12
|
#
|
19
13
|
# This cop can be configured with `RequireParenthesesForMethodChains` in order to
|
20
14
|
# specify whether method chains (including `self.foo`) should be wrapped in parens
|
@@ -23,6 +17,13 @@ module RuboCop
|
|
23
17
|
# NOTE: Regardless of this configuration, if a method receiver is a basic literal
|
24
18
|
# value, it will be wrapped in order to prevent the ambiguity of `1..2.to_a`.
|
25
19
|
#
|
20
|
+
# @safety
|
21
|
+
# The cop auto-corrects by wrapping the entire boundary in parentheses, which
|
22
|
+
# makes the outcome more explicit but is possible to not be the intention of the
|
23
|
+
# programmer. For this reason, this cop's auto-correct is unsafe (it will not
|
24
|
+
# change the behaviour of the code, but will not necessarily match the
|
25
|
+
# intent of the program).
|
26
|
+
#
|
26
27
|
# @example
|
27
28
|
# # bad
|
28
29
|
# x || 1..2
|
@@ -55,7 +56,6 @@ module RuboCop
|
|
55
56
|
#
|
56
57
|
# # good
|
57
58
|
# (a.foo)..(b.bar)
|
58
|
-
#
|
59
59
|
class AmbiguousRange < Base
|
60
60
|
extend AutoCorrector
|
61
61
|
|
@@ -81,9 +81,9 @@ module RuboCop
|
|
81
81
|
|
82
82
|
def acceptable?(node)
|
83
83
|
node.begin_type? ||
|
84
|
-
node.
|
85
|
-
node.variable? || node.const_type? ||
|
86
|
-
node.call_type? && acceptable_call?(node)
|
84
|
+
node.literal? ||
|
85
|
+
node.variable? || node.const_type? || node.self_type? ||
|
86
|
+
(node.call_type? && acceptable_call?(node))
|
87
87
|
end
|
88
88
|
|
89
89
|
def acceptable_call?(node)
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
def on_if(node)
|
50
50
|
return if node.condition.block_type?
|
51
51
|
|
52
|
-
traverse_node(node.condition
|
52
|
+
traverse_node(node.condition) do |asgn_node|
|
53
53
|
next :skip_children if skip_children?(asgn_node)
|
54
54
|
next if allowed_construct?(asgn_node)
|
55
55
|
|
@@ -83,13 +83,15 @@ module RuboCop
|
|
83
83
|
(safe_assignment_allowed? && safe_assignment?(asgn_node))
|
84
84
|
end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
def traverse_node(node, &block)
|
87
|
+
# if the node is a block, any assignments are irrelevant
|
88
|
+
return if node.block_type?
|
89
|
+
|
90
|
+
result = yield node if ASGN_TYPES.include?(node.type)
|
89
91
|
|
90
92
|
return if result == :skip_children
|
91
93
|
|
92
|
-
node.each_child_node { |child| traverse_node(child,
|
94
|
+
node.each_child_node { |child| traverse_node(child, &block) }
|
93
95
|
end
|
94
96
|
end
|
95
97
|
end
|
@@ -5,15 +5,28 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# This cop checks for places where binary operator has identical operands.
|
7
7
|
#
|
8
|
-
# It covers arithmetic operators:
|
8
|
+
# It covers arithmetic operators: `-`, `/`, `%`;
|
9
9
|
# comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, `<=`;
|
10
|
-
# bitwise operators: `|`, `^`,
|
10
|
+
# bitwise operators: `|`, `^`, `&`;
|
11
11
|
# boolean operators: `&&`, `||`
|
12
12
|
# and "spaceship" operator - `<=>`.
|
13
13
|
#
|
14
|
-
#
|
15
|
-
#
|
14
|
+
# Simple arithmetic operations are allowed by this cop: `+`, `*`, `**`, `<<` and `>>`.
|
15
|
+
# Although these can be rewritten in a different way, it should not be necessary to
|
16
|
+
# do so. This does not include operations such as `-` or `/` where the result will
|
17
|
+
# always be the same (`x - x` will always be 0; `x / x` will always be 1), and
|
18
|
+
# thus are legitimate offenses.
|
19
|
+
#
|
20
|
+
# @safety
|
21
|
+
# This cop is unsafe as it does not consider side effects when calling methods
|
22
|
+
# and thus can generate false positives, for example:
|
23
|
+
#
|
24
|
+
# [source,ruby]
|
25
|
+
# ----
|
16
26
|
# if wr.take_char == '\0' && wr.take_char == '\0'
|
27
|
+
# # ...
|
28
|
+
# end
|
29
|
+
# ----
|
17
30
|
#
|
18
31
|
# @example
|
19
32
|
# # bad
|
@@ -24,7 +37,7 @@ module RuboCop
|
|
24
37
|
# do_something
|
25
38
|
# end
|
26
39
|
#
|
27
|
-
# def
|
40
|
+
# def child?
|
28
41
|
# left_child || left_child
|
29
42
|
# end
|
30
43
|
#
|
@@ -6,6 +6,11 @@ module RuboCop
|
|
6
6
|
# This cop checks for `:true` and `:false` symbols.
|
7
7
|
# In most cases it would be a typo.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# Autocorrection is unsafe for this cop because code relying
|
11
|
+
# on `:true` or `:false` symbols will break when those are
|
12
|
+
# changed to actual booleans.
|
13
|
+
#
|
9
14
|
# @example
|
10
15
|
#
|
11
16
|
# # bad
|
@@ -7,8 +7,8 @@ module RuboCop
|
|
7
7
|
# not be kept for production code.
|
8
8
|
#
|
9
9
|
# The cop can be configured using `DebuggerMethods`. By default, a number of gems
|
10
|
-
# debug entrypoints are configured (`Kernel`, `Byebug`, `Capybara`, `
|
11
|
-
# and `WebConsole`). Additional methods can be added.
|
10
|
+
# debug entrypoints are configured (`Kernel`, `Byebug`, `Capybara`, `debug.rb`,
|
11
|
+
# `Pry`, `Rails`, `RubyJard`, and `WebConsole`). Additional methods can be added.
|
12
12
|
#
|
13
13
|
# Specific default groups can be disabled if necessary:
|
14
14
|
#
|
@@ -57,8 +57,6 @@ module RuboCop
|
|
57
57
|
class Debugger < Base
|
58
58
|
MSG = 'Remove debugger entry point `%<source>s`.'
|
59
59
|
|
60
|
-
RESTRICT_ON_SEND = [].freeze
|
61
|
-
|
62
60
|
# @!method kernel?(node)
|
63
61
|
def_node_matcher :kernel?, <<~PATTERN
|
64
62
|
(const {nil? cbase} :Kernel)
|
@@ -58,12 +58,12 @@ module RuboCop
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def to_s
|
61
|
-
[class_constant, method].compact.join(
|
61
|
+
[class_constant, method].compact.join(delimiter)
|
62
62
|
end
|
63
63
|
|
64
64
|
private
|
65
65
|
|
66
|
-
def
|
66
|
+
def delimiter
|
67
67
|
CLASS_METHOD_DELIMETER
|
68
68
|
end
|
69
69
|
end
|
@@ -81,12 +81,12 @@ module RuboCop
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def to_s
|
84
|
-
[class_constant, method].compact.join(
|
84
|
+
[class_constant, method].compact.join(delimiter)
|
85
85
|
end
|
86
86
|
|
87
87
|
private
|
88
88
|
|
89
|
-
def
|
89
|
+
def delimiter
|
90
90
|
instance_method? ? INSTANCE_METHOD_DELIMETER : CLASS_METHOD_DELIMETER
|
91
91
|
end
|
92
92
|
|
@@ -42,11 +42,12 @@ module RuboCop
|
|
42
42
|
# Maybe further investigation of RuboCop AST will lead to an essential solution.
|
43
43
|
return unless node.loc
|
44
44
|
|
45
|
-
constant = node.absolute? ? constant_name(node, node.short_name
|
45
|
+
constant = node.absolute? ? constant_name(node, node.short_name) : node.source
|
46
46
|
return unless (deprecated_constant = deprecated_constants[constant])
|
47
47
|
|
48
48
|
alternative = deprecated_constant['Alternative']
|
49
49
|
version = deprecated_constant['DeprecatedVersion']
|
50
|
+
return if target_ruby_version < version.to_f
|
50
51
|
|
51
52
|
add_offense(node, message: message(alternative, node.source, version)) do |corrector|
|
52
53
|
corrector.replace(node, alternative)
|
@@ -56,7 +57,7 @@ module RuboCop
|
|
56
57
|
private
|
57
58
|
|
58
59
|
def constant_name(node, nested_constant_name)
|
59
|
-
return nested_constant_name unless node.namespace.const_type?
|
60
|
+
return nested_constant_name.to_s unless node.namespace.const_type?
|
60
61
|
|
61
62
|
constant_name(node.namespace, "#{node.namespace.short_name}::#{nested_constant_name}")
|
62
63
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This cop checks constructors for disjunctive assignments that should
|
6
|
+
# This cop checks constructors for disjunctive assignments (`||=`) that should
|
7
7
|
# be plain assignments.
|
8
8
|
#
|
9
9
|
# So far, this cop is only concerned with disjunctive assignment of
|
@@ -12,6 +12,29 @@ module RuboCop
|
|
12
12
|
# In ruby, an instance variable is nil until a value is assigned, so the
|
13
13
|
# disjunction is unnecessary. A plain assignment has the same effect.
|
14
14
|
#
|
15
|
+
# @safety
|
16
|
+
# This cop is unsafe because it can register a false positive when a
|
17
|
+
# method is redefined in a subclass that calls super. For example:
|
18
|
+
#
|
19
|
+
# [source,ruby]
|
20
|
+
# ----
|
21
|
+
# class Base
|
22
|
+
# def initialize
|
23
|
+
# @config ||= 'base'
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# class Derived < Base
|
28
|
+
# def initialize
|
29
|
+
# @config = 'derived'
|
30
|
+
# super
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# ----
|
34
|
+
#
|
35
|
+
# Without the disjunctive assignment, `Derived` will be unable to override
|
36
|
+
# the value for `@config`.
|
37
|
+
#
|
15
38
|
# @example
|
16
39
|
# # bad
|
17
40
|
# def initialize
|
@@ -49,6 +49,9 @@ module RuboCop
|
|
49
49
|
def on_if(node)
|
50
50
|
return if node.ternary?
|
51
51
|
|
52
|
+
# If the if is on a single line, it'll be handled by `Style/OneLineConditional`
|
53
|
+
return if node.single_line?
|
54
|
+
|
52
55
|
check(node)
|
53
56
|
end
|
54
57
|
|
@@ -66,13 +69,10 @@ module RuboCop
|
|
66
69
|
|
67
70
|
def check_else(node)
|
68
71
|
else_branch = node.else_branch
|
69
|
-
|
70
|
-
return unless else_branch.begin_type?
|
71
|
-
|
72
|
-
first_else = else_branch.children.first
|
72
|
+
first_else = else_branch.begin_type? ? else_branch.children.first : else_branch
|
73
73
|
|
74
74
|
return unless first_else
|
75
|
-
return unless first_else
|
75
|
+
return unless same_line?(first_else, node.loc.else)
|
76
76
|
|
77
77
|
add_offense(first_else) { |corrector| autocorrect(corrector, node, first_else) }
|
78
78
|
end
|
@@ -81,9 +81,13 @@ module RuboCop
|
|
81
81
|
corrector.insert_after(node.loc.else, "\n")
|
82
82
|
|
83
83
|
blank_range = range_between(node.loc.else.end_pos, first_else.loc.expression.begin_pos)
|
84
|
-
indentation = indent(node
|
84
|
+
indentation = indent(node, offset: indentation_width)
|
85
85
|
corrector.replace(blank_range, indentation)
|
86
86
|
end
|
87
|
+
|
88
|
+
def indentation_width
|
89
|
+
@config.for_cop('Layout/IndentationWidth')['Width'] || 2
|
90
|
+
end
|
87
91
|
end
|
88
92
|
end
|
89
93
|
end
|
@@ -51,7 +51,7 @@ module RuboCop
|
|
51
51
|
|
52
52
|
def on_case_match(node)
|
53
53
|
node.in_pattern_branches.each do |branch|
|
54
|
-
next if branch.body || cop_config['AllowComments'] && comment_lines?(node)
|
54
|
+
next if branch.body || (cop_config['AllowComments'] && comment_lines?(node))
|
55
55
|
|
56
56
|
add_offense(branch)
|
57
57
|
end
|
@@ -118,7 +118,7 @@ module RuboCop
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def correct_arguments?(arguments)
|
121
|
-
arguments.size == 1 || arguments.size == 2 && arguments[1].hash_type?
|
121
|
+
arguments.size == 1 || (arguments.size == 2 && arguments[1].hash_type?)
|
122
122
|
end
|
123
123
|
|
124
124
|
def build_kwargs(node)
|
@@ -3,10 +3,19 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Prefer using `Hash#compare_by_identity` than using `object_id`
|
6
|
+
# Prefer using `Hash#compare_by_identity` rather than using `object_id`
|
7
|
+
# for hash keys.
|
7
8
|
#
|
8
|
-
# This cop
|
9
|
-
#
|
9
|
+
# This cop looks for hashes being keyed by objects' `object_id`, using
|
10
|
+
# one of these methods: `key?`, `has_key?`, `fetch`, `[]` and `[]=`.
|
11
|
+
#
|
12
|
+
# @safety
|
13
|
+
# This cop is unsafe. Although unlikely, the hash could store both object
|
14
|
+
# ids and other values that need be compared by value, and thus
|
15
|
+
# could be a false positive.
|
16
|
+
#
|
17
|
+
# Furthermore, this cop cannot guarantee that the receiver of one of the
|
18
|
+
# methods (`key?`, etc.) is actually a hash.
|
10
19
|
#
|
11
20
|
# @example
|
12
21
|
# # bad
|