rubocop 1.91.0 → 1.92.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +4 -1
- data/lib/rubocop/cached_data.rb +47 -7
- data/lib/rubocop/changed_files.rb +35 -13
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +2 -2
- data/lib/rubocop/cli/command/explain.rb +34 -0
- data/lib/rubocop/cli/command/show_cops.rb +6 -0
- data/lib/rubocop/cli/command/show_docs_url.rb +6 -4
- data/lib/rubocop/cli.rb +3 -2
- data/lib/rubocop/comment_config.rb +17 -8
- data/lib/rubocop/config_loader.rb +6 -3
- data/lib/rubocop/config_loader_resolver.rb +37 -12
- data/lib/rubocop/config_obsoletion/removed_cop.rb +1 -1
- data/lib/rubocop/config_validator.rb +11 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +42 -21
- data/lib/rubocop/cop/bundler/gem_comment.rb +0 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +0 -8
- data/lib/rubocop/cop/cop_documentation.rb +81 -0
- data/lib/rubocop/cop/cop_explanation.rb +140 -0
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +13 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +37 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +25 -4
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +34 -0
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +45 -8
- data/lib/rubocop/cop/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +0 -6
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -5
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +0 -7
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
- data/lib/rubocop/cop/layout/argument_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +27 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/class_structure.rb +29 -7
- data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/dot_position.rb +25 -15
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +9 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +19 -17
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -0
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +27 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +15 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +16 -8
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +16 -12
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +7 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +15 -0
- data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
- data/lib/rubocop/cop/layout/indentation_style.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +8 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/line_length.rb +153 -21
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +12 -0
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +8 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +9 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +6 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +30 -5
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +22 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +15 -2
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
- data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +6 -11
- data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +4 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +15 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +31 -8
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +2 -1
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +15 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +63 -19
- data/lib/rubocop/cop/lint/loop.rb +24 -2
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +71 -11
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -3
- data/lib/rubocop/cop/lint/number_conversion.rb +3 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +12 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +13 -2
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +47 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -0
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +18 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +14 -7
- data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/lint/void.rb +8 -1
- data/lib/rubocop/cop/metrics/class_length.rb +4 -2
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
- data/lib/rubocop/cop/metrics/module_length.rb +4 -2
- data/lib/rubocop/cop/mixin/alignment.rb +4 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +23 -19
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +8 -2
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +24 -5
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +26 -2
- data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +9 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +17 -2
- data/lib/rubocop/cop/mixin/project_index_help.rb +15 -0
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +13 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +25 -4
- data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
- data/lib/rubocop/cop/mixin.rb +2 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +0 -16
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
- data/lib/rubocop/cop/naming/predicate_prefix.rb +7 -22
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +59 -3
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/json_load.rb +16 -4
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +37 -2
- data/lib/rubocop/cop/style/alias.rb +18 -5
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/and_or.rb +6 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +32 -3
- data/lib/rubocop/cop/style/attr.rb +3 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +6 -4
- data/lib/rubocop/cop/style/block_delimiters.rb +35 -3
- data/lib/rubocop/cop/style/case_like_if.rb +6 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +56 -16
- data/lib/rubocop/cop/style/class_methods_definitions.rb +15 -0
- data/lib/rubocop/cop/style/collection_querying.rb +79 -46
- data/lib/rubocop/cop/style/combinable_loops.rb +89 -11
- data/lib/rubocop/cop/style/concat_array_literals.rb +58 -7
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +65 -9
- data/lib/rubocop/cop/style/double_negation.rb +11 -0
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +3 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +53 -11
- data/lib/rubocop/cop/style/endless_method.rb +71 -6
- data/lib/rubocop/cop/style/exact_regexp_match.rb +45 -8
- data/lib/rubocop/cop/style/explicit_block_argument.rb +50 -10
- data/lib/rubocop/cop/style/float_division.rb +22 -2
- data/lib/rubocop/cop/style/for.rb +53 -2
- data/lib/rubocop/cop/style/format_string.rb +28 -6
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/guard_clause.rb +31 -22
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +4 -0
- data/lib/rubocop/cop/style/hash_conversion.rb +28 -8
- data/lib/rubocop/cop/style/hash_lookup_method.rb +32 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +16 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +21 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +32 -26
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +47 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +24 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +94 -4
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +3 -1
- data/lib/rubocop/cop/style/lambda.rb +34 -1
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/map_into_array.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +80 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -2
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +26 -3
- data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -3
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +45 -5
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -5
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
- data/lib/rubocop/cop/style/mutable_constant.rb +52 -7
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +2 -1
- data/lib/rubocop/cop/style/negative_array_index.rb +9 -1
- data/lib/rubocop/cop/style/nested_modifier.rb +27 -8
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
- data/lib/rubocop/cop/style/next.rb +24 -10
- data/lib/rubocop/cop/style/nil_comparison.rb +16 -4
- data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
- data/lib/rubocop/cop/style/not.rb +10 -5
- data/lib/rubocop/cop/style/numeric_predicate.rb +21 -5
- data/lib/rubocop/cop/style/one_line_conditional.rb +13 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -1
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +14 -3
- data/lib/rubocop/cop/style/raise_args.rb +19 -9
- data/lib/rubocop/cop/style/reduce_to_hash.rb +17 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +22 -4
- data/lib/rubocop/cop/style/redundant_condition.rb +30 -13
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -0
- data/lib/rubocop/cop/style/redundant_exception.rb +15 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +9 -1
- data/lib/rubocop/cop/style/redundant_freeze.rb +11 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +24 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +12 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +7 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +20 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +4 -0
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +28 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +38 -4
- data/lib/rubocop/cop/style/regexp_literal.rb +75 -26
- data/lib/rubocop/cop/style/require_order.rb +25 -8
- data/lib/rubocop/cop/style/rescue_modifier.rb +11 -9
- data/lib/rubocop/cop/style/return_nil.rb +17 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
- data/lib/rubocop/cop/style/sample.rb +9 -8
- data/lib/rubocop/cop/style/self_assignment.rb +12 -15
- data/lib/rubocop/cop/style/semicolon.rb +16 -5
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +21 -4
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +29 -5
- data/lib/rubocop/cop/style/string_concatenation.rb +9 -3
- data/lib/rubocop/cop/style/struct_inheritance.rb +6 -0
- data/lib/rubocop/cop/style/super_arguments.rb +3 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +24 -6
- data/lib/rubocop/cop/style/ternary_parentheses.rb +23 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -19
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +24 -9
- data/lib/rubocop/cop/style/yoda_expression.rb +10 -1
- data/lib/rubocop/cop/team.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -1
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/formatter_set.rb +4 -0
- data/lib/rubocop/formatter/json_formatter.rb +71 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +3 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +3 -1
- data/lib/rubocop/formatter/sarif_formatter.rb +12 -7
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +3 -1
- data/lib/rubocop/lsp/routes.rb +23 -23
- data/lib/rubocop/lsp/runtime.rb +47 -11
- data/lib/rubocop/lsp/stdin_runner.rb +11 -5
- data/lib/rubocop/lsp.rb +5 -2
- data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
- data/lib/rubocop/mcp/explain_tool.rb +68 -0
- data/lib/rubocop/mcp/scope.rb +65 -0
- data/lib/rubocop/mcp/server.rb +184 -76
- data/lib/rubocop/mcp/source_files.rb +35 -0
- data/lib/rubocop/offense_limit.rb +30 -0
- data/lib/rubocop/options.rb +45 -10
- data/lib/rubocop/plugin/configuration_integrator.rb +12 -5
- data/lib/rubocop/remote_config.rb +4 -1
- data/lib/rubocop/result_cache.rb +20 -13
- data/lib/rubocop/runner.rb +109 -41
- data/lib/rubocop/server/cache.rb +6 -6
- data/lib/rubocop/target_ruby.rb +21 -9
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -0
- metadata +16 -5
|
@@ -56,6 +56,13 @@ module RuboCop
|
|
|
56
56
|
ARG_MSG = 'Block argument expression is not on the same line as the block start.'
|
|
57
57
|
PIPE_SIZE = '|'.length
|
|
58
58
|
|
|
59
|
+
# `Style/Lambda` moves the block arguments of `lambda` into `->(...)`, and
|
|
60
|
+
# `Style/ItBlockParameter` and `Style/HashEachMethods` remove some or all of them,
|
|
61
|
+
# in the same pass, while this cop moves them next to the block start.
|
|
62
|
+
def self.autocorrect_incompatible_with
|
|
63
|
+
[Style::HashEachMethods, Style::ItBlockParameter, Style::Lambda]
|
|
64
|
+
end
|
|
65
|
+
|
|
59
66
|
def on_block(node)
|
|
60
67
|
return if node.single_line?
|
|
61
68
|
|
|
@@ -155,7 +162,7 @@ module RuboCop
|
|
|
155
162
|
end
|
|
156
163
|
|
|
157
164
|
def include_trailing_comma?(args)
|
|
158
|
-
arg_count = args.each_descendant(
|
|
165
|
+
arg_count = args.each_descendant.count(&:argument_type?)
|
|
159
166
|
arg_count == 1 && args.source.include?(',')
|
|
160
167
|
end
|
|
161
168
|
end
|
|
@@ -106,6 +106,15 @@ module RuboCop
|
|
|
106
106
|
ALWAYS_SAME_LINE_MESSAGE = 'Closing hash brace must be on the same ' \
|
|
107
107
|
'line as the last hash element.'
|
|
108
108
|
|
|
109
|
+
# Moving the closing brace after a method call value while
|
|
110
|
+
# `Layout/MultilineMethodCallBraceLayout` moves that call's closing parenthesis
|
|
111
|
+
# before a comment in the same pass places the brace after the comment.
|
|
112
|
+
# Moving it while `Style/HashAsLastArrayItem` or `Style/RedundantDoubleSplatHashBraces`
|
|
113
|
+
# removes the braces in the same pass leaves the brace behind.
|
|
114
|
+
def self.autocorrect_incompatible_with
|
|
115
|
+
[Layout::MultilineMethodCallBraceLayout, Style::HashAsLastArrayItem, Style::RedundantDoubleSplatHashBraces]
|
|
116
|
+
end
|
|
117
|
+
|
|
109
118
|
def on_hash(node)
|
|
110
119
|
check_brace_layout(node)
|
|
111
120
|
end
|
|
@@ -106,6 +106,12 @@ module RuboCop
|
|
|
106
106
|
ALWAYS_SAME_LINE_MESSAGE = 'Closing method call brace must be on ' \
|
|
107
107
|
'the same line as the last argument.'
|
|
108
108
|
|
|
109
|
+
# Moving the closing parenthesis and removing it under `omit_parentheses` in the same pass
|
|
110
|
+
# leaves the moved parenthesis behind.
|
|
111
|
+
def self.autocorrect_incompatible_with
|
|
112
|
+
[Style::MethodCallWithArgsParentheses]
|
|
113
|
+
end
|
|
114
|
+
|
|
109
115
|
def on_send(node)
|
|
110
116
|
check_brace_layout(node)
|
|
111
117
|
end
|
|
@@ -73,14 +73,28 @@ module RuboCop
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def find_pair_ancestor(node)
|
|
76
|
+
child = node
|
|
76
77
|
node.each_ancestor do |ancestor|
|
|
77
78
|
return ancestor if ancestor.pair_type?
|
|
78
79
|
break if grouped_expression?(ancestor) || inside_arg_list_parentheses?(node, ancestor)
|
|
80
|
+
break if inside_body?(ancestor, child)
|
|
81
|
+
|
|
82
|
+
child = ancestor
|
|
79
83
|
end
|
|
80
84
|
|
|
81
85
|
nil
|
|
82
86
|
end
|
|
83
87
|
|
|
88
|
+
# A block, `begin`, `if` or loop body is a separate set of statements, so
|
|
89
|
+
# a method chain in it is not the value of a hash pair the body is nested in.
|
|
90
|
+
# The send node of a block is still part of the value.
|
|
91
|
+
def inside_body?(ancestor, child)
|
|
92
|
+
return !child.equal?(ancestor.send_node) if ancestor.any_block_type?
|
|
93
|
+
return !ancestor.ternary? if ancestor.if_type?
|
|
94
|
+
|
|
95
|
+
ancestor.type?(:kwbegin, :while, :until, :for)
|
|
96
|
+
end
|
|
97
|
+
|
|
84
98
|
def unwrap_block_node(node)
|
|
85
99
|
node&.any_block_type? ? node.send_node : node
|
|
86
100
|
end
|
|
@@ -88,7 +102,7 @@ module RuboCop
|
|
|
88
102
|
def autocorrect(corrector, node)
|
|
89
103
|
if @send_node.block_node
|
|
90
104
|
correct_selector_only(corrector, node)
|
|
91
|
-
correct_block(corrector, @send_node.block_node)
|
|
105
|
+
correct_block(corrector, @send_node.block_node, node.first_line)
|
|
92
106
|
else
|
|
93
107
|
AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
|
|
94
108
|
end
|
|
@@ -100,10 +114,21 @@ module RuboCop
|
|
|
100
114
|
AlignmentCorrector.correct(corrector, processed_source, selector_range, @column_delta)
|
|
101
115
|
end
|
|
102
116
|
|
|
103
|
-
def correct_block(corrector, block_node)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
117
|
+
def correct_block(corrector, block_node, selector_line)
|
|
118
|
+
lines_to_shift = block_lines(block_node) - [selector_line]
|
|
119
|
+
|
|
120
|
+
lines_to_shift.each do |line|
|
|
121
|
+
line_range = processed_source.buffer.line_range(line)
|
|
122
|
+
|
|
123
|
+
AlignmentCorrector.correct(corrector, processed_source, line_range, @column_delta)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def block_lines(block_node)
|
|
128
|
+
body = block_node.body
|
|
129
|
+
lines = body ? (body.first_line..body.last_line).to_a : []
|
|
130
|
+
|
|
131
|
+
(lines << block_node.loc.end.line).uniq
|
|
107
132
|
end
|
|
108
133
|
|
|
109
134
|
def relevant_node?(send_node)
|
|
@@ -118,6 +118,10 @@ module RuboCop
|
|
|
118
118
|
ALWAYS_SAME_LINE_MESSAGE = 'Closing method definition brace must be ' \
|
|
119
119
|
'on the same line as the last parameter.'
|
|
120
120
|
|
|
121
|
+
def self.autocorrect_incompatible_with
|
|
122
|
+
[Style::MultilineMethodSignature]
|
|
123
|
+
end
|
|
124
|
+
|
|
121
125
|
def on_def(node)
|
|
122
126
|
check_brace_layout(node.arguments)
|
|
123
127
|
end
|
|
@@ -54,6 +54,11 @@ module RuboCop
|
|
|
54
54
|
|
|
55
55
|
MSG = 'Redundant line break detected.'
|
|
56
56
|
|
|
57
|
+
def on_new_investigation
|
|
58
|
+
super
|
|
59
|
+
@offense_line_ranges = []
|
|
60
|
+
end
|
|
61
|
+
|
|
57
62
|
def on_lvasgn(node)
|
|
58
63
|
super unless end_with_percent_blank_string?(processed_source)
|
|
59
64
|
end
|
|
@@ -77,12 +82,15 @@ module RuboCop
|
|
|
77
82
|
end
|
|
78
83
|
|
|
79
84
|
def check_assignment(node, _rhs)
|
|
80
|
-
return unless offense?(node)
|
|
85
|
+
return unless offense?(node) && !part_of_ignored_node?(node)
|
|
81
86
|
|
|
82
87
|
register_offense(node)
|
|
83
88
|
end
|
|
84
89
|
|
|
85
90
|
def register_offense(node)
|
|
91
|
+
line_range = joined_line_range(node)
|
|
92
|
+
return if too_long_as_single_line?(line_range)
|
|
93
|
+
|
|
86
94
|
# The exact single-line correction is verified to parse equivalently
|
|
87
95
|
# before the offense is registered, so a join that would change how
|
|
88
96
|
# the code parses is never reported or offered.
|
|
@@ -92,6 +100,19 @@ module RuboCop
|
|
|
92
100
|
corrector.replace(node, to_single_line(node.source).strip)
|
|
93
101
|
end
|
|
94
102
|
ignore_node(node)
|
|
103
|
+
@offense_line_ranges.reject! { |range| line_range.cover?(range) }
|
|
104
|
+
@offense_line_ranges << line_range
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Offenses registered in the same pass that share a line with `node`
|
|
108
|
+
# get joined onto that line too, so the combined line has to fit.
|
|
109
|
+
def joined_line_range(node)
|
|
110
|
+
sharing_ranges = @offense_line_ranges.select do |range|
|
|
111
|
+
range.begin <= node.last_line && node.first_line <= range.end
|
|
112
|
+
end
|
|
113
|
+
lines = [node.first_line, node.last_line, *sharing_ranges.flat_map(&:minmax)]
|
|
114
|
+
|
|
115
|
+
lines.min..lines.max
|
|
95
116
|
end
|
|
96
117
|
|
|
97
118
|
def apply_reparse_correction(corrector, node)
|
|
@@ -22,6 +22,7 @@ module RuboCop
|
|
|
22
22
|
# puts 'error'
|
|
23
23
|
# end
|
|
24
24
|
class RescueEnsureAlignment < Base
|
|
25
|
+
include Alignment
|
|
25
26
|
include RangeHelp
|
|
26
27
|
include EndKeywordAlignment
|
|
27
28
|
extend AutoCorrector
|
|
@@ -74,9 +75,10 @@ module RuboCop
|
|
|
74
75
|
# Some inline node is sitting before current node.
|
|
75
76
|
return nil unless whitespace.source.strip.empty?
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
indentation = alignment_indentation(alignment_location)
|
|
79
|
+
return nil if indentation.nil?
|
|
78
80
|
|
|
79
|
-
corrector.replace(whitespace,
|
|
81
|
+
corrector.replace(whitespace, indentation)
|
|
80
82
|
end
|
|
81
83
|
|
|
82
84
|
def format_message(alignment_node, alignment_loc, kw_loc)
|
|
@@ -91,6 +93,17 @@ module RuboCop
|
|
|
91
93
|
)
|
|
92
94
|
end
|
|
93
95
|
|
|
96
|
+
# A run of spaces sized to the target column would be turned back into tabs by
|
|
97
|
+
# `Layout/IndentationStyle`, generally landing on a different column, so under
|
|
98
|
+
# tabs the target line's own indentation is reused. There is nothing to reuse
|
|
99
|
+
# when the target does not start its line.
|
|
100
|
+
def alignment_indentation(location)
|
|
101
|
+
return ' ' * location.column unless using_tabs?
|
|
102
|
+
return unless begins_its_line?(location)
|
|
103
|
+
|
|
104
|
+
location.source_line[/\A\s*/]
|
|
105
|
+
end
|
|
106
|
+
|
|
94
107
|
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength
|
|
95
108
|
def alignment_source(node, starting_loc)
|
|
96
109
|
ending_loc =
|
|
@@ -25,13 +25,17 @@ module RuboCop
|
|
|
25
25
|
|
|
26
26
|
MSG = 'Put method call on a separate line if chained to a single line block.'
|
|
27
27
|
|
|
28
|
+
# These cops rewrite a method chained to the block in the same pass,
|
|
29
|
+
# which must not start a line of its own.
|
|
28
30
|
def self.autocorrect_incompatible_with
|
|
29
|
-
[Style::MapToHash]
|
|
31
|
+
[Style::FloatDivision, Style::MapToHash, Style::NilComparison, Style::RedundantSort]
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def on_send(node)
|
|
33
35
|
range = offending_range(node)
|
|
34
|
-
|
|
36
|
+
return if !range || heredoc_opened_before?(node.receiver, range)
|
|
37
|
+
|
|
38
|
+
add_offense(range) { |corrector| corrector.insert_before(range, "\n") }
|
|
35
39
|
end
|
|
36
40
|
alias on_csend on_send
|
|
37
41
|
|
|
@@ -63,6 +67,10 @@ module RuboCop
|
|
|
63
67
|
# l.(1) has no selector, so we use the opening parenthesis instead
|
|
64
68
|
node.loc.selector || node.loc.begin
|
|
65
69
|
end
|
|
70
|
+
|
|
71
|
+
def heredoc_opened_before?(receiver, range)
|
|
72
|
+
receiver.each_node(:any_str).any? { |str| str.heredoc? && str.first_line == range.line }
|
|
73
|
+
end
|
|
66
74
|
end
|
|
67
75
|
end
|
|
68
76
|
end
|
|
@@ -20,6 +20,7 @@ module RuboCop
|
|
|
20
20
|
|
|
21
21
|
def on_send(node)
|
|
22
22
|
return unless node.prefix_bang? && whitespace_after_operator?(node)
|
|
23
|
+
return if unary_tilde?(node.receiver)
|
|
23
24
|
|
|
24
25
|
add_offense(node) do |corrector|
|
|
25
26
|
corrector.remove(
|
|
@@ -33,6 +34,10 @@ module RuboCop
|
|
|
33
34
|
def whitespace_after_operator?(node)
|
|
34
35
|
node.receiver.source_range.begin_pos - node.source_range.begin_pos > 1
|
|
35
36
|
end
|
|
37
|
+
|
|
38
|
+
def unary_tilde?(receiver)
|
|
39
|
+
receiver.send_type? && receiver.unary_operation? && receiver.method?(:~)
|
|
40
|
+
end
|
|
36
41
|
end
|
|
37
42
|
end
|
|
38
43
|
end
|
|
@@ -6,7 +6,8 @@ module RuboCop
|
|
|
6
6
|
# Checks the spacing inside and after block parameters pipes. Line breaks
|
|
7
7
|
# inside parameter pipes are checked by `Layout/MultilineBlockLayout` and
|
|
8
8
|
# not by this cop. Spaces inside a lambda's parameter parentheses are left
|
|
9
|
-
# to `Layout/SpaceInsideParens` when that cop
|
|
9
|
+
# to `Layout/SpaceInsideParens` when that cop is enabled, so the examples
|
|
10
|
+
# below apply to a lambda only when it is not.
|
|
10
11
|
#
|
|
11
12
|
# @example EnforcedStyleInsidePipes: no_space (default)
|
|
12
13
|
# # bad
|
|
@@ -35,7 +36,7 @@ module RuboCop
|
|
|
35
36
|
|
|
36
37
|
return unless node.arguments? && pipes?(arguments)
|
|
37
38
|
|
|
38
|
-
check_inside_pipes(arguments) unless
|
|
39
|
+
check_inside_pipes(arguments) unless checked_by_space_inside_parens?(arguments)
|
|
39
40
|
check_after_closing_pipe(arguments) if node.body
|
|
40
41
|
check_each_arg(arguments)
|
|
41
42
|
end
|
|
@@ -54,14 +55,8 @@ module RuboCop
|
|
|
54
55
|
'EnforcedStyleInsidePipes'
|
|
55
56
|
end
|
|
56
57
|
|
|
57
|
-
def
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
case config.for_enabled_cop('Layout/SpaceInsideParens')['EnforcedStyle']
|
|
61
|
-
when 'no_space' then style == :space
|
|
62
|
-
when 'space', 'compact' then style == :no_space
|
|
63
|
-
else false
|
|
64
|
-
end
|
|
58
|
+
def checked_by_space_inside_parens?(arguments)
|
|
59
|
+
arguments.loc.begin.source == '(' && config.cop_enabled?('Layout/SpaceInsideParens')
|
|
65
60
|
end
|
|
66
61
|
|
|
67
62
|
def check_inside_pipes(arguments)
|
|
@@ -153,7 +148,7 @@ module RuboCop
|
|
|
153
148
|
if node
|
|
154
149
|
corrector.insert_before(node, ' ')
|
|
155
150
|
else
|
|
156
|
-
corrector.insert_after(
|
|
151
|
+
corrector.insert_after(range_between(space_begin_pos, space_begin_pos), ' ')
|
|
157
152
|
end
|
|
158
153
|
end
|
|
159
154
|
end
|
|
@@ -209,6 +209,7 @@ module RuboCop
|
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
return unless space_after_missing?(range)
|
|
212
|
+
return if block_brace_with_no_space_style?(node, range)
|
|
212
213
|
|
|
213
214
|
add_offense(range, message: format(MSG_AFTER, range: range.source)) do |corrector|
|
|
214
215
|
corrector.insert_after(range, ' ')
|
|
@@ -233,6 +234,15 @@ module RuboCop
|
|
|
233
234
|
!/[\s;,#\\)}\].]/.match?(char)
|
|
234
235
|
end
|
|
235
236
|
|
|
237
|
+
def block_brace_with_no_space_style?(node, range)
|
|
238
|
+
return false unless (parent = node.parent)
|
|
239
|
+
return false unless parent.any_block_type? && parent.loc.begin&.begin_pos == range.end_pos
|
|
240
|
+
|
|
241
|
+
space_before_block_braces_config = config.for_cop('Layout/SpaceBeforeBlockBraces')
|
|
242
|
+
space_before_block_braces_config.fetch('Enabled', true) &&
|
|
243
|
+
space_before_block_braces_config['EnforcedStyle'] == 'no_space'
|
|
244
|
+
end
|
|
245
|
+
|
|
236
246
|
def accepted_opening_delimiter?(range, char)
|
|
237
247
|
return true unless char
|
|
238
248
|
|
|
@@ -49,8 +49,11 @@ module RuboCop
|
|
|
49
49
|
MISSING_MSG = 'Space missing to the left of {.'
|
|
50
50
|
DETECTED_MSG = 'Space detected to the left of {.'
|
|
51
51
|
|
|
52
|
+
# `Style/BlockDelimiters` decides whether to put a space before the `do`
|
|
53
|
+
# it writes by looking at the source before this cop removed the space,
|
|
54
|
+
# so the two corrections cannot be applied in the same pass.
|
|
52
55
|
def self.autocorrect_incompatible_with
|
|
53
|
-
[Style::SymbolProc]
|
|
56
|
+
[Style::BlockDelimiters, Style::SymbolProc]
|
|
54
57
|
end
|
|
55
58
|
|
|
56
59
|
def on_block(node)
|
|
@@ -117,7 +117,7 @@ module RuboCop
|
|
|
117
117
|
elsif style == :space
|
|
118
118
|
SpaceCorrector.add_space(processed_source, corrector, left, right)
|
|
119
119
|
else
|
|
120
|
-
compact_corrections(corrector, tokens, left, right)
|
|
120
|
+
compact_corrections(corrector, node, tokens, left, right)
|
|
121
121
|
end
|
|
122
122
|
end
|
|
123
123
|
|
|
@@ -178,6 +178,8 @@ module RuboCop
|
|
|
178
178
|
space_offenses(node, left, nil, MSG, start_ok: start_ok, end_ok: true)
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
+
return if closing_bracket_kept_apart?(node, tokens, left, right)
|
|
182
|
+
|
|
181
183
|
if qualifies_for_compact?(tokens, right)
|
|
182
184
|
compact_offense(node, right)
|
|
183
185
|
elsif !multi_dimensional_array?(tokens, right)
|
|
@@ -212,13 +214,24 @@ module RuboCop
|
|
|
212
214
|
end
|
|
213
215
|
end
|
|
214
216
|
|
|
215
|
-
|
|
217
|
+
# A closing bracket on its own line is only collapsed when the opening
|
|
218
|
+
# bracket ends up on the first element's line, so that the brackets
|
|
219
|
+
# stay symmetrical (see `Layout/MultilineArrayBraceLayout`).
|
|
220
|
+
def closing_bracket_kept_apart?(node, tokens, left, right)
|
|
221
|
+
end_has_own_line?(right) &&
|
|
222
|
+
!multi_dimensional_array?(tokens, left, side: :left) &&
|
|
223
|
+
!same_line?(left, node.children.first)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def compact_corrections(corrector, node, tokens, left, right)
|
|
216
227
|
if multi_dimensional_array?(tokens, left, side: :left)
|
|
217
228
|
compact(corrector, left, :right)
|
|
218
229
|
elsif !left.space_after?
|
|
219
230
|
corrector.insert_after(left.pos, ' ')
|
|
220
231
|
end
|
|
221
232
|
|
|
233
|
+
return if closing_bracket_kept_apart?(node, tokens, left, right)
|
|
234
|
+
|
|
222
235
|
if multi_dimensional_array?(tokens, right)
|
|
223
236
|
compact(corrector, right, :left)
|
|
224
237
|
elsif !right.space_before?
|
|
@@ -153,7 +153,7 @@ module RuboCop
|
|
|
153
153
|
else
|
|
154
154
|
column = node.source_range.column
|
|
155
155
|
return if multiline_block?(left_brace, right_brace) &&
|
|
156
|
-
aligned_braces?(inner, right_brace, column)
|
|
156
|
+
aligned_braces?(inner, right_brace, column, left_brace)
|
|
157
157
|
|
|
158
158
|
space_inside_right_brace(inner, right_brace, column)
|
|
159
159
|
end
|
|
@@ -163,14 +163,21 @@ module RuboCop
|
|
|
163
163
|
left_brace.first_line != right_brace.first_line
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
-
def aligned_braces?(inner, right_brace, column)
|
|
167
|
-
column == right_brace.column ||
|
|
166
|
+
def aligned_braces?(inner, right_brace, column, left_brace)
|
|
167
|
+
column == right_brace.column ||
|
|
168
|
+
column == inner_last_space_count(inner) ||
|
|
169
|
+
aligned_with_opening_brace_line?(left_brace, right_brace)
|
|
168
170
|
end
|
|
169
171
|
|
|
170
172
|
def inner_last_space_count(inner)
|
|
171
173
|
inner.split("\n").last.count(' ')
|
|
172
174
|
end
|
|
173
175
|
|
|
176
|
+
def aligned_with_opening_brace_line?(left_brace, right_brace)
|
|
177
|
+
begins_its_line?(right_brace) &&
|
|
178
|
+
right_brace.column == left_brace.source_line[/\A\s*/].length
|
|
179
|
+
end
|
|
180
|
+
|
|
174
181
|
def no_space_inside_left_brace(left_brace, args_delimiter)
|
|
175
182
|
if pipe?(args_delimiter)
|
|
176
183
|
if left_brace.end_pos == args_delimiter.begin_pos &&
|
|
@@ -197,9 +204,7 @@ module RuboCop
|
|
|
197
204
|
'Space between { and | detected.')
|
|
198
205
|
end
|
|
199
206
|
else
|
|
200
|
-
|
|
201
|
-
space(brace_with_space.begin_pos + 1, brace_with_space.end_pos,
|
|
202
|
-
'Space inside { detected.')
|
|
207
|
+
space_after_left_brace(left_brace)
|
|
203
208
|
end
|
|
204
209
|
end
|
|
205
210
|
|
|
@@ -207,6 +212,20 @@ module RuboCop
|
|
|
207
212
|
args_delimiter&.is?('|')
|
|
208
213
|
end
|
|
209
214
|
|
|
215
|
+
def space_after_left_brace(left_brace)
|
|
216
|
+
brace_with_space = range_with_surrounding_space(left_brace, side: :right)
|
|
217
|
+
return if brace_with_space.source.match?(/\R/)
|
|
218
|
+
return if comment_at?(brace_with_space.end_pos)
|
|
219
|
+
|
|
220
|
+
space(
|
|
221
|
+
brace_with_space.begin_pos + 1, brace_with_space.end_pos, 'Space inside { detected.'
|
|
222
|
+
)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def comment_at?(pos)
|
|
226
|
+
processed_source.comments.any? { |comment| comment.source_range.begin_pos == pos }
|
|
227
|
+
end
|
|
228
|
+
|
|
210
229
|
def space_inside_right_brace(inner, right_brace, column)
|
|
211
230
|
brace_with_space = range_with_surrounding_space(right_brace, side: :left)
|
|
212
231
|
begin_pos = brace_with_space.begin_pos
|
|
@@ -216,7 +235,7 @@ module RuboCop
|
|
|
216
235
|
begin_pos = end_pos - (right_brace.column - column)
|
|
217
236
|
end
|
|
218
237
|
|
|
219
|
-
if
|
|
238
|
+
if closing_bracket_on_own_line?(inner)
|
|
220
239
|
end_pos -= 1
|
|
221
240
|
begin_pos = end_pos - (inner_last_space_count(inner) - column)
|
|
222
241
|
end
|
|
@@ -224,6 +243,10 @@ module RuboCop
|
|
|
224
243
|
space(begin_pos, end_pos, 'Space inside } detected.')
|
|
225
244
|
end
|
|
226
245
|
|
|
246
|
+
def closing_bracket_on_own_line?(inner)
|
|
247
|
+
inner[/[^\n]*\z/].match?(/\A\s*\]\z/)
|
|
248
|
+
end
|
|
249
|
+
|
|
227
250
|
def no_space(begin_pos, end_pos, msg)
|
|
228
251
|
if style == :space
|
|
229
252
|
offense(begin_pos, end_pos, msg)
|
|
@@ -241,7 +264,7 @@ module RuboCop
|
|
|
241
264
|
end
|
|
242
265
|
|
|
243
266
|
def offense(begin_pos, end_pos, msg, style_param = 'EnforcedStyle')
|
|
244
|
-
return if begin_pos
|
|
267
|
+
return if begin_pos >= end_pos
|
|
245
268
|
|
|
246
269
|
range = range_between(begin_pos, end_pos)
|
|
247
270
|
add_offense(range, message: msg) do |corrector|
|
|
@@ -108,14 +108,9 @@ module RuboCop
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def left_ref_bracket(node, tokens)
|
|
111
|
-
|
|
112
|
-
previous_token = previous_token(current_token)
|
|
111
|
+
bracket_pos = node.loc.selector.begin_pos
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
tokens.find(&:left_ref_bracket?)
|
|
116
|
-
else
|
|
117
|
-
current_token
|
|
118
|
-
end
|
|
113
|
+
tokens.find { |token| token.left_ref_bracket? && token.begin_pos == bracket_pos }
|
|
119
114
|
end
|
|
120
115
|
|
|
121
116
|
def closing_bracket(tokens, opening_bracket)
|
|
@@ -129,11 +124,6 @@ module RuboCop
|
|
|
129
124
|
end
|
|
130
125
|
end
|
|
131
126
|
|
|
132
|
-
def previous_token(current_token)
|
|
133
|
-
index = processed_source.tokens.index(current_token)
|
|
134
|
-
index.nil? || index.zero? ? nil : processed_source.tokens[index - 1]
|
|
135
|
-
end
|
|
136
|
-
|
|
137
127
|
def empty_config
|
|
138
128
|
cop_config['EnforcedStyleForEmptyBrackets']
|
|
139
129
|
end
|
|
@@ -56,7 +56,8 @@ module RuboCop
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def on_send(node)
|
|
59
|
-
|
|
59
|
+
# `foo.*` is a regular method call, not a binary operator.
|
|
60
|
+
return if node.parenthesized? || node.loc.dot
|
|
60
61
|
|
|
61
62
|
return unless (parent = node.parent)
|
|
62
63
|
return unless operator?(parent)
|
|
@@ -55,7 +55,8 @@ module RuboCop
|
|
|
55
55
|
return node if first_argument_is_regexp?(node) || !node.parent
|
|
56
56
|
|
|
57
57
|
if (node.parent.send_type? && node.receiver) ||
|
|
58
|
-
method_chain_to_regexp_receiver?(node, regexp_receiver)
|
|
58
|
+
method_chain_to_regexp_receiver?(node, regexp_receiver) ||
|
|
59
|
+
part_of_hash_argument?(node)
|
|
59
60
|
node = find_offense_node(node.parent, regexp_receiver)
|
|
60
61
|
end
|
|
61
62
|
|
|
@@ -72,6 +73,10 @@ module RuboCop
|
|
|
72
73
|
|
|
73
74
|
parent.parent && parent_receiver.receiver == regexp_receiver
|
|
74
75
|
end
|
|
76
|
+
|
|
77
|
+
def part_of_hash_argument?(node)
|
|
78
|
+
node.pair_type? || node.parent.pair_type? || (node.hash_type? && !node.braces?)
|
|
79
|
+
end
|
|
75
80
|
end
|
|
76
81
|
end
|
|
77
82
|
end
|
|
@@ -97,12 +97,14 @@ module RuboCop
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def can_simplify_conditional?(node)
|
|
100
|
-
node.else_branch && node.loc.else.source == 'else'
|
|
100
|
+
!node.elsif? && node.else_branch && node.loc.else.source == 'else'
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
def remove_empty_branch(corrector, node)
|
|
104
104
|
range = if empty_if_branch?(node) && else_branch?(node)
|
|
105
105
|
branch_range(node)
|
|
106
|
+
elsif node.condition.last_line == node.loc.else.line
|
|
107
|
+
node.source_range.with(end_pos: node.loc.else.begin_pos)
|
|
106
108
|
else
|
|
107
109
|
deletion_range(branch_range(node))
|
|
108
110
|
end
|
|
@@ -34,6 +34,10 @@ module RuboCop
|
|
|
34
34
|
|
|
35
35
|
MSG = 'Put a method call with a HEREDOC receiver on the same line as the HEREDOC opening.'
|
|
36
36
|
|
|
37
|
+
def self.autocorrect_incompatible_with
|
|
38
|
+
[Style::MethodCallWithArgsParentheses]
|
|
39
|
+
end
|
|
40
|
+
|
|
37
41
|
def on_send(node)
|
|
38
42
|
heredoc = heredoc_node_descendent_receiver(node)
|
|
39
43
|
return unless heredoc
|
|
@@ -98,6 +98,8 @@ module RuboCop
|
|
|
98
98
|
end
|
|
99
99
|
elsif node.condition.falsey_literal?
|
|
100
100
|
add_offense(node.condition) do |corrector|
|
|
101
|
+
next if orphans_loop_control_keyword?(node)
|
|
102
|
+
|
|
101
103
|
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
|
102
104
|
end
|
|
103
105
|
end
|
|
@@ -127,6 +129,8 @@ module RuboCop
|
|
|
127
129
|
end
|
|
128
130
|
elsif node.condition.truthy_literal?
|
|
129
131
|
add_offense(node.condition) do |corrector|
|
|
132
|
+
next if orphans_loop_control_keyword?(node)
|
|
133
|
+
|
|
130
134
|
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
|
131
135
|
end
|
|
132
136
|
end
|
|
@@ -175,6 +179,15 @@ module RuboCop
|
|
|
175
179
|
|
|
176
180
|
private
|
|
177
181
|
|
|
182
|
+
# Unwrapping the body of a loop that runs once would leave a `break`,
|
|
183
|
+
# `next` or `redo` that belongs to it outside of any loop.
|
|
184
|
+
def orphans_loop_control_keyword?(node)
|
|
185
|
+
node.body.each_node(:next, :break, :redo).any? do |control|
|
|
186
|
+
inner = control.each_ancestor.take_while { |ancestor| !ancestor.equal?(node) }
|
|
187
|
+
inner.none? { |ancestor| ancestor.any_block_type? || ancestor.loop_keyword? }
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
178
191
|
def void_value_expression?(node)
|
|
179
192
|
node = node.children.last while node&.begin_type?
|
|
180
193
|
|
|
@@ -273,6 +286,8 @@ module RuboCop
|
|
|
273
286
|
"#{node.else_branch.source.sub('elsif', 'if')}\nend"
|
|
274
287
|
elsif node.else? || node.ternary?
|
|
275
288
|
node.else_branch.source
|
|
289
|
+
elsif node.value_used?
|
|
290
|
+
'nil'
|
|
276
291
|
else
|
|
277
292
|
'' # Equivalent to removing the node
|
|
278
293
|
end
|