rubocop 1.91.0 → 1.92.2
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.rb +0 -4
- 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_obsoletion.rb +9 -0
- 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_after_module_inclusion.rb +1 -1
- 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 +21 -25
- data/lib/rubocop/cop/layout/extra_spacing.rb +21 -6
- 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 +176 -26
- 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 +16 -3
- 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_around_operators.rb +31 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +16 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +15 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +32 -9
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +29 -11
- 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/interpolation_check.rb +20 -17
- 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/nested_percent_literal.rb +3 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +3 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +22 -1
- data/lib/rubocop/cop/lint/percent_string_array.rb +75 -9
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +39 -9
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +13 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +11 -4
- 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/comments_help.rb +1 -1
- 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 +41 -6
- 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 +39 -5
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- 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 +37 -10
- 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_equality.rb +14 -3
- data/lib/rubocop/cop/style/case_like_if.rb +6 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +57 -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 +104 -11
- 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 +37 -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 +42 -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 +26 -2
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +26 -3
- data/lib/rubocop/cop/style/method_def_parentheses.rb +38 -4
- 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 +28 -5
- data/lib/rubocop/cop/style/one_line_conditional.rb +13 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +19 -1
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +14 -3
- data/lib/rubocop/cop/style/quoted_symbols.rb +5 -7
- data/lib/rubocop/cop/style/raise_args.rb +80 -11
- data/lib/rubocop/cop/style/reduce_to_hash.rb +47 -33
- data/lib/rubocop/cop/style/redundant_begin.rb +45 -5
- 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 +27 -11
- 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.rb +9 -1
- 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 +42 -4
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +29 -5
- data/lib/rubocop/cop/style/string_concatenation.rb +21 -4
- 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 +36 -8
- data/lib/rubocop/remote_config.rb +4 -1
- data/lib/rubocop/result_cache.rb +20 -13
- data/lib/rubocop/runner.rb +110 -42
- 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
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
# Common functionality for checking whether a node is used in a pattern of
|
|
6
|
+
# pattern matching, where only some expressions are allowed.
|
|
7
|
+
module PatternMatchingHelp
|
|
8
|
+
PATTERN_TYPES = %i[
|
|
9
|
+
array_pattern array_pattern_with_tail begin const_pattern find_pattern hash_pattern
|
|
10
|
+
match_alt match_as pair
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def in_pattern?(node)
|
|
16
|
+
child = node
|
|
17
|
+
|
|
18
|
+
node.each_ancestor do |ancestor|
|
|
19
|
+
case ancestor.type
|
|
20
|
+
when :in_pattern
|
|
21
|
+
return ancestor.pattern.equal?(child)
|
|
22
|
+
when :match_pattern, :match_pattern_p
|
|
23
|
+
return ancestor.children[1].equal?(child)
|
|
24
|
+
when *PATTERN_TYPES
|
|
25
|
+
child = ancestor
|
|
26
|
+
else
|
|
27
|
+
return false
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -174,8 +174,13 @@ module RuboCop
|
|
|
174
174
|
# ^
|
|
175
175
|
tokens = remove_equals_in_def(tokens, processed_source)
|
|
176
176
|
|
|
177
|
-
# Only attempt to align the first = on each line
|
|
178
|
-
|
|
177
|
+
# Only attempt to align the first = on each line. An `=` that comes after a comparison
|
|
178
|
+
# on its line is left out as well: whether a line is aligned is judged by its first
|
|
179
|
+
# assignment or comparison operator, so such an `=` could never be found aligned
|
|
180
|
+
# and `Layout/SpaceAroundOperators` would keep undoing the padding added for it.
|
|
181
|
+
Set.new(tokens.uniq(&:line).select do |token|
|
|
182
|
+
first_operator_on_line(token.line).equal?(token)
|
|
183
|
+
end)
|
|
179
184
|
end
|
|
180
185
|
end
|
|
181
186
|
|
|
@@ -270,6 +275,16 @@ module RuboCop
|
|
|
270
275
|
|
|
271
276
|
asgn_tokens.reject { |t| eqls_to_ignore.include?(t.begin_pos) }
|
|
272
277
|
end
|
|
278
|
+
|
|
279
|
+
def first_operator_on_line(line)
|
|
280
|
+
@first_operator_by_line ||= processed_source.tokens.each_with_object({}) do |token, by_line|
|
|
281
|
+
next unless ASSIGNMENT_OR_COMPARISON_TOKENS.include?(token.type)
|
|
282
|
+
|
|
283
|
+
by_line[token.line] ||= token
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
@first_operator_by_line[line]
|
|
287
|
+
end
|
|
273
288
|
end
|
|
274
289
|
end
|
|
275
290
|
end
|
|
@@ -119,6 +119,21 @@ module RuboCop
|
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
+
# Whether the `def`/`defs` node overrides a method defined by an ancestor
|
|
123
|
+
# of its enclosing class or module elsewhere in the project.
|
|
124
|
+
def overrides_inherited_method?(def_node)
|
|
125
|
+
return false unless project_index
|
|
126
|
+
return false unless (namespace_node = def_node.each_ancestor(:class, :module).first)
|
|
127
|
+
|
|
128
|
+
declaration = resolve_constant_in_index(namespace_node.identifier)
|
|
129
|
+
return false unless declaration.is_a?(Rubydex::Namespace)
|
|
130
|
+
|
|
131
|
+
scope = def_node.defs_type? ? indexed_singleton_of(declaration) : declaration
|
|
132
|
+
!scope.nil? && inherited_index_member?(scope, "#{def_node.method_name}()")
|
|
133
|
+
rescue StandardError
|
|
134
|
+
false
|
|
135
|
+
end
|
|
136
|
+
|
|
122
137
|
# Whether every link of the declaration's ancestry is resolved in the
|
|
123
138
|
# index: no definition of any ancestor has an unresolved superclass or
|
|
124
139
|
# mixin reference. Unresolved links silently vanish from `ancestors`,
|
|
@@ -51,15 +51,25 @@ module RuboCop
|
|
|
51
51
|
# regardless of size (for cops where verification is the offense logic).
|
|
52
52
|
def verified_by_reparse(items, oversized: :report)
|
|
53
53
|
scope_groups(items).flat_map do |scope, group|
|
|
54
|
-
if
|
|
55
|
-
(group.size > 1 && corrections_verify?(scope, group))
|
|
54
|
+
if oversized == :report && verification_too_large?(scope)
|
|
56
55
|
group
|
|
57
56
|
else
|
|
58
|
-
|
|
57
|
+
verified_subset(scope, group)
|
|
59
58
|
end
|
|
60
59
|
end
|
|
61
60
|
end
|
|
62
61
|
|
|
62
|
+
# Verifies a group with a single reparse and bisects it when that fails,
|
|
63
|
+
# so a few significant items among many cost a logarithmic number of
|
|
64
|
+
# reparses rather than one each.
|
|
65
|
+
def verified_subset(scope, group)
|
|
66
|
+
return group if corrections_verify?(scope, group)
|
|
67
|
+
return [] if group.one?
|
|
68
|
+
|
|
69
|
+
half = group.size / 2
|
|
70
|
+
verified_subset(scope, group.take(half)) + verified_subset(scope, group.drop(half))
|
|
71
|
+
end
|
|
72
|
+
|
|
63
73
|
# Whether the exact correction for `item` produces source that still
|
|
64
74
|
# parses, without requiring an equivalent AST. For corrections that
|
|
65
75
|
# intentionally change the tree.
|
|
@@ -7,6 +7,8 @@ module RuboCop
|
|
|
7
7
|
include LineLengthHelp
|
|
8
8
|
include AllowedPattern
|
|
9
9
|
|
|
10
|
+
SPACE_INSIDE_PARENS_STYLES = %w[space compact].freeze
|
|
11
|
+
|
|
10
12
|
private
|
|
11
13
|
|
|
12
14
|
def single_line_as_modifier?(node)
|
|
@@ -42,7 +44,10 @@ module RuboCop
|
|
|
42
44
|
def modifier_fits_on_single_line?(node)
|
|
43
45
|
return true unless max_line_length
|
|
44
46
|
|
|
45
|
-
line_length(line_in_modifier_form(node))
|
|
47
|
+
length = line_length(line_in_modifier_form(node))
|
|
48
|
+
length += 2 if parenthesize?(node) && space_inside_parens?
|
|
49
|
+
|
|
50
|
+
length <= max_line_length
|
|
46
51
|
end
|
|
47
52
|
|
|
48
53
|
def line_in_modifier_form(node)
|
|
@@ -52,6 +57,14 @@ module RuboCop
|
|
|
52
57
|
"#{code_before}#{to_modifier_form(node)}#{code_after(node)}"
|
|
53
58
|
end
|
|
54
59
|
|
|
60
|
+
def space_inside_parens?
|
|
61
|
+
return false unless config.cop_enabled?('Layout/SpaceInsideParens')
|
|
62
|
+
|
|
63
|
+
style = config.for_cop('Layout/SpaceInsideParens')['EnforcedStyle']
|
|
64
|
+
|
|
65
|
+
SPACE_INSIDE_PARENS_STYLES.include?(style)
|
|
66
|
+
end
|
|
67
|
+
|
|
55
68
|
# Whether an existing line is acceptable to `Layout/LineLength`,
|
|
56
69
|
# exemptions (the cop disabled at that line, an allowed pattern, an
|
|
57
70
|
# allowed cop directive, an allowed URI) included. Only for judging
|
|
@@ -96,15 +109,22 @@ module RuboCop
|
|
|
96
109
|
[parenthesized, first_line_comment(node)].compact.join(' ')
|
|
97
110
|
end
|
|
98
111
|
|
|
112
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
99
113
|
def if_body_source(if_body)
|
|
100
|
-
if
|
|
114
|
+
if unparenthesized_call_with_omitted_value?(if_body)
|
|
101
115
|
"#{method_source(if_body)}(#{if_body.arguments.map(&:source).join(', ')})"
|
|
116
|
+
elsif (value = wrapped_value(if_body))
|
|
117
|
+
prefix = if_body.source_range.begin.join(value.source_range.begin).source
|
|
118
|
+
suffix = value.source_range.end.join(if_body.source_range.end).source
|
|
119
|
+
|
|
120
|
+
"#{prefix}#{if_body_source(value)}#{suffix}"
|
|
102
121
|
else
|
|
103
122
|
if_body.source
|
|
104
123
|
end
|
|
105
124
|
end
|
|
106
125
|
|
|
107
|
-
def
|
|
126
|
+
def unparenthesized_call_with_omitted_value?(if_body)
|
|
127
|
+
return false if !if_body.call_type? || if_body.method?(:[]=) || if_body.parenthesized?
|
|
108
128
|
return false unless (last_argument = if_body.last_argument)
|
|
109
129
|
|
|
110
130
|
last_argument.hash_type? && last_argument.pairs.last&.value_omission?
|
|
@@ -116,6 +136,14 @@ module RuboCop
|
|
|
116
136
|
if_body.source_range.begin.join(end_range).source
|
|
117
137
|
end
|
|
118
138
|
|
|
139
|
+
def wrapped_value(if_body)
|
|
140
|
+
if if_body.type?(:return, :next, :break)
|
|
141
|
+
if_body.first_argument if if_body.arguments.one?
|
|
142
|
+
elsif if_body.type?(:lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn)
|
|
143
|
+
if_body.expression
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
119
147
|
def first_line_comment(node)
|
|
120
148
|
comment = processed_source.comment_at_line(node.first_line)
|
|
121
149
|
return unless comment
|
|
@@ -137,9 +165,15 @@ module RuboCop
|
|
|
137
165
|
parent = node.parent
|
|
138
166
|
return false if parent.nil?
|
|
139
167
|
return true if parent.assignment? || parent.operator_keyword?
|
|
140
|
-
return true if
|
|
168
|
+
return true if parent.type?(:array, :pair, :call, :yield, :super)
|
|
169
|
+
|
|
170
|
+
ternary_branch_or_endless_method_body?(parent)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def ternary_branch_or_endless_method_body?(parent)
|
|
174
|
+
return parent.ternary? if parent.if_type?
|
|
141
175
|
|
|
142
|
-
|
|
176
|
+
parent.any_def_type? && parent.endless?
|
|
143
177
|
end
|
|
144
178
|
|
|
145
179
|
def comment_disables_cop?(comment)
|
|
@@ -163,7 +163,7 @@ module RuboCop
|
|
|
163
163
|
|
|
164
164
|
def put_comma(items, kind)
|
|
165
165
|
last_item = items.last
|
|
166
|
-
return if last_item.
|
|
166
|
+
return if last_item.type?(:block_pass, :forwarded_args)
|
|
167
167
|
|
|
168
168
|
range = autocorrect_range(last_item)
|
|
169
169
|
msg = format(MSG, command: 'Put a', unit: format(kind, article: 'a multiline'))
|
|
@@ -63,9 +63,10 @@ module RuboCop
|
|
|
63
63
|
(send nil? VISIBILITY_SCOPES def)
|
|
64
64
|
PATTERN
|
|
65
65
|
|
|
66
|
+
# A modifier applies to every symbol it is given, not only to a sole argument.
|
|
66
67
|
# @!method visibility_inline_on_method_name?(node, method_name:)
|
|
67
68
|
def_node_matcher :visibility_inline_on_method_name?, <<~PATTERN
|
|
68
|
-
(send nil? VISIBILITY_SCOPES (sym %method_name))
|
|
69
|
+
(send nil? VISIBILITY_SCOPES <(sym %method_name) ...>)
|
|
69
70
|
PATTERN
|
|
70
71
|
end
|
|
71
72
|
end
|
data/lib/rubocop/cop/mixin.rb
CHANGED
|
@@ -32,6 +32,7 @@ module RuboCop
|
|
|
32
32
|
autoload :AnnotationComment, "#{__dir__}/mixin/annotation_comment"
|
|
33
33
|
autoload :EmptyParameter, "#{__dir__}/mixin/empty_parameter"
|
|
34
34
|
autoload :EndKeywordAlignment, "#{__dir__}/mixin/end_keyword_alignment"
|
|
35
|
+
autoload :EndlessMethodBodyHelp, "#{__dir__}/mixin/endless_method_body_help"
|
|
35
36
|
autoload :EndlessMethodRewriter, "#{__dir__}/mixin/endless_method_rewriter"
|
|
36
37
|
autoload :EnforceSuperclass, "#{__dir__}/mixin/enforce_superclass"
|
|
37
38
|
autoload :FirstElementLineBreak, "#{__dir__}/mixin/first_element_line_break"
|
|
@@ -64,6 +65,7 @@ module RuboCop
|
|
|
64
65
|
autoload :OnNormalIfUnless, "#{__dir__}/mixin/on_normal_if_unless"
|
|
65
66
|
autoload :OrderedGemNode, "#{__dir__}/mixin/ordered_gem_node"
|
|
66
67
|
autoload :Parentheses, "#{__dir__}/mixin/parentheses"
|
|
68
|
+
autoload :PatternMatchingHelp, "#{__dir__}/mixin/pattern_matching_help"
|
|
67
69
|
autoload :PercentArray, "#{__dir__}/mixin/percent_array"
|
|
68
70
|
autoload :PercentLiteral, "#{__dir__}/mixin/percent_literal"
|
|
69
71
|
autoload :PrecedingFollowingAlignment, "#{__dir__}/mixin/preceding_following_alignment"
|
|
@@ -80,22 +80,6 @@ module RuboCop
|
|
|
80
80
|
node.arguments.one? &&
|
|
81
81
|
node.first_argument.arg_type?
|
|
82
82
|
end
|
|
83
|
-
|
|
84
|
-
# When `AllCops/UseProjectIndex` is enabled, methods that override a
|
|
85
|
-
# method defined by an ancestor elsewhere in the project are not
|
|
86
|
-
# reported: renaming an override breaks the inherited contract.
|
|
87
|
-
def overrides_inherited_method?(node)
|
|
88
|
-
return false unless project_index
|
|
89
|
-
return false unless (namespace_node = node.each_ancestor(:class, :module).first)
|
|
90
|
-
|
|
91
|
-
declaration = resolve_constant_in_index(namespace_node.identifier)
|
|
92
|
-
return false unless declaration.is_a?(Rubydex::Namespace)
|
|
93
|
-
|
|
94
|
-
scope = node.defs_type? ? indexed_singleton_of(declaration) : declaration
|
|
95
|
-
!scope.nil? && inherited_index_member?(scope, "#{node.method_name}()")
|
|
96
|
-
rescue StandardError
|
|
97
|
-
false
|
|
98
|
-
end
|
|
99
83
|
end
|
|
100
84
|
end
|
|
101
85
|
end
|
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
|
63
63
|
|
|
64
64
|
def self.autocorrect_incompatible_with
|
|
65
65
|
[
|
|
66
|
-
Lint::AmbiguousOperator, Style::ArgumentsForwarding,
|
|
66
|
+
Lint::AmbiguousOperator, Style::ArgumentsForwarding, Style::EndlessMethod,
|
|
67
67
|
Style::ExplicitBlockArgument, Style::MethodDefParentheses
|
|
68
68
|
]
|
|
69
69
|
end
|
|
@@ -35,7 +35,7 @@ module RuboCop
|
|
|
35
35
|
MSG = 'Use %<style>s heredoc delimiters.'
|
|
36
36
|
|
|
37
37
|
def on_heredoc(node)
|
|
38
|
-
return if correct_case_delimiters?(node)
|
|
38
|
+
return if correct_case_delimiters?(node) || corrected_delimiter_in_body?(node)
|
|
39
39
|
|
|
40
40
|
add_offense(node.loc.heredoc_end) do |corrector|
|
|
41
41
|
expr = node.source_range
|
|
@@ -52,7 +52,14 @@ module RuboCop
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def correct_case_delimiters?(node)
|
|
55
|
-
|
|
55
|
+
delimiters = delimiter_string(node)
|
|
56
|
+
delimiters == correct_delimiters(delimiters)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def corrected_delimiter_in_body?(node)
|
|
60
|
+
corrected = correct_delimiters(delimiter_string(node))
|
|
61
|
+
|
|
62
|
+
node.loc.heredoc_body.source.each_line.any? { |line| line.strip == corrected }
|
|
56
63
|
end
|
|
57
64
|
|
|
58
65
|
def correct_delimiters(source)
|
|
@@ -43,9 +43,11 @@ module RuboCop
|
|
|
43
43
|
|
|
44
44
|
return false unless /\w/.match?(delimiters)
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
forbidden_delimiter_regexps.none? { |regexp| regexp.match?(delimiters) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def forbidden_delimiter_regexps
|
|
50
|
+
@forbidden_delimiter_regexps ||= forbidden_delimiters.map { |d| Regexp.new(d) }
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
def forbidden_delimiters
|
|
@@ -142,12 +142,6 @@ module RuboCop
|
|
|
142
142
|
end
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
def offending_prefixes_for(node, method_name)
|
|
146
|
-
predicate_prefixes.reject do |prefix|
|
|
147
|
-
allowed_method_name?(method_name, prefix) ||
|
|
148
|
-
(use_sorbet_sigs? && !sorbet_sig?(node, return_type: 'T::Boolean'))
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
145
|
alias on_defs on_def
|
|
152
146
|
|
|
153
147
|
def validate_config
|
|
@@ -162,6 +156,13 @@ module RuboCop
|
|
|
162
156
|
|
|
163
157
|
private
|
|
164
158
|
|
|
159
|
+
def offending_prefixes_for(node, method_name)
|
|
160
|
+
prefixes = predicate_prefixes.reject { |p| allowed_method_name?(method_name, p) }
|
|
161
|
+
return prefixes if prefixes.empty? || !use_sorbet_sigs?
|
|
162
|
+
|
|
163
|
+
sorbet_sig?(node, return_type: 'T::Boolean') ? prefixes : []
|
|
164
|
+
end
|
|
165
|
+
|
|
165
166
|
# @!method sorbet_return_type(node)
|
|
166
167
|
def_node_matcher :sorbet_return_type, <<~PATTERN
|
|
167
168
|
(block (send nil? :sig) args (send _ :returns $_type))
|
|
@@ -210,22 +211,6 @@ module RuboCop
|
|
|
210
211
|
def method_definition_macro?(macro_name)
|
|
211
212
|
cop_config['MethodDefinitionMacros'].include?(macro_name.to_s)
|
|
212
213
|
end
|
|
213
|
-
|
|
214
|
-
# When `AllCops/UseProjectIndex` is enabled, methods that override a
|
|
215
|
-
# method defined by an ancestor elsewhere in the project are not
|
|
216
|
-
# reported: renaming an override breaks the inherited contract.
|
|
217
|
-
def overrides_inherited_method?(node)
|
|
218
|
-
return false unless project_index
|
|
219
|
-
return false unless (namespace_node = node.each_ancestor(:class, :module).first)
|
|
220
|
-
|
|
221
|
-
declaration = resolve_constant_in_index(namespace_node.identifier)
|
|
222
|
-
return false unless declaration.is_a?(Rubydex::Namespace)
|
|
223
|
-
|
|
224
|
-
scope = node.defs_type? ? indexed_singleton_of(declaration) : declaration
|
|
225
|
-
!scope.nil? && inherited_index_member?(scope, "#{node.method_name}()")
|
|
226
|
-
rescue StandardError
|
|
227
|
-
false
|
|
228
|
-
end
|
|
229
214
|
end
|
|
230
215
|
end
|
|
231
216
|
end
|
|
@@ -128,7 +128,7 @@ module RuboCop
|
|
|
128
128
|
if child_node.lvar_type?
|
|
129
129
|
parent_node = child_node.parent
|
|
130
130
|
if parent_node.respond_to?(:value_omission?) && parent_node.value_omission?
|
|
131
|
-
corrector.
|
|
131
|
+
corrector.replace(parent_node.loc.operator, ": #{preferred_name}")
|
|
132
132
|
else
|
|
133
133
|
corrector.replace(child_node, preferred_name)
|
|
134
134
|
end
|
data/lib/rubocop/cop/offense.rb
CHANGED
|
@@ -86,6 +86,9 @@ module RuboCop
|
|
|
86
86
|
|
|
87
87
|
NO_LOCATION = PseudoSourceRange.new(1, 0, '', 0, 0).freeze
|
|
88
88
|
|
|
89
|
+
EMPTY_CORRECTIONS = [].freeze
|
|
90
|
+
private_constant :EMPTY_CORRECTIONS
|
|
91
|
+
|
|
89
92
|
# @api public
|
|
90
93
|
#
|
|
91
94
|
# @!attribute [r] justification
|
|
@@ -96,9 +99,43 @@ module RuboCop
|
|
|
96
99
|
# or the directive carries no reason
|
|
97
100
|
attr_reader :justification
|
|
98
101
|
|
|
102
|
+
# @api public
|
|
103
|
+
#
|
|
104
|
+
# @!attribute [r] corrections
|
|
105
|
+
#
|
|
106
|
+
# @return [Array<Correction>]
|
|
107
|
+
# the individual edits that autocorrecting this offense would make, in
|
|
108
|
+
# source order. Empty when the offense has no correction. Unlike
|
|
109
|
+
# {#corrector}, this survives serialization, so it is available on a
|
|
110
|
+
# cache hit and in parallel runs.
|
|
111
|
+
attr_reader :corrections
|
|
112
|
+
|
|
113
|
+
# @api public
|
|
114
|
+
#
|
|
115
|
+
# @!attribute [r] correction_safe
|
|
116
|
+
#
|
|
117
|
+
# @return [Boolean]
|
|
118
|
+
# whether autocorrection would apply {#corrections} in a normal `-a`
|
|
119
|
+
# run. A cop marked `Safe: false` or `SafeAutoCorrect: false` still
|
|
120
|
+
# builds its correction, but only `-A` applies it, so a consumer that
|
|
121
|
+
# applies edits itself has to make the same distinction.
|
|
122
|
+
attr_reader :correction_safe
|
|
123
|
+
|
|
124
|
+
# A single edit of an autocorrection: the source range it replaces and
|
|
125
|
+
# the text it replaces it with. An insertion has an empty range, a
|
|
126
|
+
# removal an empty replacement.
|
|
127
|
+
#
|
|
128
|
+
# @api public
|
|
129
|
+
Correction = Struct.new(:begin_pos, :end_pos, :replacement) do
|
|
130
|
+
def length
|
|
131
|
+
end_pos - begin_pos
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
99
135
|
# @api private
|
|
100
136
|
def initialize(severity, location, message, cop_name, # rubocop:disable Metrics/ParameterLists
|
|
101
|
-
status = :uncorrected, corrector = nil, justification: nil
|
|
137
|
+
status = :uncorrected, corrector = nil, justification: nil,
|
|
138
|
+
corrections: nil, correction_safe: true)
|
|
102
139
|
@severity = RuboCop::Cop::Severity.new(severity)
|
|
103
140
|
@location = location
|
|
104
141
|
|
|
@@ -112,15 +149,21 @@ module RuboCop
|
|
|
112
149
|
@status = status
|
|
113
150
|
@corrector = corrector
|
|
114
151
|
@justification = justification.freeze
|
|
152
|
+
@corrections = (corrections || corrections_from(corrector)).freeze
|
|
153
|
+
@correction_safe = correction_safe
|
|
115
154
|
freeze
|
|
116
155
|
end
|
|
117
156
|
|
|
118
157
|
def marshal_dump
|
|
119
|
-
[@severity, @location, @message, @cop_name, @status, @justification
|
|
158
|
+
[@severity, @location, @message, @cop_name, @status, @justification, @corrections,
|
|
159
|
+
@correction_safe]
|
|
120
160
|
end
|
|
121
161
|
|
|
122
162
|
def marshal_load(array)
|
|
123
|
-
@severity, @location, @message, @cop_name, @status, @justification
|
|
163
|
+
@severity, @location, @message, @cop_name, @status, @justification, @corrections,
|
|
164
|
+
@correction_safe = array
|
|
165
|
+
@corrections ||= EMPTY_CORRECTIONS
|
|
166
|
+
@correction_safe = true if @correction_safe.nil?
|
|
124
167
|
@line = @location.line
|
|
125
168
|
@column = @location.column
|
|
126
169
|
end
|
|
@@ -276,6 +319,19 @@ module RuboCop
|
|
|
276
319
|
end
|
|
277
320
|
0
|
|
278
321
|
end
|
|
322
|
+
|
|
323
|
+
private
|
|
324
|
+
|
|
325
|
+
# Extracted eagerly rather than on demand because the offense is frozen,
|
|
326
|
+
# and because a corrector cannot be serialized - the cache and parallel
|
|
327
|
+
# workers would otherwise hand back offenses that have lost their edits.
|
|
328
|
+
def corrections_from(corrector)
|
|
329
|
+
return EMPTY_CORRECTIONS unless corrector
|
|
330
|
+
|
|
331
|
+
corrector.as_replacements.map do |range, replacement|
|
|
332
|
+
Correction.new(range.begin_pos, range.end_pos, replacement.freeze).freeze
|
|
333
|
+
end
|
|
334
|
+
end
|
|
279
335
|
end
|
|
280
336
|
end
|
|
281
337
|
end
|
data/lib/rubocop/cop/registry.rb
CHANGED
|
@@ -22,6 +22,13 @@ module RuboCop
|
|
|
22
22
|
# passing the `create_additions` keyword argument emits a deprecation warning, with the
|
|
23
23
|
# goal of being secure by default in the next major version 3.0.0.
|
|
24
24
|
#
|
|
25
|
+
# NOTE: Before `json` gem version 2.17.0, `JSON.load` only takes options as its third
|
|
26
|
+
# argument. A hash passed as the second argument is taken as the `proc` argument, so
|
|
27
|
+
# its `create_additions` option is ignored. Which `json` version runs can't be told
|
|
28
|
+
# statically (the lockfile may resolve a newer one than the default gem loaded in
|
|
29
|
+
# production), so options passed as the second argument are always reported. Pass
|
|
30
|
+
# `nil` as the second argument instead.
|
|
31
|
+
#
|
|
25
32
|
# @safety
|
|
26
33
|
# This cop's autocorrection is unsafe because it's potentially dangerous.
|
|
27
34
|
# If using a stream, like `JSON.load(open('file'))`, you will need to call
|
|
@@ -33,13 +40,16 @@ module RuboCop
|
|
|
33
40
|
# JSON.load('{}')
|
|
34
41
|
# JSON.restore('{}')
|
|
35
42
|
#
|
|
43
|
+
# # bad - ignored by `json` older than 2.17.0
|
|
44
|
+
# JSON.load('{}', create_additions: false)
|
|
45
|
+
#
|
|
36
46
|
# # good
|
|
37
47
|
# JSON.parse('{}')
|
|
38
48
|
# JSON.unsafe_load('{}')
|
|
39
49
|
#
|
|
40
50
|
# # good - explicit use of `create_additions` option
|
|
41
|
-
# JSON.load('{}', create_additions: true)
|
|
42
|
-
# JSON.load('{}', create_additions: false)
|
|
51
|
+
# JSON.load('{}', nil, create_additions: true)
|
|
52
|
+
# JSON.load('{}', nil, create_additions: false)
|
|
43
53
|
#
|
|
44
54
|
class JSONLoad < Base
|
|
45
55
|
extend AutoCorrector
|
|
@@ -51,8 +61,10 @@ module RuboCop
|
|
|
51
61
|
def_node_matcher :insecure_json_load, <<~PATTERN
|
|
52
62
|
(
|
|
53
63
|
send (const {nil? cbase} :JSON) ${:load :restore}
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
{
|
|
65
|
+
_ hash
|
|
66
|
+
| ... !`(pair (sym :create_additions) _)
|
|
67
|
+
}
|
|
56
68
|
)
|
|
57
69
|
PATTERN
|
|
58
70
|
|
|
@@ -132,10 +132,11 @@ module RuboCop
|
|
|
132
132
|
# private alias_method :qux, :foo
|
|
133
133
|
#
|
|
134
134
|
# end
|
|
135
|
-
class AccessModifierDeclarations < Base
|
|
135
|
+
class AccessModifierDeclarations < Base # rubocop:disable Metrics/ClassLength
|
|
136
136
|
extend AutoCorrector
|
|
137
137
|
|
|
138
138
|
include ConfigurableEnforcedStyle
|
|
139
|
+
include EndlessMethodBodyHelp
|
|
139
140
|
include RangeHelp
|
|
140
141
|
|
|
141
142
|
GROUP_STYLE_MESSAGE = [
|
|
@@ -169,6 +170,10 @@ module RuboCop
|
|
|
169
170
|
(send nil? :alias_method _ _))
|
|
170
171
|
PATTERN
|
|
171
172
|
|
|
173
|
+
def self.autocorrect_incompatible_with
|
|
174
|
+
[Style::EndlessMethod, Style::SingleLineMethods]
|
|
175
|
+
end
|
|
176
|
+
|
|
172
177
|
def on_send(node)
|
|
173
178
|
return if allowed?(node)
|
|
174
179
|
|
|
@@ -187,11 +192,18 @@ module RuboCop
|
|
|
187
192
|
def allowed?(node)
|
|
188
193
|
!node.access_modifier? ||
|
|
189
194
|
node.parent&.type?(:pair, :any_block) ||
|
|
195
|
+
dynamic_method_list?(node) ||
|
|
190
196
|
allow_modifiers_on_symbols?(node) ||
|
|
191
197
|
allow_modifiers_on_attrs?(node) ||
|
|
192
198
|
allow_modifiers_on_alias_method?(node)
|
|
193
199
|
end
|
|
194
200
|
|
|
201
|
+
# `private(*names)` with a list computed at runtime names no definition
|
|
202
|
+
# the modifier could be grouped with.
|
|
203
|
+
def dynamic_method_list?(node)
|
|
204
|
+
node.arguments.any?(&:splat_type?) && !access_modifier_with_symbol?(node)
|
|
205
|
+
end
|
|
206
|
+
|
|
195
207
|
def autocorrect(corrector, node)
|
|
196
208
|
case style
|
|
197
209
|
when :group
|
|
@@ -241,10 +253,33 @@ module RuboCop
|
|
|
241
253
|
|
|
242
254
|
access_modifier_is_inlined?(node) && !right_siblings_same_inline_method?(node)
|
|
243
255
|
else
|
|
244
|
-
access_modifier_is_not_inlined?(node) && select_grouped_def_nodes(node)
|
|
256
|
+
access_modifier_is_not_inlined?(node) && inlinable?(select_grouped_def_nodes(node))
|
|
245
257
|
end
|
|
246
258
|
end
|
|
247
259
|
|
|
260
|
+
def inlinable?(def_nodes)
|
|
261
|
+
return false if def_nodes.empty?
|
|
262
|
+
|
|
263
|
+
def_nodes.none? { |def_node| def_node.endless? && body_unsafe_to_inline?(def_node.body) }
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def body_unsafe_to_inline?(body)
|
|
267
|
+
return true if body.each_node(:any_block).any? { |block| do_end_block?(block) }
|
|
268
|
+
|
|
269
|
+
target_ruby_version < 4.0 && command_body?(body)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def do_end_block?(block)
|
|
273
|
+
block.keywords? && !block.send_node.lambda_literal?
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def command_body?(body)
|
|
277
|
+
body = body.body while body.rescue_type?
|
|
278
|
+
return true if body.send_type? && body.prefix_not? && !body.parenthesized?
|
|
279
|
+
|
|
280
|
+
command_call?(body)
|
|
281
|
+
end
|
|
282
|
+
|
|
248
283
|
def correctable_group_offense?(node)
|
|
249
284
|
return false unless group_style?
|
|
250
285
|
return false if allowed?(node)
|