rubocop 1.69.2 → 1.71.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/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +36 -2
- data/lib/rubocop/cli/command/execute_runner.rb +3 -3
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +13 -4
- data/lib/rubocop/config_loader.rb +4 -0
- data/lib/rubocop/config_loader_resolver.rb +14 -3
- data/lib/rubocop/config_validator.rb +18 -8
- data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs.rb +4 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -8
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +9 -9
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -5
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +7 -6
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +3 -3
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/debugger.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
- data/lib/rubocop/cop/lint/float_comparison.rb +5 -2
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +8 -4
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +18 -31
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -4
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +4 -3
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +8 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +11 -11
- data/lib/rubocop/cop/mixin/comments_help.rb +3 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +4 -4
- data/lib/rubocop/cop/mixin/hash_subset.rb +188 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +48 -24
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
- data/lib/rubocop/cop/mixin/string_help.rb +1 -1
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
- data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -3
- data/lib/rubocop/cop/security/compound_hash.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +34 -5
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +39 -23
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +7 -20
- data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
- data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -4
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +3 -3
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/empty_else.rb +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +3 -10
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
- data/lib/rubocop/cop/style/hash_except.rb +24 -148
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +6 -6
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
- data/lib/rubocop/cop/style/map_into_array.rb +1 -1
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
- data/lib/rubocop/cop/style/map_to_set.rb +3 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -12
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiple_comparison.rb +26 -20
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +13 -15
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +1 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +6 -4
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +34 -13
- data/lib/rubocop/cop/style/redundant_parentheses.rb +10 -10
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/super_arguments.rb +65 -17
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/util.rb +11 -4
- data/lib/rubocop/cop/variable_force/variable.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
- data/lib/rubocop/cops_documentation_generator.rb +13 -13
- data/lib/rubocop/directive_comment.rb +9 -8
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +7 -23
- data/lib/rubocop/lsp/runtime.rb +15 -49
- data/lib/rubocop/lsp/stdin_runner.rb +83 -0
- data/lib/rubocop/options.rb +2 -1
- data/lib/rubocop/path_util.rb +11 -8
- data/lib/rubocop/result_cache.rb +13 -13
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -1
- data/lib/rubocop/rspec/support.rb +1 -2
- data/lib/rubocop/runner.rb +5 -6
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/target_ruby.rb +15 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +6 -0
- data/lib/ruby_lsp/rubocop/addon.rb +78 -0
- data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +50 -0
- metadata +23 -11
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -23,6 +23,10 @@ module RuboCop
|
|
23
23
|
# `define_method`, therefore, `super` used within these blocks will be allowed.
|
24
24
|
# This approach might result in false negatives, yet ensuring safe detection takes precedence.
|
25
25
|
#
|
26
|
+
# NOTE: When forwarding the same arguments but replacing the block argument with a new inline
|
27
|
+
# block, it is not necessary to explicitly list the non-block arguments. As such, an offense
|
28
|
+
# will be registered in this case.
|
29
|
+
#
|
26
30
|
# @example
|
27
31
|
# # bad
|
28
32
|
# def method(*args, **kwargs)
|
@@ -44,6 +48,16 @@ module RuboCop
|
|
44
48
|
# super()
|
45
49
|
# end
|
46
50
|
#
|
51
|
+
# # bad - forwarding with overridden block
|
52
|
+
# def method(*args, **kwargs, &block)
|
53
|
+
# super(*args, **kwargs) { do_something }
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# # good - implicitly passing all non-block arguments
|
57
|
+
# def method(*args, **kwargs, &block)
|
58
|
+
# super { do_something }
|
59
|
+
# end
|
60
|
+
#
|
47
61
|
# # good - assigning to the block variable before calling super
|
48
62
|
# def method(&block)
|
49
63
|
# # Assigning to the block variable would pass the old value to super,
|
@@ -58,46 +72,77 @@ module RuboCop
|
|
58
72
|
ASSIGN_TYPES = %i[or_asgn lvasgn].freeze
|
59
73
|
|
60
74
|
MSG = 'Call `super` without arguments and parentheses when the signature is identical.'
|
75
|
+
MSG_INLINE_BLOCK = 'Call `super` without arguments and parentheses when all positional ' \
|
76
|
+
'and keyword arguments are forwarded.'
|
61
77
|
|
62
78
|
def on_super(super_node)
|
63
|
-
def_node = super_node
|
79
|
+
return unless (def_node = find_def_node(super_node))
|
80
|
+
|
81
|
+
def_node_args = def_node.arguments.argument_list
|
82
|
+
super_args = preprocess_super_args(super_node.arguments)
|
83
|
+
|
84
|
+
return unless arguments_identical?(def_node, super_node, def_node_args, super_args)
|
85
|
+
|
86
|
+
# If the number of arguments to the def node and super node are different here,
|
87
|
+
# it's because the block argument is not forwarded.
|
88
|
+
message = def_node_args.size == super_args.size ? MSG : MSG_INLINE_BLOCK
|
89
|
+
add_offense(super_node, message: message) do |corrector|
|
90
|
+
corrector.replace(super_node, 'super')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def find_def_node(super_node)
|
97
|
+
super_node.ancestors.find do |node|
|
64
98
|
# When defining dynamic methods, implicitly calling `super` is not possible.
|
65
99
|
# Since there is a possibility of delegation to `define_method`,
|
66
100
|
# `super` used within the block is always allowed.
|
67
|
-
break if node.
|
101
|
+
break if node.any_block_type? && !block_sends_to_super?(super_node, node)
|
68
102
|
|
69
103
|
break node if DEF_TYPES.include?(node.type)
|
70
104
|
end
|
71
|
-
return unless def_node
|
72
|
-
return unless arguments_identical?(def_node, def_node.arguments.argument_list,
|
73
|
-
super_node.arguments)
|
74
|
-
|
75
|
-
add_offense(super_node) { |corrector| corrector.replace(super_node, 'super') }
|
76
105
|
end
|
77
106
|
|
78
|
-
private
|
79
|
-
|
80
107
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
81
|
-
def arguments_identical?(def_node, def_args, super_args)
|
82
|
-
|
83
|
-
return false if def_args.size != super_args.size
|
108
|
+
def arguments_identical?(def_node, super_node, def_args, super_args)
|
109
|
+
return false if argument_list_size_differs?(def_args, super_args, super_node)
|
84
110
|
|
85
111
|
def_args.zip(super_args).each do |def_arg, super_arg|
|
86
112
|
next if positional_arg_same?(def_arg, super_arg)
|
87
113
|
next if positional_rest_arg_same(def_arg, super_arg)
|
88
114
|
next if keyword_arg_same?(def_arg, super_arg)
|
89
115
|
next if keyword_rest_arg_same?(def_arg, super_arg)
|
90
|
-
next if block_arg_same?(def_node, def_arg, super_arg)
|
116
|
+
next if block_arg_same?(def_node, super_node, def_arg, super_arg)
|
91
117
|
next if forward_arg_same?(def_arg, super_arg)
|
92
118
|
|
93
119
|
return false
|
94
120
|
end
|
121
|
+
|
95
122
|
true
|
96
123
|
end
|
97
124
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
98
125
|
|
126
|
+
def argument_list_size_differs?(def_args, super_args, super_node)
|
127
|
+
# If the def node has a block argument and the super node has an explicit block,
|
128
|
+
# the number of arguments is the same, so ignore the def node block arg.
|
129
|
+
def_args_size = def_args.size
|
130
|
+
def_args_size -= 1 if def_args.any?(&:blockarg_type?) && block_sends_to_super?(super_node)
|
131
|
+
|
132
|
+
def_args_size != super_args.size
|
133
|
+
end
|
134
|
+
|
135
|
+
def block_sends_to_super?(super_node, parent_node = super_node.parent)
|
136
|
+
# Checks if the send node of a block is the given super node,
|
137
|
+
# or a method chain containing it.
|
138
|
+
return false unless parent_node
|
139
|
+
return false unless parent_node.any_block_type?
|
140
|
+
|
141
|
+
parent_node.send_node.each_node(:super).any?(super_node)
|
142
|
+
end
|
143
|
+
|
99
144
|
def positional_arg_same?(def_arg, super_arg)
|
100
|
-
return false unless def_arg.
|
145
|
+
return false unless def_arg.type?(:arg, :optarg)
|
101
146
|
return false unless super_arg.lvar_type?
|
102
147
|
|
103
148
|
def_arg.name == super_arg.children.first
|
@@ -114,7 +159,7 @@ module RuboCop
|
|
114
159
|
end
|
115
160
|
|
116
161
|
def keyword_arg_same?(def_arg, super_arg)
|
117
|
-
return false unless def_arg.
|
162
|
+
return false unless def_arg.type?(:kwarg, :kwoptarg)
|
118
163
|
return false unless (pair_node = super_arg).pair_type?
|
119
164
|
return false unless (sym_node = pair_node.key).sym_type?
|
120
165
|
return false unless (lvar_node = pair_node.value).lvar_type?
|
@@ -133,8 +178,11 @@ module RuboCop
|
|
133
178
|
def_arg.name == lvar_node.children.first
|
134
179
|
end
|
135
180
|
|
136
|
-
def block_arg_same?(def_node, def_arg, super_arg)
|
137
|
-
return false unless def_arg.blockarg_type?
|
181
|
+
def block_arg_same?(def_node, super_node, def_arg, super_arg)
|
182
|
+
return false unless def_arg.blockarg_type?
|
183
|
+
return true if block_sends_to_super?(super_node)
|
184
|
+
return false unless super_arg.block_pass_type?
|
185
|
+
|
138
186
|
# anonymous forwarding
|
139
187
|
return true if (block_pass_child = super_arg.children.first).nil? && def_arg.name.nil?
|
140
188
|
|
@@ -7,12 +7,15 @@ module RuboCop
|
|
7
7
|
# The supported styles are:
|
8
8
|
#
|
9
9
|
# * `consistent_comma`: Requires a comma after the last argument,
|
10
|
-
# for all parenthesized method calls with arguments.
|
10
|
+
# for all parenthesized multi-line method calls with arguments.
|
11
11
|
# * `comma`: Requires a comma after the last argument, but only for
|
12
12
|
# parenthesized method calls where each argument is on its own line.
|
13
13
|
# * `no_comma`: Requires that there is no comma after the last
|
14
14
|
# argument.
|
15
15
|
#
|
16
|
+
# Regardless of style, trailing commas are not allowed in
|
17
|
+
# single-line method calls.
|
18
|
+
#
|
16
19
|
# @example EnforcedStyleForMultiline: consistent_comma
|
17
20
|
# # bad
|
18
21
|
# method(1, 2,)
|
@@ -85,6 +85,12 @@ module RuboCop
|
|
85
85
|
NONCOMMUTATIVE_OPERATORS = %i[===].freeze
|
86
86
|
PROGRAM_NAMES = %i[$0 $PROGRAM_NAME].freeze
|
87
87
|
RESTRICT_ON_SEND = RuboCop::AST::Node::COMPARISON_OPERATORS
|
88
|
+
ENFORCE_YODA_STYLES = %i[
|
89
|
+
require_for_all_comparison_operators require_for_equality_operators_only
|
90
|
+
].freeze
|
91
|
+
EQUALITY_ONLY_STYLES = %i[
|
92
|
+
forbid_for_equality_operators_only require_for_equality_operators_only
|
93
|
+
].freeze
|
88
94
|
|
89
95
|
# @!method file_constant_equal_program_name?(node)
|
90
96
|
def_node_matcher :file_constant_equal_program_name?, <<~PATTERN
|
@@ -105,13 +111,11 @@ module RuboCop
|
|
105
111
|
private
|
106
112
|
|
107
113
|
def enforce_yoda?
|
108
|
-
style
|
109
|
-
style == :require_for_equality_operators_only
|
114
|
+
ENFORCE_YODA_STYLES.include?(style)
|
110
115
|
end
|
111
116
|
|
112
117
|
def equality_only?
|
113
|
-
style
|
114
|
-
style == :require_for_equality_operators_only
|
118
|
+
EQUALITY_ONLY_STYLES.include?(style)
|
115
119
|
end
|
116
120
|
|
117
121
|
def yoda_compatible_condition?(node)
|
@@ -50,6 +50,7 @@ module RuboCop
|
|
50
50
|
|
51
51
|
def on_send(node)
|
52
52
|
return unless supported_operators.include?(node.method_name.to_s)
|
53
|
+
return unless node.arguments?
|
53
54
|
|
54
55
|
lhs = node.receiver
|
55
56
|
rhs = node.first_argument
|
@@ -71,7 +72,7 @@ module RuboCop
|
|
71
72
|
end
|
72
73
|
|
73
74
|
def constant_portion?(node)
|
74
|
-
node.
|
75
|
+
node.type?(:numeric, :const)
|
75
76
|
end
|
76
77
|
|
77
78
|
def supported_operators
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -74,9 +74,9 @@ module RuboCop
|
|
74
74
|
|
75
75
|
def args_begin(node)
|
76
76
|
loc = node.loc
|
77
|
-
selector = if node.
|
77
|
+
selector = if node.type?(:super, :yield)
|
78
78
|
loc.keyword
|
79
|
-
elsif node.
|
79
|
+
elsif node.type?(:def, :defs)
|
80
80
|
loc.name
|
81
81
|
else
|
82
82
|
loc.selector
|
@@ -193,11 +193,18 @@ module RuboCop
|
|
193
193
|
enforced_style.sub(/^Enforced/, 'Supported').sub('Style', 'Styles')
|
194
194
|
end
|
195
195
|
|
196
|
+
def parse_regexp(text)
|
197
|
+
Regexp::Parser.parse(text)
|
198
|
+
rescue Regexp::Parser::Error
|
199
|
+
# Upon encountering an invalid regular expression,
|
200
|
+
# we aim to proceed and identify any remaining potential offenses.
|
201
|
+
nil
|
202
|
+
end
|
203
|
+
|
196
204
|
private
|
197
205
|
|
198
206
|
def compatible_external_encoding_for?(src)
|
199
|
-
src
|
200
|
-
src.force_encoding(Encoding.default_external).valid_encoding?
|
207
|
+
src.dup.force_encoding(Encoding.default_external).valid_encoding?
|
201
208
|
end
|
202
209
|
|
203
210
|
def include_or_equal?(source, target)
|
@@ -72,7 +72,7 @@ module RuboCop
|
|
72
72
|
parent = parent.parent if parent&.begin_type?
|
73
73
|
return false if parent.nil?
|
74
74
|
|
75
|
-
|
75
|
+
parent.type?(:if, :while, :until) && parent.modifier_form?
|
76
76
|
end
|
77
77
|
|
78
78
|
def capture_with_block!
|
@@ -100,7 +100,7 @@ module RuboCop
|
|
100
100
|
|
101
101
|
# Only block scope allows referencing outer scope variables.
|
102
102
|
node = scope.node
|
103
|
-
return nil unless node.
|
103
|
+
return nil unless node.any_block_type?
|
104
104
|
end
|
105
105
|
|
106
106
|
nil
|
@@ -113,14 +113,14 @@ module RuboCop
|
|
113
113
|
def accessible_variables
|
114
114
|
scope_stack.reverse_each.with_object([]) do |scope, variables|
|
115
115
|
variables.concat(scope.variables.values)
|
116
|
-
break variables unless scope.node.
|
116
|
+
break variables unless scope.node.any_block_type?
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
120
|
private
|
121
121
|
|
122
122
|
def mark_variable_as_captured_by_block_if_so(variable)
|
123
|
-
return unless current_scope.node.
|
123
|
+
return unless current_scope.node.any_block_type?
|
124
124
|
return if variable.scope == current_scope
|
125
125
|
|
126
126
|
variable.capture_with_block!
|
@@ -18,7 +18,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
18
18
|
description: ->(data) { "#{data.description}\n" },
|
19
19
|
safety: ->(data) { safety_object(data.safety_objects, data.cop) },
|
20
20
|
examples: ->(data) { examples(data.example_objects, data.cop) },
|
21
|
-
configuration: ->(data) { configurations(data.cop.department, data.
|
21
|
+
configuration: ->(data) { configurations(data.cop.department, data.cop, data.config) },
|
22
22
|
references: ->(data) { references(data.cop, data.see_objects) }
|
23
23
|
}.freeze
|
24
24
|
|
@@ -180,17 +180,17 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
180
180
|
content
|
181
181
|
end
|
182
182
|
|
183
|
-
def configurations(department,
|
184
|
-
return '' if pars.empty?
|
185
|
-
|
183
|
+
def configurations(department, cop, cop_config)
|
186
184
|
header = ['Name', 'Default value', 'Configurable values']
|
187
|
-
configs =
|
185
|
+
configs = cop_config
|
188
186
|
.each_key
|
189
187
|
.reject { |key| key.start_with?('Supported') }
|
190
188
|
.reject { |key| key.start_with?('AllowMultipleStyles') }
|
189
|
+
return '' if configs.empty?
|
190
|
+
|
191
191
|
content = configs.map do |name|
|
192
|
-
configurable = configurable_values(
|
193
|
-
default = format_table_value(
|
192
|
+
configurable = configurable_values(cop_config, name)
|
193
|
+
default = format_table_value(cop_config[name])
|
194
194
|
|
195
195
|
[configuration_name(department, name), default, configurable]
|
196
196
|
end
|
@@ -206,17 +206,17 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
206
206
|
end
|
207
207
|
|
208
208
|
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
|
209
|
-
def configurable_values(
|
209
|
+
def configurable_values(cop_config, name)
|
210
210
|
case name
|
211
211
|
when /^Enforced/
|
212
212
|
supported_style_name = RuboCop::Cop::Util.to_supported_styles(name)
|
213
|
-
format_table_value(
|
213
|
+
format_table_value(cop_config[supported_style_name])
|
214
214
|
when 'IndentationWidth'
|
215
215
|
'Integer'
|
216
216
|
when 'Database'
|
217
|
-
format_table_value(
|
217
|
+
format_table_value(cop_config['SupportedDatabases'])
|
218
218
|
else
|
219
|
-
case
|
219
|
+
case cop_config[name]
|
220
220
|
when String
|
221
221
|
'String'
|
222
222
|
when Integer
|
@@ -319,7 +319,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
319
319
|
AutoCorrect Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
|
320
320
|
VersionChanged
|
321
321
|
]
|
322
|
-
|
322
|
+
parameters = cop_config.reject { |k| non_display_keys.include? k }
|
323
323
|
description = 'No documentation'
|
324
324
|
example_objects = safety_objects = see_objects = []
|
325
325
|
cop_code(cop) do |code_object|
|
@@ -329,7 +329,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
329
329
|
see_objects = code_object.tags('see')
|
330
330
|
end
|
331
331
|
data = CopData.new(cop: cop, description: description, example_objects: example_objects,
|
332
|
-
safety_objects: safety_objects, see_objects: see_objects, config:
|
332
|
+
safety_objects: safety_objects, see_objects: see_objects, config: parameters)
|
333
333
|
cops_body(data)
|
334
334
|
end
|
335
335
|
|
@@ -88,10 +88,15 @@ module RuboCop
|
|
88
88
|
@cop_names ||= all_cops? ? all_cop_names : parsed_cop_names
|
89
89
|
end
|
90
90
|
|
91
|
+
# Returns an array of cops for this directive comment, without resolving departments
|
92
|
+
def raw_cop_names
|
93
|
+
@raw_cop_names ||= (cops || '').split(/,\s*/)
|
94
|
+
end
|
95
|
+
|
91
96
|
# Returns array of specified in this directive department names
|
92
97
|
# when all department disabled
|
93
98
|
def department_names
|
94
|
-
|
99
|
+
raw_cop_names.select { |cop| department?(cop) }
|
95
100
|
end
|
96
101
|
|
97
102
|
# Checks if directive departments include cop
|
@@ -101,11 +106,11 @@ module RuboCop
|
|
101
106
|
|
102
107
|
# Checks if cop department has already used in directive comment
|
103
108
|
def overridden_by_department?(cop)
|
104
|
-
in_directive_department?(cop) &&
|
109
|
+
in_directive_department?(cop) && raw_cop_names.include?(cop)
|
105
110
|
end
|
106
111
|
|
107
112
|
def directive_count
|
108
|
-
|
113
|
+
raw_cop_names.count
|
109
114
|
end
|
110
115
|
|
111
116
|
# Returns line number for directive
|
@@ -115,12 +120,8 @@ module RuboCop
|
|
115
120
|
|
116
121
|
private
|
117
122
|
|
118
|
-
def splitted_cops_string
|
119
|
-
(cops || '').split(/,\s*/)
|
120
|
-
end
|
121
|
-
|
122
123
|
def parsed_cop_names
|
123
|
-
cops =
|
124
|
+
cops = raw_cop_names.map do |name|
|
124
125
|
department?(name) ? cop_names_for_department(name) : name
|
125
126
|
end.flatten
|
126
127
|
cops - [LINT_SYNTAX_COP]
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'severity'
|
4
|
+
|
5
|
+
#
|
6
|
+
# This code is based on https://github.com/standardrb/standard.
|
7
|
+
#
|
8
|
+
# Copyright (c) 2023 Test Double, Inc.
|
9
|
+
#
|
10
|
+
# The MIT License (MIT)
|
11
|
+
#
|
12
|
+
# https://github.com/standardrb/standard/blob/main/LICENSE.txt
|
13
|
+
#
|
14
|
+
module RuboCop
|
15
|
+
module LSP
|
16
|
+
# Diagnostic for Language Server Protocol of RuboCop.
|
17
|
+
# @api private
|
18
|
+
class Diagnostic
|
19
|
+
def initialize(document_encoding, offense, uri, cop_class)
|
20
|
+
@document_encoding = document_encoding
|
21
|
+
@offense = offense
|
22
|
+
@uri = uri
|
23
|
+
@cop_class = cop_class
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_lsp_code_actions
|
27
|
+
code_actions = []
|
28
|
+
|
29
|
+
code_actions << autocorrect_action if correctable?
|
30
|
+
code_actions << disable_line_action
|
31
|
+
|
32
|
+
code_actions
|
33
|
+
end
|
34
|
+
|
35
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
36
|
+
def to_lsp_diagnostic(config)
|
37
|
+
highlighted = @offense.highlighted_area
|
38
|
+
|
39
|
+
LanguageServer::Protocol::Interface::Diagnostic.new(
|
40
|
+
message: message,
|
41
|
+
source: 'RuboCop',
|
42
|
+
code: @offense.cop_name,
|
43
|
+
code_description: code_description(config),
|
44
|
+
severity: severity,
|
45
|
+
range: LanguageServer::Protocol::Interface::Range.new(
|
46
|
+
start: LanguageServer::Protocol::Interface::Position.new(
|
47
|
+
line: @offense.line - 1,
|
48
|
+
character: highlighted.begin_pos
|
49
|
+
),
|
50
|
+
end: LanguageServer::Protocol::Interface::Position.new(
|
51
|
+
line: @offense.line - 1,
|
52
|
+
character: highlighted.end_pos
|
53
|
+
)
|
54
|
+
),
|
55
|
+
data: {
|
56
|
+
correctable: correctable?,
|
57
|
+
code_actions: to_lsp_code_actions
|
58
|
+
}
|
59
|
+
)
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def message
|
66
|
+
message = @offense.message
|
67
|
+
message += "\n\nThis offense is not autocorrectable.\n" unless correctable?
|
68
|
+
message
|
69
|
+
end
|
70
|
+
|
71
|
+
def severity
|
72
|
+
Severity.find_by(@offense.severity.name)
|
73
|
+
end
|
74
|
+
|
75
|
+
def code_description(config)
|
76
|
+
return unless @cop_class
|
77
|
+
return unless (doc_url = @cop_class.documentation_url(config))
|
78
|
+
|
79
|
+
LanguageServer::Protocol::Interface::CodeDescription.new(href: doc_url)
|
80
|
+
end
|
81
|
+
|
82
|
+
# rubocop:disable Layout/LineLength, Metrics/MethodLength
|
83
|
+
def autocorrect_action
|
84
|
+
LanguageServer::Protocol::Interface::CodeAction.new(
|
85
|
+
title: "Autocorrect #{@offense.cop_name}",
|
86
|
+
kind: LanguageServer::Protocol::Constant::CodeActionKind::QUICK_FIX,
|
87
|
+
edit: LanguageServer::Protocol::Interface::WorkspaceEdit.new(
|
88
|
+
document_changes: [
|
89
|
+
LanguageServer::Protocol::Interface::TextDocumentEdit.new(
|
90
|
+
text_document: LanguageServer::Protocol::Interface::OptionalVersionedTextDocumentIdentifier.new(
|
91
|
+
uri: ensure_uri_scheme(@uri.to_s).to_s,
|
92
|
+
version: nil
|
93
|
+
),
|
94
|
+
edits: correctable? ? offense_replacements : []
|
95
|
+
)
|
96
|
+
]
|
97
|
+
),
|
98
|
+
is_preferred: true
|
99
|
+
)
|
100
|
+
end
|
101
|
+
# rubocop:enable Layout/LineLength, Metrics/MethodLength
|
102
|
+
|
103
|
+
# rubocop:disable Metrics/MethodLength
|
104
|
+
def offense_replacements
|
105
|
+
@offense.corrector.as_replacements.map do |range, replacement|
|
106
|
+
LanguageServer::Protocol::Interface::TextEdit.new(
|
107
|
+
range: LanguageServer::Protocol::Interface::Range.new(
|
108
|
+
start: LanguageServer::Protocol::Interface::Position.new(
|
109
|
+
line: range.line - 1,
|
110
|
+
character: range.column
|
111
|
+
),
|
112
|
+
end: LanguageServer::Protocol::Interface::Position.new(
|
113
|
+
line: range.last_line - 1,
|
114
|
+
character: range.last_column
|
115
|
+
)
|
116
|
+
),
|
117
|
+
new_text: replacement
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
# rubocop:enable Metrics/MethodLength
|
122
|
+
|
123
|
+
# rubocop:disable Layout/LineLength, Metrics/MethodLength
|
124
|
+
def disable_line_action
|
125
|
+
LanguageServer::Protocol::Interface::CodeAction.new(
|
126
|
+
title: "Disable #{@offense.cop_name} for this line",
|
127
|
+
kind: LanguageServer::Protocol::Constant::CodeActionKind::QUICK_FIX,
|
128
|
+
edit: LanguageServer::Protocol::Interface::WorkspaceEdit.new(
|
129
|
+
document_changes: [
|
130
|
+
LanguageServer::Protocol::Interface::TextDocumentEdit.new(
|
131
|
+
text_document: LanguageServer::Protocol::Interface::OptionalVersionedTextDocumentIdentifier.new(
|
132
|
+
uri: ensure_uri_scheme(@uri.to_s).to_s,
|
133
|
+
version: nil
|
134
|
+
),
|
135
|
+
edits: line_disable_comment
|
136
|
+
)
|
137
|
+
]
|
138
|
+
)
|
139
|
+
)
|
140
|
+
end
|
141
|
+
# rubocop:enable Layout/LineLength, Metrics/MethodLength
|
142
|
+
|
143
|
+
def line_disable_comment
|
144
|
+
new_text = if @offense.source_line.include?(' # rubocop:disable ')
|
145
|
+
",#{@offense.cop_name}"
|
146
|
+
else
|
147
|
+
" # rubocop:disable #{@offense.cop_name}"
|
148
|
+
end
|
149
|
+
|
150
|
+
eol = LanguageServer::Protocol::Interface::Position.new(
|
151
|
+
line: @offense.line - 1,
|
152
|
+
character: length_of_line(@offense.source_line)
|
153
|
+
)
|
154
|
+
|
155
|
+
# TODO: fails for multiline strings - may be preferable to use block
|
156
|
+
# comments to disable some offenses
|
157
|
+
inline_comment = LanguageServer::Protocol::Interface::TextEdit.new(
|
158
|
+
range: LanguageServer::Protocol::Interface::Range.new(start: eol, end: eol),
|
159
|
+
new_text: new_text
|
160
|
+
)
|
161
|
+
|
162
|
+
[inline_comment]
|
163
|
+
end
|
164
|
+
|
165
|
+
def length_of_line(line)
|
166
|
+
if @document_encoding == Encoding::UTF_16LE
|
167
|
+
line_length = 0
|
168
|
+
line.codepoints.each do |codepoint|
|
169
|
+
line_length += 1
|
170
|
+
line_length += 1 if codepoint > RubyLsp::Document::Scanner::SURROGATE_PAIR_START
|
171
|
+
end
|
172
|
+
line_length
|
173
|
+
else
|
174
|
+
line.length
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def correctable?
|
179
|
+
!@offense.corrector.nil?
|
180
|
+
end
|
181
|
+
|
182
|
+
def ensure_uri_scheme(uri)
|
183
|
+
uri = URI.parse(uri)
|
184
|
+
uri.scheme = 'file' if uri.scheme.nil?
|
185
|
+
uri
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
data/lib/rubocop/lsp/logger.rb
CHANGED