rubocop 1.53.0 → 1.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +5 -3
- data/config/default.yml +80 -11
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +10 -5
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +0 -2
- data/lib/rubocop/config_finder.rb +2 -2
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +11 -8
- data/lib/rubocop/config_validator.rb +0 -2
- data/lib/rubocop/cop/autocorrect_logic.rb +3 -1
- data/lib/rubocop/cop/base.rb +7 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
- data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
- data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
- data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +42 -21
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -5
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +26 -3
- data/lib/rubocop/cop/layout/end_alignment.rb +12 -2
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +22 -7
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +17 -9
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
- data/lib/rubocop/cop/layout/redundant_line_break.rb +15 -4
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
- data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +53 -21
- data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +4 -4
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +18 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -3
- data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
- data/lib/rubocop/cop/lint/number_conversion.rb +9 -4
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +10 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +63 -4
- data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
- data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +8 -3
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +5 -3
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +38 -12
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +46 -21
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +8 -3
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +32 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +16 -12
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +14 -11
- data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -2
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/string_help.rb +4 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +12 -4
- data/lib/rubocop/cop/naming/constant_name.rb +1 -2
- data/lib/rubocop/cop/naming/file_name.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/registry.rb +4 -4
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +2 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +9 -8
- data/lib/rubocop/cop/style/arguments_forwarding.rb +355 -63
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- data/lib/rubocop/cop/style/array_intersect.rb +13 -5
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
- data/lib/rubocop/cop/style/case_like_if.rb +4 -4
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_equality_comparison.rb +7 -0
- data/lib/rubocop/cop/style/collection_compact.rb +7 -6
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +17 -9
- data/lib/rubocop/cop/style/concat_array_literals.rb +2 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
- data/lib/rubocop/cop/style/date_time.rb +5 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -14
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +24 -3
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -1
- data/lib/rubocop/cop/style/guard_clause.rb +26 -0
- data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +83 -10
- data/lib/rubocop/cop/style/hash_except.rb +2 -1
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +28 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +6 -5
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +39 -2
- data/lib/rubocop/cop/style/lambda.rb +3 -3
- data/lib/rubocop/cop/style/lambda_call.rb +5 -0
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +3 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +17 -7
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +22 -6
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +2 -4
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +8 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +9 -3
- data/lib/rubocop/cop/style/redundant_begin.rb +9 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -9
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +1 -1
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +93 -5
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +22 -5
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +10 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +63 -21
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +18 -4
- data/lib/rubocop/cop/style/redundant_return.rb +8 -3
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +5 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +9 -8
- data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -1
- data/lib/rubocop/cop/style/return_nil.rb +6 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +23 -9
- data/lib/rubocop/cop/style/sample.rb +2 -1
- data/lib/rubocop/cop/style/select_by_regexp.rb +7 -6
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +8 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/symbol_array.rb +35 -15
- data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
- data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
- data/lib/rubocop/cop/utils/regexp_ranges.rb +26 -13
- data/lib/rubocop/cop/variable_force/assignment.rb +14 -5
- data/lib/rubocop/cops_documentation_generator.rb +11 -1
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/file_finder.rb +4 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/html_formatter.rb +5 -4
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +42 -19
- data/lib/rubocop/lsp/runtime.rb +22 -2
- data/lib/rubocop/lsp/server.rb +10 -4
- data/lib/rubocop/magic_comment.rb +12 -10
- data/lib/rubocop/options.rb +0 -8
- data/lib/rubocop/result_cache.rb +4 -1
- data/lib/rubocop/rspec/shared_contexts.rb +8 -3
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/runner.rb +6 -4
- data/lib/rubocop/server/client_command/exec.rb +1 -1
- data/lib/rubocop/string_interpreter.rb +3 -3
- data/lib/rubocop/target_finder.rb +7 -3
- data/lib/rubocop/target_ruby.rb +9 -5
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +6 -0
- metadata +20 -13
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
|
@@ -14,12 +14,15 @@ module RuboCop
|
|
|
14
14
|
# Check for unparenthesized args' preceding and trailing whitespaces.
|
|
15
15
|
remove_unparenthesized_whitespace(corrector)
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
if block_node.block_type?
|
|
18
|
+
# Avoid correcting to `lambdado` by inserting whitespace
|
|
19
|
+
# if none exists before or after the lambda arguments.
|
|
20
|
+
insert_separating_space(corrector)
|
|
21
|
+
|
|
22
|
+
remove_arguments(corrector)
|
|
23
|
+
end
|
|
20
24
|
|
|
21
25
|
replace_selector(corrector)
|
|
22
|
-
remove_arguments(corrector)
|
|
23
26
|
|
|
24
27
|
replace_delimiters(corrector)
|
|
25
28
|
|
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
|
8
8
|
# The parameter name given is transformed into a method name (eg. `Max`
|
|
9
9
|
# becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
|
|
10
10
|
def exclude_limit(parameter_name, method_name: transform(parameter_name))
|
|
11
|
-
define_method("#{method_name}=") do |value|
|
|
11
|
+
define_method(:"#{method_name}=") do |value|
|
|
12
12
|
cfg = config_to_allow_offenses
|
|
13
13
|
cfg[:exclude_limit] ||= {}
|
|
14
14
|
current_max = cfg[:exclude_limit][parameter_name]
|
|
@@ -43,7 +43,7 @@ module RuboCop
|
|
|
43
43
|
def on_block(block_node)
|
|
44
44
|
return unless gem_specification(block_node)
|
|
45
45
|
|
|
46
|
-
block_parameter = block_node.
|
|
46
|
+
block_parameter = block_node.first_argument.source
|
|
47
47
|
|
|
48
48
|
assignment = block_node.descendants.detect do |node|
|
|
49
49
|
use_deprecated_attributes?(node, block_parameter)
|
|
@@ -65,7 +65,7 @@ module RuboCop
|
|
|
65
65
|
lhs, _op, _rhs = *node
|
|
66
66
|
[lhs, attribute]
|
|
67
67
|
else
|
|
68
|
-
[node, "#{attribute}="
|
|
68
|
+
[node, :"#{attribute}="]
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
@@ -45,7 +45,15 @@ module RuboCop
|
|
|
45
45
|
#
|
|
46
46
|
# spec.add_runtime_dependency 'rspec'
|
|
47
47
|
#
|
|
48
|
-
#
|
|
48
|
+
# @example TreatCommentsAsGroupSeparators: true (default)
|
|
49
|
+
# # good
|
|
50
|
+
# # For code quality
|
|
51
|
+
# spec.add_dependency 'rubocop'
|
|
52
|
+
# # For tests
|
|
53
|
+
# spec.add_dependency 'rspec'
|
|
54
|
+
#
|
|
55
|
+
# @example TreatCommentsAsGroupSeparators: false
|
|
56
|
+
# # bad
|
|
49
57
|
# # For code quality
|
|
50
58
|
# spec.add_dependency 'rubocop'
|
|
51
59
|
# # For tests
|
|
@@ -26,9 +26,7 @@ module RuboCop
|
|
|
26
26
|
# expect_no_offenses('...')
|
|
27
27
|
# end
|
|
28
28
|
class ExampleDescription < Base
|
|
29
|
-
|
|
30
|
-
attr_accessor :descriptions
|
|
31
|
-
end
|
|
29
|
+
extend AutoCorrector
|
|
32
30
|
|
|
33
31
|
MSG = 'Description does not match use of `%<method_name>s`.'
|
|
34
32
|
|
|
@@ -39,21 +37,31 @@ module RuboCop
|
|
|
39
37
|
expect_no_corrections
|
|
40
38
|
].to_set.freeze
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
EXPECT_NO_OFFENSES_DESCRIPTION_MAPPING = {
|
|
41
|
+
/\A(adds|registers|reports|finds) (an? )?offense/ => 'does not register an offense',
|
|
42
|
+
/\A(flags|handles|works)\b/ => 'does not register'
|
|
43
|
+
}.freeze
|
|
44
|
+
|
|
45
|
+
EXPECT_OFFENSE_DESCRIPTION_MAPPING = {
|
|
46
|
+
/\A(does not|doesn't) (register|find|flag|report)/ => 'registers',
|
|
47
|
+
/\A(does not|doesn't) add (a|an|any )?offense/ => 'registers an offense',
|
|
48
|
+
/\Aaccepts\b/ => 'registers'
|
|
49
|
+
}.freeze
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
].freeze
|
|
51
|
+
EXPECT_NO_CORRECTIONS_DESCRIPTION_MAPPING = {
|
|
52
|
+
/\A(auto[- ]?)?correct/ => 'does not correct'
|
|
53
|
+
}.freeze
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
EXPECT_CORRECTION_DESCRIPTION_MAPPING = {
|
|
56
|
+
/\b(does not|doesn't) (auto[- ]?)?correct/ => 'autocorrects'
|
|
57
|
+
}.freeze
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
EXAMPLE_DESCRIPTION_MAPPING = {
|
|
60
|
+
expect_no_offenses: EXPECT_NO_OFFENSES_DESCRIPTION_MAPPING,
|
|
61
|
+
expect_offense: EXPECT_OFFENSE_DESCRIPTION_MAPPING,
|
|
62
|
+
expect_no_corrections: EXPECT_NO_CORRECTIONS_DESCRIPTION_MAPPING,
|
|
63
|
+
expect_correction: EXPECT_CORRECTION_DESCRIPTION_MAPPING
|
|
64
|
+
}.freeze
|
|
57
65
|
|
|
58
66
|
# @!method offense_example?(node)
|
|
59
67
|
def_node_matcher :offense_example?, <<~PATTERN
|
|
@@ -66,21 +74,34 @@ module RuboCop
|
|
|
66
74
|
|
|
67
75
|
def on_send(node)
|
|
68
76
|
parent = node.each_ancestor(:block).first
|
|
69
|
-
return unless parent && (
|
|
77
|
+
return unless parent && (current_description = offense_example?(parent))
|
|
70
78
|
|
|
71
79
|
method_name = node.method_name
|
|
72
80
|
message = format(MSG, method_name: method_name)
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
check_description(
|
|
82
|
+
description_map = EXAMPLE_DESCRIPTION_MAPPING[method_name]
|
|
83
|
+
check_description(current_description, description_map, message)
|
|
76
84
|
end
|
|
77
85
|
|
|
78
86
|
private
|
|
79
87
|
|
|
80
|
-
def check_description(
|
|
81
|
-
|
|
88
|
+
def check_description(current_description, description_map, message)
|
|
89
|
+
description_text = string_contents(current_description)
|
|
90
|
+
return unless (new_description = correct_description(description_text, description_map))
|
|
91
|
+
|
|
92
|
+
add_offense(current_description, message: message) do |corrector|
|
|
93
|
+
corrector.replace(current_description, "'#{new_description}'")
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def correct_description(current_description, description_map)
|
|
98
|
+
description_map.each do |incorrect_description_pattern, preferred_description|
|
|
99
|
+
if incorrect_description_pattern.match?(current_description)
|
|
100
|
+
return current_description.gsub(incorrect_description_pattern, preferred_description)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
82
103
|
|
|
83
|
-
|
|
104
|
+
nil
|
|
84
105
|
end
|
|
85
106
|
|
|
86
107
|
def string_contents(node)
|
|
@@ -51,7 +51,9 @@ module RuboCop
|
|
|
51
51
|
|
|
52
52
|
def extract_receiver(node)
|
|
53
53
|
receiver = node.receiver
|
|
54
|
-
|
|
54
|
+
if receiver.send_type? && (receiver.method?(:loc) || receiver.method?(:source_range))
|
|
55
|
+
receiver = receiver.receiver
|
|
56
|
+
end
|
|
55
57
|
receiver.source
|
|
56
58
|
end
|
|
57
59
|
end
|
|
@@ -12,38 +12,37 @@ module RuboCop
|
|
|
12
12
|
# # good
|
|
13
13
|
# node.method?(:do_something)
|
|
14
14
|
#
|
|
15
|
+
# # bad
|
|
16
|
+
# node.method_name != :do_something
|
|
17
|
+
#
|
|
18
|
+
# # good
|
|
19
|
+
# !node.method?(:do_something)
|
|
20
|
+
#
|
|
15
21
|
class MethodNameEqual < Base
|
|
16
|
-
include RangeHelp
|
|
17
22
|
extend AutoCorrector
|
|
18
23
|
|
|
19
|
-
MSG = 'Use
|
|
20
|
-
RESTRICT_ON_SEND = %i[==].freeze
|
|
24
|
+
MSG = 'Use `%<prefer>s` instead.'
|
|
25
|
+
RESTRICT_ON_SEND = %i[== !=].freeze
|
|
21
26
|
|
|
22
|
-
# @!method method_name
|
|
23
|
-
def_node_matcher :method_name
|
|
27
|
+
# @!method method_name(node)
|
|
28
|
+
def_node_matcher :method_name, <<~PATTERN
|
|
24
29
|
(send
|
|
25
|
-
|
|
26
|
-
(...) :method_name) :==
|
|
27
|
-
|
|
30
|
+
(send
|
|
31
|
+
(...) :method_name) {:== :!=}
|
|
32
|
+
$_)
|
|
28
33
|
PATTERN
|
|
29
34
|
|
|
30
35
|
def on_send(node)
|
|
31
|
-
method_name
|
|
32
|
-
|
|
36
|
+
method_name(node) do |method_name_arg|
|
|
37
|
+
bang = node.method?(:!=) ? '!' : ''
|
|
38
|
+
prefer = "#{bang}#{node.receiver.receiver.source}.method?(#{method_name_arg.source})"
|
|
39
|
+
message = format(MSG, prefer: prefer)
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
add_offense(range, message: message) do |corrector|
|
|
37
|
-
corrector.replace(range, "method?(#{method_name_arg.first.source})")
|
|
41
|
+
add_offense(node, message: message) do |corrector|
|
|
42
|
+
corrector.replace(node, prefer)
|
|
38
43
|
end
|
|
39
44
|
end
|
|
40
45
|
end
|
|
41
|
-
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
def range(method_name_node, node)
|
|
45
|
-
range_between(method_name_node.loc.selector.begin_pos, node.source_range.end_pos)
|
|
46
|
-
end
|
|
47
46
|
end
|
|
48
47
|
end
|
|
49
48
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module InternalAffairs
|
|
6
|
+
# Checks for the use of `node.arguments.first` or `node.arguments.last` and
|
|
7
|
+
# suggests the use of `node.first_argument` or `node.last_argument` instead.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# # bad
|
|
11
|
+
# node.arguments.first
|
|
12
|
+
# node.arguments[0]
|
|
13
|
+
# node.arguments.last
|
|
14
|
+
# node.arguments[-1]
|
|
15
|
+
#
|
|
16
|
+
# # good
|
|
17
|
+
# node.first_argument
|
|
18
|
+
# node.last_argument
|
|
19
|
+
#
|
|
20
|
+
class NodeFirstOrLastArgument < Base
|
|
21
|
+
extend AutoCorrector
|
|
22
|
+
include RangeHelp
|
|
23
|
+
|
|
24
|
+
MSG = 'Use `#%<correct>s` instead of `#%<incorrect>s`.'
|
|
25
|
+
RESTRICT_ON_SEND = %i[arguments].freeze
|
|
26
|
+
|
|
27
|
+
# @!method arguments_first_or_last?(node)
|
|
28
|
+
def_node_matcher :arguments_first_or_last?, <<~PATTERN
|
|
29
|
+
{
|
|
30
|
+
(send (send !nil? :arguments) ${:first :last})
|
|
31
|
+
(send (send !nil? :arguments) :[] (int ${0 -1}))
|
|
32
|
+
}
|
|
33
|
+
PATTERN
|
|
34
|
+
|
|
35
|
+
def on_send(node)
|
|
36
|
+
arguments_first_or_last?(node.parent) do |end_or_index|
|
|
37
|
+
range = range_between(node.loc.selector.begin_pos, node.parent.source_range.end_pos)
|
|
38
|
+
correct = case end_or_index
|
|
39
|
+
when :first, 0 then 'first_argument'
|
|
40
|
+
when :last, -1 then 'last_argument'
|
|
41
|
+
else raise "Unknown end_or_index: #{end_or_index}"
|
|
42
|
+
end
|
|
43
|
+
message = format(MSG, correct: correct, incorrect: range.source)
|
|
44
|
+
|
|
45
|
+
add_offense(range, message: message) do |corrector|
|
|
46
|
+
corrector.replace(range, correct)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
|
40
40
|
return if node.arguments.none?
|
|
41
41
|
return unless valid_method_name?(node)
|
|
42
42
|
|
|
43
|
-
actual_name = node.
|
|
43
|
+
actual_name = node.first_argument.value
|
|
44
44
|
directives = method_directives(node)
|
|
45
45
|
return too_many_directives(node) if directives.size > 1
|
|
46
46
|
|
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
|
53
53
|
private
|
|
54
54
|
|
|
55
55
|
def valid_method_name?(node)
|
|
56
|
-
node.
|
|
56
|
+
node.first_argument.str_type? || node.first_argument.sym_type?
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def method_directives(node)
|
|
@@ -14,6 +14,12 @@ module RuboCop
|
|
|
14
14
|
# node.method_name
|
|
15
15
|
#
|
|
16
16
|
# # bad
|
|
17
|
+
# node.send_node.method?(:method_name)
|
|
18
|
+
#
|
|
19
|
+
# # good
|
|
20
|
+
# node.method?(:method_name)
|
|
21
|
+
#
|
|
22
|
+
# # bad
|
|
17
23
|
# node.send_node.receiver
|
|
18
24
|
#
|
|
19
25
|
# # good
|
|
@@ -24,11 +30,14 @@ module RuboCop
|
|
|
24
30
|
extend AutoCorrector
|
|
25
31
|
|
|
26
32
|
MSG = 'Remove the redundant `send_node`.'
|
|
27
|
-
RESTRICT_ON_SEND = %i[method_name receiver].freeze
|
|
33
|
+
RESTRICT_ON_SEND = %i[method_name method? receiver].freeze
|
|
28
34
|
|
|
29
35
|
# @!method dispatch_method(node)
|
|
30
36
|
def_node_matcher :dispatch_method, <<~PATTERN
|
|
31
|
-
|
|
37
|
+
{
|
|
38
|
+
(send $(send _ :send_node) {:method_name :receiver})
|
|
39
|
+
(send $(send _ :send_node) :method? _)
|
|
40
|
+
}
|
|
32
41
|
PATTERN
|
|
33
42
|
|
|
34
43
|
def on_send(node)
|
|
@@ -12,6 +12,7 @@ require_relative 'internal_affairs/location_line_equality_comparison'
|
|
|
12
12
|
require_relative 'internal_affairs/method_name_end_with'
|
|
13
13
|
require_relative 'internal_affairs/method_name_equal'
|
|
14
14
|
require_relative 'internal_affairs/node_destructuring'
|
|
15
|
+
require_relative 'internal_affairs/node_first_or_last_argument'
|
|
15
16
|
require_relative 'internal_affairs/node_matcher_directive'
|
|
16
17
|
require_relative 'internal_affairs/node_type_predicate'
|
|
17
18
|
require_relative 'internal_affairs/numblock_handler'
|
|
@@ -32,7 +32,7 @@ module RuboCop
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def on_send(node)
|
|
35
|
-
return unless node.dot? ||
|
|
35
|
+
return unless node.dot? || node.safe_navigation?
|
|
36
36
|
|
|
37
37
|
return correct_style_detected if proper_dot_position?(node)
|
|
38
38
|
|
|
@@ -133,10 +133,6 @@ module RuboCop
|
|
|
133
133
|
# l.(1) has no selector, so we use the opening parenthesis instead
|
|
134
134
|
node.loc.selector || node.loc.begin
|
|
135
135
|
end
|
|
136
|
-
|
|
137
|
-
def ampersand_dot?(node)
|
|
138
|
-
node.loc.respond_to?(:dot) && node.loc.dot && node.loc.dot.is?('&.')
|
|
139
|
-
end
|
|
140
136
|
end
|
|
141
137
|
end
|
|
142
138
|
end
|
|
@@ -3,7 +3,23 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Layout
|
|
6
|
-
# Enforces empty line after guard clause
|
|
6
|
+
# Enforces empty line after guard clause.
|
|
7
|
+
#
|
|
8
|
+
# This cop allows `# :nocov:` directive after guard clause because
|
|
9
|
+
# SimpleCov excludes code from the coverage report by wrapping it in `# :nocov:`:
|
|
10
|
+
#
|
|
11
|
+
# [source,ruby]
|
|
12
|
+
# ----
|
|
13
|
+
# def foo
|
|
14
|
+
# # :nocov:
|
|
15
|
+
# return if condition
|
|
16
|
+
# # :nocov:
|
|
17
|
+
# bar
|
|
18
|
+
# end
|
|
19
|
+
# ----
|
|
20
|
+
#
|
|
21
|
+
# Refer to SimpleCov's documentation for more details:
|
|
22
|
+
# https://github.com/simplecov-ruby/simplecov#ignoringskipping-code
|
|
7
23
|
#
|
|
8
24
|
# @example
|
|
9
25
|
#
|
|
@@ -42,19 +58,22 @@ module RuboCop
|
|
|
42
58
|
|
|
43
59
|
MSG = 'Add empty line after guard clause.'
|
|
44
60
|
END_OF_HEREDOC_LINE = 1
|
|
61
|
+
SIMPLE_DIRECTIVE_COMMENT_PATTERN = /\A# *:nocov:\z/.freeze
|
|
45
62
|
|
|
46
63
|
def on_if(node)
|
|
47
64
|
return if correct_style?(node)
|
|
48
65
|
return if multiple_statements_on_line?(node)
|
|
49
66
|
|
|
50
67
|
if node.modifier_form? && (heredoc_node = last_heredoc_argument(node))
|
|
51
|
-
|
|
68
|
+
if next_line_empty_or_allowed_directive_comment?(heredoc_line(node, heredoc_node))
|
|
69
|
+
return
|
|
70
|
+
end
|
|
52
71
|
|
|
53
72
|
add_offense(heredoc_node.loc.heredoc_end) do |corrector|
|
|
54
73
|
autocorrect(corrector, heredoc_node)
|
|
55
74
|
end
|
|
56
75
|
else
|
|
57
|
-
return if
|
|
76
|
+
return if next_line_empty_or_allowed_directive_comment?(node.last_line)
|
|
58
77
|
|
|
59
78
|
add_offense(offense_location(node)) { |corrector| autocorrect(corrector, node) }
|
|
60
79
|
end
|
|
@@ -70,7 +89,7 @@ module RuboCop
|
|
|
70
89
|
end
|
|
71
90
|
|
|
72
91
|
next_line = node_range.last_line + 1
|
|
73
|
-
if
|
|
92
|
+
if next_line_allowed_directive_comment?(next_line)
|
|
74
93
|
node_range = processed_source.comment_at_line(next_line)
|
|
75
94
|
end
|
|
76
95
|
|
|
@@ -88,21 +107,21 @@ module RuboCop
|
|
|
88
107
|
node.if_branch&.guard_clause?
|
|
89
108
|
end
|
|
90
109
|
|
|
91
|
-
def
|
|
110
|
+
def next_line_empty_or_allowed_directive_comment?(line)
|
|
92
111
|
return true if next_line_empty?(line)
|
|
93
112
|
|
|
94
113
|
next_line = line + 1
|
|
95
|
-
|
|
114
|
+
next_line_allowed_directive_comment?(next_line) && next_line_empty?(next_line)
|
|
96
115
|
end
|
|
97
116
|
|
|
98
117
|
def next_line_empty?(line)
|
|
99
118
|
processed_source[line].blank?
|
|
100
119
|
end
|
|
101
120
|
|
|
102
|
-
def
|
|
121
|
+
def next_line_allowed_directive_comment?(line)
|
|
103
122
|
return false unless (comment = processed_source.comment_at_line(line))
|
|
104
123
|
|
|
105
|
-
DirectiveComment.new(comment).enabled?
|
|
124
|
+
DirectiveComment.new(comment).enabled? || simplecov_directive_comment?(comment)
|
|
106
125
|
end
|
|
107
126
|
|
|
108
127
|
def next_line_rescue_or_ensure?(node)
|
|
@@ -137,7 +156,7 @@ module RuboCop
|
|
|
137
156
|
return node if node
|
|
138
157
|
end
|
|
139
158
|
|
|
140
|
-
|
|
159
|
+
last_heredoc_argument(n.receiver) if n.respond_to?(:receiver)
|
|
141
160
|
end
|
|
142
161
|
|
|
143
162
|
def last_heredoc_argument_node(node)
|
|
@@ -145,6 +164,8 @@ module RuboCop
|
|
|
145
164
|
|
|
146
165
|
if node.if_branch.and_type?
|
|
147
166
|
node.if_branch.children.first
|
|
167
|
+
elsif use_heredoc_in_condition?(node.condition)
|
|
168
|
+
node.condition
|
|
148
169
|
else
|
|
149
170
|
node.if_branch.children.last
|
|
150
171
|
end
|
|
@@ -161,6 +182,12 @@ module RuboCop
|
|
|
161
182
|
node.respond_to?(:heredoc?) && node.heredoc?
|
|
162
183
|
end
|
|
163
184
|
|
|
185
|
+
def use_heredoc_in_condition?(condition)
|
|
186
|
+
condition.descendants.any? do |descendant|
|
|
187
|
+
descendant.respond_to?(:heredoc?) && descendant.heredoc?
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
164
191
|
def offense_location(node)
|
|
165
192
|
if node.loc.respond_to?(:end) && node.loc.end
|
|
166
193
|
node.loc.end
|
|
@@ -175,6 +202,12 @@ module RuboCop
|
|
|
175
202
|
|
|
176
203
|
parent.begin_type? && parent.single_line?
|
|
177
204
|
end
|
|
205
|
+
|
|
206
|
+
# SimpleCov excludes code from the coverage report by wrapping it in `# :nocov:`:
|
|
207
|
+
# https://github.com/simplecov-ruby/simplecov#ignoringskipping-code
|
|
208
|
+
def simplecov_directive_comment?(comment)
|
|
209
|
+
SIMPLE_DIRECTIVE_COMMENT_PATTERN.match?(comment.text)
|
|
210
|
+
end
|
|
178
211
|
end
|
|
179
212
|
end
|
|
180
213
|
end
|
|
@@ -135,7 +135,8 @@ module RuboCop
|
|
|
135
135
|
return if nodes.all?(&:single_line?) && cop_config['AllowAdjacentOneLineDefs']
|
|
136
136
|
|
|
137
137
|
correction_node = nodes.last
|
|
138
|
-
|
|
138
|
+
|
|
139
|
+
location = def_location(correction_node)
|
|
139
140
|
add_offense(location, message: message(correction_node, count: count)) do |corrector|
|
|
140
141
|
autocorrect(corrector, *nodes, count)
|
|
141
142
|
end
|
|
@@ -159,10 +160,28 @@ module RuboCop
|
|
|
159
160
|
|
|
160
161
|
private
|
|
161
162
|
|
|
163
|
+
def def_location(correction_node)
|
|
164
|
+
if correction_node.block_type?
|
|
165
|
+
correction_node.source_range.join(correction_node.children.first.source_range)
|
|
166
|
+
else
|
|
167
|
+
correction_node.loc.keyword.join(correction_node.loc.name)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
162
171
|
def candidate?(node)
|
|
163
172
|
return false unless node
|
|
164
173
|
|
|
165
|
-
method_candidate?(node) || class_candidate?(node) || module_candidate?(node)
|
|
174
|
+
method_candidate?(node) || class_candidate?(node) || module_candidate?(node) ||
|
|
175
|
+
macro_candidate?(node)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def empty_line_between_macros
|
|
179
|
+
cop_config.fetch('DefLikeMacros', []).map(&:to_sym)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def macro_candidate?(node)
|
|
183
|
+
node.block_type? && node.children.first.macro? &&
|
|
184
|
+
empty_line_between_macros.include?(node.children.first.method_name)
|
|
166
185
|
end
|
|
167
186
|
|
|
168
187
|
def method_candidate?(node)
|
|
@@ -226,7 +245,11 @@ module RuboCop
|
|
|
226
245
|
end
|
|
227
246
|
|
|
228
247
|
def def_start(node)
|
|
229
|
-
node.
|
|
248
|
+
if node.block_type? && node.children.first.send_type?
|
|
249
|
+
node.source_range.line
|
|
250
|
+
else
|
|
251
|
+
node.loc.keyword.line
|
|
252
|
+
end
|
|
230
253
|
end
|
|
231
254
|
|
|
232
255
|
def def_end(node)
|
|
@@ -83,7 +83,11 @@ module RuboCop
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def on_sclass(node)
|
|
86
|
-
|
|
86
|
+
if node.parent&.assignment?
|
|
87
|
+
check_asgn_alignment(node.parent, node)
|
|
88
|
+
else
|
|
89
|
+
check_other_alignment(node)
|
|
90
|
+
end
|
|
87
91
|
end
|
|
88
92
|
|
|
89
93
|
def on_module(node)
|
|
@@ -163,7 +167,13 @@ module RuboCop
|
|
|
163
167
|
when :keyword
|
|
164
168
|
node
|
|
165
169
|
when :variable
|
|
166
|
-
alignment_node_for_variable_style(node)
|
|
170
|
+
align_to = alignment_node_for_variable_style(node)
|
|
171
|
+
|
|
172
|
+
while (parent = align_to.parent) && parent.send_type? && same_line?(align_to, parent)
|
|
173
|
+
align_to = parent
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
align_to
|
|
167
177
|
else
|
|
168
178
|
start_line_range(node)
|
|
169
179
|
end
|
|
@@ -49,19 +49,13 @@ module RuboCop
|
|
|
49
49
|
|
|
50
50
|
private
|
|
51
51
|
|
|
52
|
-
def aligned_locations(locs)
|
|
52
|
+
def aligned_locations(locs)
|
|
53
53
|
return [] if locs.empty?
|
|
54
54
|
|
|
55
|
-
aligned = Set
|
|
56
|
-
locs.each_cons(
|
|
57
|
-
|
|
58
|
-
aligned << loc.line if col == before.column || col == after.column
|
|
55
|
+
aligned = Set.new
|
|
56
|
+
locs.each_cons(2) do |loc1, loc2|
|
|
57
|
+
aligned << loc1.line << loc2.line if loc1.column == loc2.column
|
|
59
58
|
end
|
|
60
|
-
|
|
61
|
-
# if locs.size > 2 and the size of variable `aligned`
|
|
62
|
-
# has not increased from its initial value, there are not aligned lines.
|
|
63
|
-
return [] if locs.size > 2 && aligned.size == 2
|
|
64
|
-
|
|
65
59
|
aligned
|
|
66
60
|
end
|
|
67
61
|
|