rubocop 1.88.2 → 1.90.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/config/default.yml +139 -16
- data/exe/rubocop +1 -1
- data/lib/rubocop/cached_data.rb +7 -2
- data/lib/rubocop/cli/command/execute_runner.rb +31 -0
- data/lib/rubocop/cli.rb +2 -4
- data/lib/rubocop/comment_config/directive_range.rb +32 -0
- data/lib/rubocop/comment_config/disable_next.rb +97 -0
- data/lib/rubocop/comment_config.rb +81 -49
- data/lib/rubocop/config.rb +76 -5
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +1 -2
- data/lib/rubocop/config_validator.rb +39 -3
- data/lib/rubocop/cop/autocorrect_logic.rb +8 -0
- data/lib/rubocop/cop/badge.rb +8 -0
- data/lib/rubocop/cop/base.rb +40 -6
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +55 -5
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator.rb +4 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/class_structure.rb +108 -26
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/extra_spacing.rb +105 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +21 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +3 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +27 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -2
- data/lib/rubocop/cop/layout/line_length.rb +84 -12
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -2
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +12 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +77 -0
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +7 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +31 -34
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -7
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +71 -0
- data/lib/rubocop/cop/lint/ambiguous_range.rb +1 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +89 -0
- data/lib/rubocop/cop/lint/constant_reassignment.rb +18 -21
- data/lib/rubocop/cop/lint/constant_resolution.rb +25 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -8
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +300 -22
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +1 -2
- data/lib/rubocop/cop/lint/literal_as_condition.rb +8 -6
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -7
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +25 -12
- data/lib/rubocop/cop/lint/missing_super.rb +31 -1
- data/lib/rubocop/cop/lint/name_typo.rb +270 -0
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +98 -19
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +47 -7
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -2
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -4
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +1 -2
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +38 -3
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -2
- data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +36 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -0
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +61 -7
- data/lib/rubocop/cop/lint/void.rb +18 -8
- data/lib/rubocop/cop/lint.rb +178 -0
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics.rb +31 -0
- data/lib/rubocop/cop/migration/department_name.rb +1 -6
- data/lib/rubocop/cop/migration.rb +13 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +23 -5
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +23 -6
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -2
- data/lib/rubocop/cop/mixin/hash_subset.rb +1 -2
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +7 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +51 -6
- data/lib/rubocop/cop/mixin/project_index_help.rb +140 -0
- data/lib/rubocop/cop/mixin/range_help.rb +1 -2
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +46 -4
- data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
- data/lib/rubocop/cop/mixin.rb +82 -77
- data/lib/rubocop/cop/naming/accessor_method_name.rb +24 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +16 -0
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -4
- data/lib/rubocop/cop/naming/method_name.rb +5 -2
- data/lib/rubocop/cop/naming/predicate_prefix.rb +33 -5
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -2
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +37 -10
- data/lib/rubocop/cop/registry.rb +180 -46
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -6
- data/lib/rubocop/cop/style/array_first_last.rb +1 -2
- data/lib/rubocop/cop/style/array_intersect.rb +24 -5
- data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +3 -6
- data/lib/rubocop/cop/style/case_like_if.rb +2 -4
- data/lib/rubocop/cop/style/class_and_module_children.rb +79 -20
- data/lib/rubocop/cop/style/combinable_loops.rb +1 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +23 -2
- data/lib/rubocop/cop/style/constant_visibility.rb +1 -2
- data/lib/rubocop/cop/style/copyright.rb +5 -1
- data/lib/rubocop/cop/style/directive_scope.rb +171 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +76 -12
- data/lib/rubocop/cop/style/documentation.rb +47 -0
- data/lib/rubocop/cop/style/empty_case_condition.rb +1 -2
- data/lib/rubocop/cop/style/endless_method.rb +0 -10
- data/lib/rubocop/cop/style/format_string_token.rb +1 -2
- data/lib/rubocop/cop/style/guard_clause.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -4
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +8 -50
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +1 -2
- data/lib/rubocop/cop/style/lambda.rb +4 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +22 -7
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -2
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +30 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -2
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +5 -0
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -2
- data/lib/rubocop/cop/style/negative_array_index.rb +3 -3
- data/lib/rubocop/cop/style/nil_comparison.rb +1 -2
- data/lib/rubocop/cop/style/operator_method_call.rb +1 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -4
- data/lib/rubocop/cop/style/redundant_constant_base.rb +37 -1
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +1 -2
- data/lib/rubocop/cop/style/redundant_each.rb +1 -2
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
- data/lib/rubocop/cop/style/redundant_format.rb +14 -7
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +78 -135
- data/lib/rubocop/cop/style/redundant_parentheses.rb +65 -67
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -2
- data/lib/rubocop/cop/style/redundant_return.rb +1 -2
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +11 -2
- data/lib/rubocop/cop/style/sample.rb +11 -6
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -2
- data/lib/rubocop/cop/style/semicolon.rb +2 -4
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -5
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +18 -5
- data/lib/rubocop/cop/style/super_arguments.rb +1 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -2
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -2
- data/lib/rubocop/cop/style.rb +312 -0
- data/lib/rubocop/cop/team.rb +59 -6
- data/lib/rubocop/cop/util.rb +2 -4
- data/lib/rubocop/cop/variable_force/variable.rb +19 -8
- data/lib/rubocop/cops_documentation_generator.rb +4 -7
- data/lib/rubocop/directive_comment.rb +39 -3
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/html_formatter.rb +2 -4
- data/lib/rubocop/formatter/json_formatter.rb +11 -6
- data/lib/rubocop/formatter/junit_formatter.rb +26 -9
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -2
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -3
- data/lib/rubocop/formatter/tap_formatter.rb +3 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -2
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +4 -8
- data/lib/rubocop/lsp/routes.rb +89 -22
- data/lib/rubocop/lsp/runtime.rb +4 -0
- data/lib/rubocop/lsp/server.rb +4 -0
- data/lib/rubocop/lsp/stdin_runner.rb +20 -0
- data/lib/rubocop/mcp/server.rb +1 -2
- data/lib/rubocop/options.rb +10 -6
- data/lib/rubocop/path_util.rb +1 -2
- data/lib/rubocop/pending_cops_reporter.rb +1 -6
- data/lib/rubocop/plugin/configuration_integrator.rb +6 -3
- data/lib/rubocop/project_index_loader.rb +16 -0
- data/lib/rubocop/rake_task.rb +1 -2
- data/lib/rubocop/result_cache.rb +6 -4
- data/lib/rubocop/rspec/expect_offense.rb +2 -4
- data/lib/rubocop/rspec/shared_contexts.rb +16 -2
- data/lib/rubocop/runner.rb +71 -43
- data/lib/rubocop/server/cache.rb +11 -7
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +4 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/version.rb +3 -5
- data/lib/rubocop.rb +20 -626
- data/lib/ruby_lsp/rubocop/addon.rb +1 -2
- metadata +28 -5
|
@@ -15,6 +15,7 @@ module RuboCop
|
|
|
15
15
|
#
|
|
16
16
|
class RedundantParentheses < Base # rubocop:disable Metrics/ClassLength
|
|
17
17
|
include Parentheses
|
|
18
|
+
include ReparsedEquivalence
|
|
18
19
|
extend AutoCorrector
|
|
19
20
|
|
|
20
21
|
ALLOWED_NODE_TYPES = %i[or send splat kwsplat].freeze
|
|
@@ -30,12 +31,30 @@ module RuboCop
|
|
|
30
31
|
# @!method allowed_pin_operator?(node)
|
|
31
32
|
def_node_matcher :allowed_pin_operator?, '^(pin (begin !{lvar ivar cvar gvar}))'
|
|
32
33
|
|
|
34
|
+
def on_new_investigation
|
|
35
|
+
@pending_offenses = {}.compare_by_identity
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
|
|
33
39
|
def on_begin(node)
|
|
34
40
|
return if !parentheses?(node) || parens_allowed?(node) || ignore_syntax?(node)
|
|
35
41
|
|
|
36
42
|
check(node)
|
|
37
43
|
end
|
|
38
44
|
|
|
45
|
+
def on_investigation_end
|
|
46
|
+
# Each candidate's exact correction is verified by reparsing before
|
|
47
|
+
# the offense is registered, so redundancy never depends on
|
|
48
|
+
# hand-maintained knowledge of Ruby's grammar.
|
|
49
|
+
verified_by_reparse(@pending_offenses.keys).each do |node|
|
|
50
|
+
add_offense(node, message: @pending_offenses[node]) do |corrector|
|
|
51
|
+
ParenthesesCorrector.correct(corrector, node)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
super
|
|
56
|
+
end
|
|
57
|
+
|
|
39
58
|
private
|
|
40
59
|
|
|
41
60
|
def variable?(node)
|
|
@@ -44,7 +63,6 @@ module RuboCop
|
|
|
44
63
|
|
|
45
64
|
def parens_allowed?(node)
|
|
46
65
|
empty_parentheses?(node) ||
|
|
47
|
-
first_arg_begins_with_hash_literal?(node) ||
|
|
48
66
|
rescue?(node) ||
|
|
49
67
|
in_pattern_matching_in_method_argument?(node) ||
|
|
50
68
|
allowed_pin_operator?(node) ||
|
|
@@ -111,15 +129,6 @@ module RuboCop
|
|
|
111
129
|
node.children.empty?
|
|
112
130
|
end
|
|
113
131
|
|
|
114
|
-
def first_arg_begins_with_hash_literal?(node)
|
|
115
|
-
# Don't flag `method ({key: value})` or `method ({key: value}.method)`
|
|
116
|
-
hash_literal = method_chain_begins_with_hash_literal(node.children.first)
|
|
117
|
-
if (root_method = node.each_ancestor(:call).to_a.last)
|
|
118
|
-
parenthesized = root_method.parenthesized_call?
|
|
119
|
-
end
|
|
120
|
-
hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized
|
|
121
|
-
end
|
|
122
|
-
|
|
123
132
|
def in_pattern_matching_in_method_argument?(begin_node)
|
|
124
133
|
return false unless begin_node.parent&.call_type?
|
|
125
134
|
return false unless (node = begin_node.children.first)
|
|
@@ -127,14 +136,6 @@ module RuboCop
|
|
|
127
136
|
target_ruby_version <= 2.7 ? node.match_pattern_type? : node.match_pattern_p_type?
|
|
128
137
|
end
|
|
129
138
|
|
|
130
|
-
def method_chain_begins_with_hash_literal(node)
|
|
131
|
-
return if node.nil?
|
|
132
|
-
return node if node.hash_type?
|
|
133
|
-
return unless node.send_type?
|
|
134
|
-
|
|
135
|
-
method_chain_begins_with_hash_literal(node.children.first)
|
|
136
|
-
end
|
|
137
|
-
|
|
138
139
|
def check(begin_node)
|
|
139
140
|
node = begin_node.children.first
|
|
140
141
|
|
|
@@ -151,7 +152,7 @@ module RuboCop
|
|
|
151
152
|
check_send(begin_node, node) if call_node?(node)
|
|
152
153
|
end
|
|
153
154
|
|
|
154
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
155
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
155
156
|
def find_offense_message(begin_node, node)
|
|
156
157
|
return 'a keyword' if keyword_with_redundant_parentheses?(node)
|
|
157
158
|
return 'a literal' if node.literal? && disallowed_literal?(begin_node, node)
|
|
@@ -188,7 +189,6 @@ module RuboCop
|
|
|
188
189
|
'a comparison expression'
|
|
189
190
|
end
|
|
190
191
|
end
|
|
191
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
192
192
|
|
|
193
193
|
# @!method interpolation?(node)
|
|
194
194
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
|
@@ -231,8 +231,6 @@ module RuboCop
|
|
|
231
231
|
return check_unary(begin_node, node) if node.unary_operation?
|
|
232
232
|
|
|
233
233
|
return unless method_call_with_redundant_parentheses?(begin_node, node)
|
|
234
|
-
return if call_chain_starts_with_int?(begin_node, node) ||
|
|
235
|
-
do_end_block_in_method_chain?(begin_node, node)
|
|
236
234
|
|
|
237
235
|
offense(begin_node, 'a method call')
|
|
238
236
|
end
|
|
@@ -247,11 +245,50 @@ module RuboCop
|
|
|
247
245
|
end
|
|
248
246
|
|
|
249
247
|
def offense(node, msg)
|
|
250
|
-
|
|
251
|
-
|
|
248
|
+
@pending_offenses[node] = "Don't use parentheses around #{msg}."
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def apply_reparse_correction(corrector, node)
|
|
252
|
+
ParenthesesCorrector.correct(corrector, node)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Grouping parentheses are transparent to the comparison: single-child
|
|
256
|
+
# `begin` nodes are collapsed, a parenthesized statement sequence
|
|
257
|
+
# inside another sequence is spliced in place, and chains of the same
|
|
258
|
+
# `&&`/`||` operator are normalized to left association (`x && (y &&
|
|
259
|
+
# z)` and `x && y && z` differ as trees but `&&` and `||` cannot be
|
|
260
|
+
# redefined, so same-operator regrouping is semantically transparent).
|
|
261
|
+
def normalize_reparsed_ast(node)
|
|
262
|
+
return node unless node.is_a?(::Parser::AST::Node)
|
|
263
|
+
|
|
264
|
+
children = node.children.map { |child| normalize_reparsed_ast(child) }
|
|
265
|
+
children = splice_nested_sequences(children) if %i[begin kwbegin].include?(node.type)
|
|
266
|
+
|
|
267
|
+
node = node.updated(nil, children)
|
|
268
|
+
if node.begin_type? && children.one? && children.first.is_a?(::Parser::AST::Node)
|
|
269
|
+
children.first
|
|
270
|
+
else
|
|
271
|
+
rotate_same_operator(node)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def splice_nested_sequences(children)
|
|
276
|
+
children.flat_map do |child|
|
|
277
|
+
child.is_a?(::Parser::AST::Node) && child.begin_type? ? child.children : [child]
|
|
252
278
|
end
|
|
253
279
|
end
|
|
254
280
|
|
|
281
|
+
def rotate_same_operator(node)
|
|
282
|
+
return node unless node.type?(:and, :or)
|
|
283
|
+
|
|
284
|
+
right = node.rhs
|
|
285
|
+
return node unless right.is_a?(::Parser::AST::Node) && right.type == node.type
|
|
286
|
+
|
|
287
|
+
rotated_left = rotate_same_operator(node.updated(nil, [node.lhs, right.lhs]))
|
|
288
|
+
|
|
289
|
+
rotate_same_operator(node.updated(nil, [rotated_left, right.rhs]))
|
|
290
|
+
end
|
|
291
|
+
|
|
255
292
|
def suspect_unary?(node)
|
|
256
293
|
node.send_type? && node.unary_operation? && !node.prefix_not?
|
|
257
294
|
end
|
|
@@ -261,16 +298,13 @@ module RuboCop
|
|
|
261
298
|
end
|
|
262
299
|
|
|
263
300
|
def disallowed_literal?(begin_node, node)
|
|
264
|
-
|
|
265
|
-
|
|
301
|
+
return true unless node.range_type?
|
|
302
|
+
return false unless (parent = begin_node.parent)
|
|
266
303
|
|
|
267
|
-
|
|
268
|
-
else
|
|
269
|
-
!raised_to_power_negative_numeric?(begin_node, node)
|
|
270
|
-
end
|
|
304
|
+
parent.begin_type? && parent.children.one?
|
|
271
305
|
end
|
|
272
306
|
|
|
273
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
307
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
274
308
|
def body_range?(begin_node, node)
|
|
275
309
|
return false if begin_node.chained?
|
|
276
310
|
return false unless node.range_type?
|
|
@@ -280,7 +314,6 @@ module RuboCop
|
|
|
280
314
|
(node.begin.nil? && begin_node == parent.children.first) ||
|
|
281
315
|
(node.end.nil? && begin_node == parent.children.last)
|
|
282
316
|
end
|
|
283
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
284
317
|
|
|
285
318
|
def disallowed_one_line_pattern_matching?(begin_node, node)
|
|
286
319
|
if (parent = begin_node.parent)
|
|
@@ -291,17 +324,6 @@ module RuboCop
|
|
|
291
324
|
node.any_match_pattern_type? && node.each_ancestor.none?(&:operator_keyword?)
|
|
292
325
|
end
|
|
293
326
|
|
|
294
|
-
def raised_to_power_negative_numeric?(begin_node, node)
|
|
295
|
-
return false unless node.numeric_type?
|
|
296
|
-
|
|
297
|
-
next_sibling = begin_node.right_sibling
|
|
298
|
-
return false unless next_sibling
|
|
299
|
-
|
|
300
|
-
base_value = node.children.first
|
|
301
|
-
|
|
302
|
-
base_value.negative? && next_sibling == :**
|
|
303
|
-
end
|
|
304
|
-
|
|
305
327
|
def keyword_with_redundant_parentheses?(node)
|
|
306
328
|
return false unless node.keyword?
|
|
307
329
|
return true if node.special_keyword?
|
|
@@ -333,30 +355,6 @@ module RuboCop
|
|
|
333
355
|
def only_begin_arg?(args)
|
|
334
356
|
args.one? && args.first&.begin_type?
|
|
335
357
|
end
|
|
336
|
-
|
|
337
|
-
def first_argument?(node)
|
|
338
|
-
return true if first_call_argument?(node)
|
|
339
|
-
|
|
340
|
-
node.each_ancestor.any? { |ancestor| first_argument?(ancestor) }
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
# @!method first_call_argument?(node)
|
|
344
|
-
def_node_matcher :first_call_argument?, <<~PATTERN
|
|
345
|
-
{^(call _ _ equal?(%0) ...)
|
|
346
|
-
^({super yield} equal?(%0) ...)}
|
|
347
|
-
PATTERN
|
|
348
|
-
|
|
349
|
-
def call_chain_starts_with_int?(begin_node, send_node)
|
|
350
|
-
recv = first_part_of_call_chain(send_node)
|
|
351
|
-
recv&.int_type? && (parent = begin_node.parent) &&
|
|
352
|
-
parent.send_type? && (parent.method?(:-@) || parent.method?(:+@))
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
def do_end_block_in_method_chain?(begin_node, node)
|
|
356
|
-
return false unless (block = node.each_descendant(:any_block).first)
|
|
357
|
-
|
|
358
|
-
block.keywords? && begin_node.each_ancestor(:call).any?
|
|
359
|
-
end
|
|
360
358
|
end
|
|
361
359
|
end
|
|
362
360
|
end
|
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
|
66
66
|
DETERMINISTIC_REGEX.match?(regexp_node.source)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
# rubocop:disable Metrics/MethodLength
|
|
69
|
+
# rubocop:disable-next Metrics/MethodLength
|
|
70
70
|
def preferred_argument(regexp_node)
|
|
71
71
|
new_argument = replacement(regexp_node)
|
|
72
72
|
|
|
@@ -92,7 +92,6 @@ module RuboCop
|
|
|
92
92
|
|
|
93
93
|
"#{quote}#{new_argument}#{quote}"
|
|
94
94
|
end
|
|
95
|
-
# rubocop:enable Metrics/MethodLength
|
|
96
95
|
|
|
97
96
|
def replacement(regexp_node)
|
|
98
97
|
regexp_content = regexp_node.content
|
|
@@ -108,7 +108,7 @@ module RuboCop
|
|
|
108
108
|
corrector.insert_after(node.children.last, '}')
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
111
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
112
112
|
def check_branch(node)
|
|
113
113
|
return unless node
|
|
114
114
|
|
|
@@ -124,7 +124,6 @@ module RuboCop
|
|
|
124
124
|
check_begin_node(node)
|
|
125
125
|
end
|
|
126
126
|
end
|
|
127
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
128
127
|
|
|
129
128
|
def check_return_node(node)
|
|
130
129
|
return if cop_config['AllowMultipleReturnValues'] && node.children.size > 1
|
|
@@ -55,7 +55,7 @@ module RuboCop
|
|
|
55
55
|
...))
|
|
56
56
|
PATTERN
|
|
57
57
|
|
|
58
|
-
# rubocop:disable Metrics/AbcSize
|
|
58
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
59
59
|
def on_lvasgn(node)
|
|
60
60
|
return unless (rhs = node.rhs)
|
|
61
61
|
return unless rhs.type?(:any_block, :call) && method_returning_self?(rhs.method_name)
|
|
@@ -69,7 +69,6 @@ module RuboCop
|
|
|
69
69
|
corrector.replace(node, rhs.source)
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
|
-
# rubocop:enable Metrics/AbcSize
|
|
73
72
|
alias on_ivasgn on_lvasgn
|
|
74
73
|
alias on_cvasgn on_lvasgn
|
|
75
74
|
alias on_gvasgn on_lvasgn
|
|
@@ -75,7 +75,7 @@ module RuboCop
|
|
|
75
75
|
node.loc.to_hash.key?(:begin) && !node.loc.begin.nil?
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
78
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
79
79
|
def allowed_escape?(node, range)
|
|
80
80
|
escaped = range.source[(1..-1)]
|
|
81
81
|
|
|
@@ -95,7 +95,6 @@ module RuboCop
|
|
|
95
95
|
|
|
96
96
|
false
|
|
97
97
|
end
|
|
98
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
99
98
|
|
|
100
99
|
def interpolation_not_enabled?(node)
|
|
101
100
|
single_quoted?(node) ||
|
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
|
67
67
|
node.parent && parentheses?(node.parent)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
# rubocop:disable Metrics/AbcSize
|
|
70
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
71
71
|
def correct_rescue_block(corrector, node, parenthesized)
|
|
72
72
|
operation = node.body
|
|
73
73
|
|
|
@@ -83,7 +83,6 @@ module RuboCop
|
|
|
83
83
|
#{node_offset}end
|
|
84
84
|
RESCUE_CLAUSE
|
|
85
85
|
end
|
|
86
|
-
# rubocop:enable Metrics/AbcSize
|
|
87
86
|
|
|
88
87
|
def indentation_and_offset(node, parenthesized)
|
|
89
88
|
node_indentation = indentation(node)
|
|
@@ -37,6 +37,16 @@ module RuboCop
|
|
|
37
37
|
# x&.foo # raises NoMethodError
|
|
38
38
|
# ----
|
|
39
39
|
#
|
|
40
|
+
# Additionally, when a method chain is converted, a `NoMethodError` that
|
|
41
|
+
# the original code raised for an intermediate `nil` value is suppressed:
|
|
42
|
+
#
|
|
43
|
+
# [source,ruby]
|
|
44
|
+
# ----
|
|
45
|
+
# x = Struct.new(:foo).new(nil)
|
|
46
|
+
# x && x.foo.bar # raises NoMethodError
|
|
47
|
+
# x&.foo&.bar # returns nil
|
|
48
|
+
# ----
|
|
49
|
+
#
|
|
40
50
|
# @example
|
|
41
51
|
# # bad
|
|
42
52
|
# foo.bar if foo
|
|
@@ -142,7 +152,7 @@ module RuboCop
|
|
|
142
152
|
# @!method strip_begin(node)
|
|
143
153
|
def_node_matcher :strip_begin, '{ (begin $!begin) $!(begin) }'
|
|
144
154
|
|
|
145
|
-
# rubocop:disable Metrics/AbcSize
|
|
155
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
146
156
|
def on_if(node)
|
|
147
157
|
return if allowed_if_condition?(node)
|
|
148
158
|
|
|
@@ -160,7 +170,6 @@ module RuboCop
|
|
|
160
170
|
corrector.insert_before(method_call.loc.dot, '&') unless method_call.safe_navigation?
|
|
161
171
|
end
|
|
162
172
|
end
|
|
163
|
-
# rubocop:enable Metrics/AbcSize
|
|
164
173
|
|
|
165
174
|
def on_and(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
|
166
175
|
collect_and_clauses(node).each do |(lhs, lhs_operator_range), (rhs, _rhs_operator_range)|
|
|
@@ -7,6 +7,10 @@ module RuboCop
|
|
|
7
7
|
# `shuffle.last`, and `shuffle[]` and change them to use
|
|
8
8
|
# `sample` instead.
|
|
9
9
|
#
|
|
10
|
+
# NOTE: An offense involving a `random:` argument is registered but not autocorrected:
|
|
11
|
+
# `shuffle` and `sample` consume the given generator differently, so for a seeded generator
|
|
12
|
+
# the correction would select different elements.
|
|
13
|
+
#
|
|
10
14
|
# @example
|
|
11
15
|
# # bad
|
|
12
16
|
# [1, 2, 3].shuffle.first
|
|
@@ -45,10 +49,12 @@ module RuboCop
|
|
|
45
49
|
range = source_range(shuffle_node, node)
|
|
46
50
|
message = message(shuffle_arg, method, method_args, range)
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
corrector
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
if shuffle_arg.empty?
|
|
53
|
+
add_offense(range, message: message) do |corrector|
|
|
54
|
+
corrector.replace(range, correction(shuffle_arg, method, method_args))
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
add_offense(range, message: message)
|
|
52
58
|
end
|
|
53
59
|
end
|
|
54
60
|
end
|
|
@@ -92,7 +98,7 @@ module RuboCop
|
|
|
92
98
|
second.int_type? ? second.to_a.first : :unknown
|
|
93
99
|
end
|
|
94
100
|
|
|
95
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
101
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
96
102
|
def range_size(range_node)
|
|
97
103
|
vals = range_node.to_a
|
|
98
104
|
return :unknown unless vals.all? { |val| val.nil? || val.int_type? }
|
|
@@ -107,7 +113,6 @@ module RuboCop
|
|
|
107
113
|
(low..high).size
|
|
108
114
|
end
|
|
109
115
|
end
|
|
110
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
111
116
|
|
|
112
117
|
def source_range(shuffle_node, node)
|
|
113
118
|
shuffle_node.loc.selector.join(node.source_range.end)
|
|
@@ -97,7 +97,7 @@ module RuboCop
|
|
|
97
97
|
}
|
|
98
98
|
PATTERN
|
|
99
99
|
|
|
100
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
100
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
101
101
|
def on_send(node)
|
|
102
102
|
return if target_ruby_version < 2.6 && node.method?(:filter)
|
|
103
103
|
return unless (block_node = node.block_node)
|
|
@@ -113,7 +113,6 @@ module RuboCop
|
|
|
113
113
|
|
|
114
114
|
register_offense(node, block_node, regexp, replacement)
|
|
115
115
|
end
|
|
116
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
117
116
|
alias on_csend on_send
|
|
118
117
|
|
|
119
118
|
private
|
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
|
83
83
|
processed_source.tokens.group_by(&:line)
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
86
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
87
87
|
def semicolon_position(tokens)
|
|
88
88
|
if tokens.last.semicolon?
|
|
89
89
|
-1
|
|
@@ -100,7 +100,6 @@ module RuboCop
|
|
|
100
100
|
-4
|
|
101
101
|
end
|
|
102
102
|
end
|
|
103
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
104
103
|
|
|
105
104
|
def exist_semicolon_before_right_curly_brace?(tokens)
|
|
106
105
|
tokens[-2]&.right_curly_brace? && tokens[-3]&.semicolon?
|
|
@@ -122,7 +121,7 @@ module RuboCop
|
|
|
122
121
|
tokens[1]&.type == :tSTRING_DBEG && tokens[2]&.semicolon?
|
|
123
122
|
end
|
|
124
123
|
|
|
125
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
124
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength
|
|
126
125
|
def register_semicolon(line, column, after_expression, token_before_semicolon = nil)
|
|
127
126
|
range = source_range(processed_source.buffer, line, column)
|
|
128
127
|
|
|
@@ -146,7 +145,6 @@ module RuboCop
|
|
|
146
145
|
end
|
|
147
146
|
end
|
|
148
147
|
end
|
|
149
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
150
148
|
|
|
151
149
|
def replace_semicolon_with_line_break(corrector, range)
|
|
152
150
|
# Replacing the semicolon with a newline would move the rest of the
|
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
|
36
36
|
|
|
37
37
|
MSG = 'Prefer multiline `do`...`end` block.'
|
|
38
38
|
|
|
39
|
-
# rubocop:disable Metrics/AbcSize
|
|
39
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
40
40
|
def on_block(node)
|
|
41
41
|
return if node.multiline? || node.braces?
|
|
42
42
|
return if single_line_blocks_preferred? && suitable_as_single_line?(node)
|
|
@@ -55,7 +55,6 @@ module RuboCop
|
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
|
-
# rubocop:enable Metrics/AbcSize
|
|
59
58
|
alias on_numblock on_block
|
|
60
59
|
alias on_itblock on_block
|
|
61
60
|
|
|
@@ -48,6 +48,7 @@ module RuboCop
|
|
|
48
48
|
# end if condition_a
|
|
49
49
|
class SoleNestedConditional < Base
|
|
50
50
|
include RangeHelp
|
|
51
|
+
include ReparsedEquivalence
|
|
51
52
|
extend AutoCorrector
|
|
52
53
|
|
|
53
54
|
MSG = 'Consider merging nested conditions into outer `%<conditional_type>s` conditions.'
|
|
@@ -57,11 +58,10 @@ module RuboCop
|
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def on_if(node)
|
|
60
|
-
return
|
|
61
|
+
return unless offending_conditional?(node)
|
|
61
62
|
|
|
62
63
|
if_branch = node.if_branch
|
|
63
|
-
return
|
|
64
|
-
return unless offending_branch?(node, if_branch)
|
|
64
|
+
return unless correction_parses?(node)
|
|
65
65
|
|
|
66
66
|
message = format(MSG, conditional_type: node.keyword)
|
|
67
67
|
add_offense(if_branch.loc.keyword, message: message) do |corrector|
|
|
@@ -74,6 +74,23 @@ module RuboCop
|
|
|
74
74
|
|
|
75
75
|
private
|
|
76
76
|
|
|
77
|
+
def offending_conditional?(node)
|
|
78
|
+
return false if node.ternary? || node.else? || node.elsif?
|
|
79
|
+
|
|
80
|
+
if_branch = node.if_branch
|
|
81
|
+
return false if use_variable_assignment_in_condition?(node.condition, if_branch)
|
|
82
|
+
|
|
83
|
+
offending_branch?(node, if_branch)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Merging the conditionals intentionally produces a different AST, so
|
|
87
|
+
# full equivalence cannot be checked, but the corrected source must at
|
|
88
|
+
# least remain parseable (see `ReparsedEquivalence#correction_parses?`),
|
|
89
|
+
# which suppresses the entire produces-invalid-code bug class.
|
|
90
|
+
def apply_reparse_correction(corrector, node)
|
|
91
|
+
autocorrect(corrector, node, node.if_branch)
|
|
92
|
+
end
|
|
93
|
+
|
|
77
94
|
def use_variable_assignment_in_condition?(condition, if_branch)
|
|
78
95
|
assigned_variables = assigned_variables(condition)
|
|
79
96
|
|
|
@@ -131,7 +148,7 @@ module RuboCop
|
|
|
131
148
|
corrector.remove(range_with_surrounding_space(range, newlines: false))
|
|
132
149
|
end
|
|
133
150
|
|
|
134
|
-
# rubocop:disable Metrics/AbcSize
|
|
151
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
135
152
|
def correct_for_basic_condition_style(corrector, node, if_branch)
|
|
136
153
|
range = range_between(
|
|
137
154
|
node.condition.source_range.end_pos, if_branch.condition.source_range.begin_pos
|
|
@@ -147,7 +164,6 @@ module RuboCop
|
|
|
147
164
|
end
|
|
148
165
|
corrector.remove(end_range)
|
|
149
166
|
end
|
|
150
|
-
# rubocop:enable Metrics/AbcSize
|
|
151
167
|
|
|
152
168
|
def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
|
|
153
169
|
correct_node(corrector, if_branch)
|
|
@@ -25,6 +25,8 @@ module RuboCop
|
|
|
25
25
|
|
|
26
26
|
MSG_REQUIRE = 'Wrap stabby lambda arguments with parentheses.'
|
|
27
27
|
MSG_NO_REQUIRE = 'Do not wrap stabby lambda arguments with parentheses.'
|
|
28
|
+
RESTRICT_ON_SEND = %i[lambda].freeze
|
|
29
|
+
|
|
28
30
|
def on_send(node)
|
|
29
31
|
return unless stabby_lambda_with_args?(node)
|
|
30
32
|
return unless redundant_parentheses?(node) || missing_parentheses?(node)
|
|
@@ -12,6 +12,11 @@ module RuboCop
|
|
|
12
12
|
# for some other subclass, monkey-patched with instance methods or
|
|
13
13
|
# a dummy instance is instantiated from it somewhere.
|
|
14
14
|
#
|
|
15
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is
|
|
16
|
+
# installed, classes that are subclassed anywhere in the project are
|
|
17
|
+
# not reported, since converting them to modules would break their
|
|
18
|
+
# subclasses.
|
|
19
|
+
#
|
|
15
20
|
# @example
|
|
16
21
|
# # bad
|
|
17
22
|
# class SomeClass
|
|
@@ -44,6 +49,7 @@ module RuboCop
|
|
|
44
49
|
# end
|
|
45
50
|
#
|
|
46
51
|
class StaticClass < Base
|
|
52
|
+
include ProjectIndexHelp
|
|
47
53
|
include RangeHelp
|
|
48
54
|
include VisibilityHelp
|
|
49
55
|
extend AutoCorrector
|
|
@@ -53,6 +59,7 @@ module RuboCop
|
|
|
53
59
|
def on_class(class_node)
|
|
54
60
|
return if class_node.parent_class
|
|
55
61
|
return unless class_convertible_to_module?(class_node)
|
|
62
|
+
return if subclassed_in_project?(class_node)
|
|
56
63
|
|
|
57
64
|
add_offense(class_node) do |corrector|
|
|
58
65
|
autocorrect(corrector, class_node)
|
|
@@ -61,6 +68,20 @@ module RuboCop
|
|
|
61
68
|
|
|
62
69
|
private
|
|
63
70
|
|
|
71
|
+
# When `AllCops/UseProjectIndex` is enabled, a class with descendants
|
|
72
|
+
# anywhere in the project is not reported: converting it to a module
|
|
73
|
+
# would break its subclasses.
|
|
74
|
+
def subclassed_in_project?(class_node)
|
|
75
|
+
return false unless project_index
|
|
76
|
+
|
|
77
|
+
declaration = resolve_constant_in_index(class_node.identifier)
|
|
78
|
+
return false unless declaration.is_a?(Rubydex::Class)
|
|
79
|
+
|
|
80
|
+
declaration.descendants.any? { |descendant| descendant.name != declaration.name }
|
|
81
|
+
rescue StandardError
|
|
82
|
+
false
|
|
83
|
+
end
|
|
84
|
+
|
|
64
85
|
def autocorrect(corrector, class_node)
|
|
65
86
|
corrector.replace(class_node.loc.keyword, 'module')
|
|
66
87
|
corrector.insert_after(class_node.loc.name, "\nmodule_function\n")
|
|
@@ -149,11 +149,7 @@ module RuboCop
|
|
|
149
149
|
def adjust_str(part)
|
|
150
150
|
case part.type
|
|
151
151
|
when :str
|
|
152
|
-
|
|
153
|
-
part.value.gsub(/(\\|"|#\{|#@|#\$)/, '\\\\\&')
|
|
154
|
-
else
|
|
155
|
-
part.value.inspect[1..-2]
|
|
156
|
-
end
|
|
152
|
+
adjust_str_literal(part)
|
|
157
153
|
when :dstr, :begin
|
|
158
154
|
part.children.map do |child|
|
|
159
155
|
adjust_str(child)
|
|
@@ -163,6 +159,19 @@ module RuboCop
|
|
|
163
159
|
end
|
|
164
160
|
end
|
|
165
161
|
|
|
162
|
+
def adjust_str_literal(part)
|
|
163
|
+
if single_quoted?(part)
|
|
164
|
+
part.value.gsub(/(\\|"|#\{|#@|#\$)/, '\\\\\&')
|
|
165
|
+
elsif double_quoted?(part)
|
|
166
|
+
# Reuse the source as written - rebuilding it from the value via
|
|
167
|
+
# `inspect` would rewrite the author's escape notation
|
|
168
|
+
# (e.g. `\x0a` into `\n`).
|
|
169
|
+
part.source[1..-2]
|
|
170
|
+
else
|
|
171
|
+
part.value.inspect[1..-2]
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
166
175
|
def handle_quotes(parts)
|
|
167
176
|
parts.map do |part|
|
|
168
177
|
part == '"' ? '\"' : part
|
|
@@ -173,6 +182,10 @@ module RuboCop
|
|
|
173
182
|
str_node.source.start_with?("'")
|
|
174
183
|
end
|
|
175
184
|
|
|
185
|
+
def double_quoted?(str_node)
|
|
186
|
+
str_node.source.start_with?('"')
|
|
187
|
+
end
|
|
188
|
+
|
|
176
189
|
def mode
|
|
177
190
|
cop_config['Mode'].to_sym
|
|
178
191
|
end
|
|
@@ -103,7 +103,7 @@ module RuboCop
|
|
|
103
103
|
end
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
106
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
107
107
|
def arguments_identical?(def_node, super_node, def_args, super_args)
|
|
108
108
|
return false if argument_list_size_differs?(def_args, super_args, super_node)
|
|
109
109
|
|
|
@@ -120,7 +120,6 @@ module RuboCop
|
|
|
120
120
|
|
|
121
121
|
true
|
|
122
122
|
end
|
|
123
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
124
123
|
|
|
125
124
|
def argument_list_size_differs?(def_args, super_args, super_node)
|
|
126
125
|
# If the def node has a block argument and the super node has an explicit block,
|
|
@@ -167,7 +167,7 @@ module RuboCop
|
|
|
167
167
|
[Layout::SpaceBeforeBlockBraces]
|
|
168
168
|
end
|
|
169
169
|
|
|
170
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
170
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
171
171
|
def on_block(node)
|
|
172
172
|
symbol_proc?(node) do |dispatch_node, arguments_node, method_name|
|
|
173
173
|
if active_support_extensions_enabled?
|
|
@@ -184,7 +184,6 @@ module RuboCop
|
|
|
184
184
|
register_offense(node, method_name, dispatch_node.method_name)
|
|
185
185
|
end
|
|
186
186
|
end
|
|
187
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
188
187
|
alias on_numblock on_block
|
|
189
188
|
alias on_itblock on_block
|
|
190
189
|
|