rubocop 1.59.0 → 1.65.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 +3 -4
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +93 -17
- data/lib/rubocop/cached_data.rb +11 -3
- data/lib/rubocop/cli/command/auto_generate_config.rb +12 -3
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
- data/lib/rubocop/cli.rb +10 -1
- data/lib/rubocop/config.rb +36 -12
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +9 -3
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +63 -16
- data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
- data/lib/rubocop/cop/cop.rb +22 -4
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
- data/lib/rubocop/cop/documentation.rb +16 -6
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/force.rb +12 -0
- data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +122 -28
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/condition_position.rb +0 -4
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +8 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -1
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +20 -20
- data/lib/rubocop/cop/layout/redundant_line_break.rb +14 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +3 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
- data/lib/rubocop/cop/legacy/corrector.rb +12 -2
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +0 -2
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
- data/lib/rubocop/cop/lint/boolean_symbol.rb +0 -2
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
- data/lib/rubocop/cop/lint/debugger.rb +27 -6
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -10
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
- data/lib/rubocop/cop/lint/else_layout.rb +0 -2
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
- data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
- data/lib/rubocop/cop/lint/empty_when.rb +1 -3
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -6
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +21 -14
- data/lib/rubocop/cop/lint/float_comparison.rb +3 -1
- data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +15 -12
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +13 -6
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +0 -4
- data/lib/rubocop/cop/lint/loop.rb +6 -12
- data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +0 -4
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
- data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
- data/lib/rubocop/cop/lint/rand_one.rb +0 -4
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +14 -9
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +0 -4
- data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
- data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +0 -4
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +6 -10
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
- data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
- data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -5
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +11 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
- data/lib/rubocop/cop/mixin/code_length.rb +12 -1
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +9 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +32 -5
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
- data/lib/rubocop/cop/naming/predicate_name.rb +54 -28
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -1
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/compound_hash.rb +2 -2
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +50 -0
- data/lib/rubocop/cop/style/alias.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +89 -17
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +14 -5
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -7
- data/lib/rubocop/cop/style/copyright.rb +31 -21
- data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
- data/lib/rubocop/cop/style/documentation.rb +24 -24
- data/lib/rubocop/cop/style/documentation_method.rb +20 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
- data/lib/rubocop/cop/style/eval_with_location.rb +15 -23
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
- data/lib/rubocop/cop/style/file_read.rb +2 -5
- data/lib/rubocop/cop/style/file_write.rb +2 -5
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string.rb +9 -9
- data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +29 -8
- data/lib/rubocop/cop/style/hash_except.rb +8 -5
- data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -8
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +46 -4
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +81 -50
- data/lib/rubocop/cop/style/map_into_array.rb +175 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +10 -6
- data/lib/rubocop/cop/style/map_to_set.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/missing_else.rb +0 -4
- data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +25 -2
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +0 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +17 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -2
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -24
- data/lib/rubocop/cop/style/redundant_return.rb +6 -0
- data/lib/rubocop/cop/style/require_order.rb +1 -1
- data/lib/rubocop/cop/style/sample.rb +1 -3
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -2
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/super_arguments.rb +174 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/while_until_do.rb +0 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
- data/lib/rubocop/cop/team.rb +13 -0
- data/lib/rubocop/cop/util.rb +7 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +13 -1
- data/lib/rubocop/cops_documentation_generator.rb +16 -4
- data/lib/rubocop/core_ext/string.rb +2 -6
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +18 -35
- data/lib/rubocop/ext/regexp_parser.rb +4 -21
- data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
- data/lib/rubocop/formatter/formatter_set.rb +7 -1
- data/lib/rubocop/formatter/html_formatter.rb +32 -10
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter/tap_formatter.rb +3 -7
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +56 -7
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +12 -15
- data/lib/rubocop/lsp/runtime.rb +1 -1
- data/lib/rubocop/lsp/server.rb +7 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +17 -12
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +16 -8
- data/lib/rubocop/rspec/shared_contexts.rb +73 -16
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +14 -3
- data/lib/rubocop/server/cache.rb +11 -2
- data/lib/rubocop/server/client_command/exec.rb +2 -3
- data/lib/rubocop/server/client_command/start.rb +1 -1
- data/lib/rubocop/server/core.rb +4 -0
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +82 -80
- data/lib/rubocop/version.rb +19 -4
- data/lib/rubocop.rb +9 -0
- metadata +18 -11
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -26,10 +26,18 @@ module RuboCop
|
|
26
26
|
MSG = 'Precede `%<method>s` with a `@!method` YARD directive.'
|
27
27
|
MSG_WRONG_NAME = '`@!method` YARD directive has invalid method name, ' \
|
28
28
|
'use `%<expected>s` instead of `%<actual>s`.'
|
29
|
+
MSG_MISSING_SCOPE_SELF = 'Follow the `@!method` YARD directive with ' \
|
30
|
+
'`@!scope class` if it is a class method.'
|
31
|
+
MSG_WRONG_SCOPE_SELF = 'Do not use the `@!scope class` YARD directive if it ' \
|
32
|
+
'is not a class method.'
|
29
33
|
MSG_TOO_MANY = 'Multiple `@!method` YARD directives found for this matcher.'
|
30
34
|
|
31
35
|
RESTRICT_ON_SEND = %i[def_node_matcher def_node_search].to_set.freeze
|
32
|
-
|
36
|
+
REGEXP_METHOD = /
|
37
|
+
^\s*\#\s*
|
38
|
+
@!method\s+(?<receiver>self\.)?(?<method_name>[a-z0-9_]+[?!]?)(?:\((?<args>.*)\))?
|
39
|
+
/x.freeze
|
40
|
+
REGEXP_SCOPE = /^\s*\#\s*@!scope class/.freeze
|
33
41
|
|
34
42
|
# @!method pattern_matcher?(node)
|
35
43
|
def_node_matcher :pattern_matcher?, <<~PATTERN
|
@@ -40,14 +48,15 @@ module RuboCop
|
|
40
48
|
return if node.arguments.none?
|
41
49
|
return unless valid_method_name?(node)
|
42
50
|
|
43
|
-
actual_name = node.first_argument.value
|
51
|
+
actual_name = node.first_argument.value.to_s
|
52
|
+
|
53
|
+
# Ignore cases where the method has a receiver that isn't self
|
54
|
+
return if actual_name.include?('.') && !actual_name.start_with?('self.')
|
55
|
+
|
44
56
|
directives = method_directives(node)
|
45
57
|
return too_many_directives(node) if directives.size > 1
|
46
58
|
|
47
|
-
|
48
|
-
return if directive_correct?(directive, actual_name)
|
49
|
-
|
50
|
-
register_offense(node, directive, actual_name)
|
59
|
+
process_directive(node, actual_name, directives.first)
|
51
60
|
end
|
52
61
|
|
53
62
|
private
|
@@ -58,44 +67,112 @@ module RuboCop
|
|
58
67
|
|
59
68
|
def method_directives(node)
|
60
69
|
comments = processed_source.ast_with_comments[node]
|
61
|
-
|
62
|
-
|
63
|
-
match = comment.text.match(REGEXP)
|
70
|
+
group_comments(comments).filter_map do |comment_method, comment_scope|
|
71
|
+
match = comment_method.text.match(REGEXP_METHOD)
|
64
72
|
next unless match
|
65
73
|
|
66
|
-
{
|
74
|
+
{
|
75
|
+
node_method: comment_method,
|
76
|
+
node_scope: comment_scope,
|
77
|
+
method_name: match[:method_name],
|
78
|
+
args: match[:args],
|
79
|
+
receiver: match[:receiver],
|
80
|
+
has_scope_directive: comment_scope&.text&.match?(REGEXP_SCOPE)
|
81
|
+
}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def group_comments(comments)
|
86
|
+
result = []
|
87
|
+
comments.each.with_index do |comment, index|
|
88
|
+
# Grab the scope directive if it is preceded by a method directive
|
89
|
+
if comment.text.include?('@!method')
|
90
|
+
result << if (next_comment = comments[index + 1])&.text&.include?('@!scope')
|
91
|
+
[comment, next_comment]
|
92
|
+
else
|
93
|
+
[comment, nil]
|
94
|
+
end
|
95
|
+
end
|
67
96
|
end
|
97
|
+
result
|
68
98
|
end
|
69
99
|
|
70
100
|
def too_many_directives(node)
|
71
101
|
add_offense(node, message: MSG_TOO_MANY)
|
72
102
|
end
|
73
103
|
|
74
|
-
def
|
75
|
-
|
104
|
+
def process_directive(node, actual_name, directive)
|
105
|
+
return unless (offense_type = directive_offense_type(directive, actual_name))
|
106
|
+
|
107
|
+
register_offense(offense_type, node, directive, actual_name)
|
108
|
+
end
|
109
|
+
|
110
|
+
def directive_offense_type(directive, actual_name)
|
111
|
+
return :missing_directive unless directive
|
112
|
+
|
113
|
+
return :wrong_scope if wrong_scope(directive, actual_name)
|
114
|
+
return :no_scope if no_scope(directive, actual_name)
|
115
|
+
|
116
|
+
# The method directive being prefixed by 'self.' is always an offense.
|
117
|
+
# The matched method_name does not contain the receiver but the
|
118
|
+
# def_node_match method name may so it must be removed.
|
119
|
+
if directive[:method_name] != remove_receiver(actual_name) || directive[:receiver]
|
120
|
+
:wrong_name
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def wrong_scope(directive, actual_name)
|
125
|
+
!actual_name.start_with?('self.') && directive[:has_scope_directive]
|
126
|
+
end
|
127
|
+
|
128
|
+
def no_scope(directive, actual_name)
|
129
|
+
actual_name.start_with?('self.') && !directive[:has_scope_directive]
|
76
130
|
end
|
77
131
|
|
78
|
-
def register_offense(node, directive, actual_name)
|
79
|
-
message = formatted_message(directive, actual_name, node.method_name)
|
132
|
+
def register_offense(offense_type, node, directive, actual_name)
|
133
|
+
message = formatted_message(offense_type, directive, actual_name, node.method_name)
|
80
134
|
|
81
135
|
add_offense(node, message: message) do |corrector|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
136
|
+
case offense_type
|
137
|
+
when :wrong_name
|
138
|
+
correct_method_directive(corrector, directive, actual_name)
|
139
|
+
when :wrong_scope
|
140
|
+
remove_scope_directive(corrector, directive)
|
141
|
+
when :no_scope
|
142
|
+
insert_scope_directive(corrector, directive[:node_method])
|
143
|
+
when :missing_directive
|
144
|
+
insert_method_directive(corrector, node, actual_name)
|
86
145
|
end
|
87
146
|
end
|
88
147
|
end
|
89
148
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
149
|
+
# rubocop:disable Metrics/MethodLength
|
150
|
+
def formatted_message(offense_type, directive, actual_name, method_name)
|
151
|
+
case offense_type
|
152
|
+
when :wrong_name
|
153
|
+
# Add the receiver to the name when showing an offense
|
154
|
+
current_name = if directive[:receiver]
|
155
|
+
directive[:receiver] + directive[:method_name]
|
156
|
+
else
|
157
|
+
directive[:method_name]
|
158
|
+
end
|
159
|
+
# The correct name will never include a receiver, remove it
|
160
|
+
format(MSG_WRONG_NAME, expected: remove_receiver(actual_name), actual: current_name)
|
161
|
+
when :wrong_scope
|
162
|
+
MSG_WRONG_SCOPE_SELF
|
163
|
+
when :no_scope
|
164
|
+
MSG_MISSING_SCOPE_SELF
|
165
|
+
when :missing_directive
|
94
166
|
format(MSG, method: method_name)
|
95
167
|
end
|
96
168
|
end
|
169
|
+
# rubocop:enable Metrics/MethodLength
|
170
|
+
|
171
|
+
def remove_receiver(current)
|
172
|
+
current.delete_prefix('self.')
|
173
|
+
end
|
97
174
|
|
98
|
-
def
|
175
|
+
def insert_method_directive(corrector, node, actual_name)
|
99
176
|
# If the pattern matcher uses arguments (`%1`, `%2`, etc.), include them in the directive
|
100
177
|
arguments = pattern_arguments(node.arguments[1].source)
|
101
178
|
|
@@ -107,6 +184,14 @@ module RuboCop
|
|
107
184
|
corrector.insert_before(range, directive)
|
108
185
|
end
|
109
186
|
|
187
|
+
def insert_scope_directive(corrector, node)
|
188
|
+
range = range_with_surrounding_space(node.source_range, side: :left, newlines: false)
|
189
|
+
indentation = range.source.match(/^\s*/)[0]
|
190
|
+
directive = "\n#{indentation}# @!scope class"
|
191
|
+
|
192
|
+
corrector.insert_after(node, directive)
|
193
|
+
end
|
194
|
+
|
110
195
|
def pattern_arguments(pattern)
|
111
196
|
arguments = %w[node]
|
112
197
|
max_pattern_var = pattern.scan(/(?<=%)\d+/).map(&:to_i).max
|
@@ -134,12 +219,21 @@ module RuboCop
|
|
134
219
|
end
|
135
220
|
end
|
136
221
|
|
137
|
-
def
|
138
|
-
correct = "@!method #{actual_name}"
|
139
|
-
|
222
|
+
def correct_method_directive(corrector, directive, actual_name)
|
223
|
+
correct = "@!method #{remove_receiver(actual_name)}"
|
224
|
+
current_name = (directive[:receiver] || '') + directive[:method_name]
|
225
|
+
regexp = /@!method\s+#{Regexp.escape(current_name)}/
|
226
|
+
|
227
|
+
replacement = directive[:node_method].text.gsub(regexp, correct)
|
228
|
+
corrector.replace(directive[:node_method], replacement)
|
229
|
+
end
|
140
230
|
|
141
|
-
|
142
|
-
|
231
|
+
def remove_scope_directive(corrector, directive)
|
232
|
+
range = range_by_whole_lines(
|
233
|
+
directive[:node_scope].source_range,
|
234
|
+
include_final_newline: true
|
235
|
+
)
|
236
|
+
corrector.remove(range)
|
143
237
|
end
|
144
238
|
end
|
145
239
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Checks for redundant arguments of `RuboCop::RSpec::ExpectOffense`'s methods.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# expect_no_offenses('code', keyword: keyword)
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# expect_no_offenses('code')
|
15
|
+
#
|
16
|
+
class RedundantExpectOffenseArguments < Base
|
17
|
+
extend AutoCorrector
|
18
|
+
|
19
|
+
MSG = 'Remove the redundant arguments.'
|
20
|
+
RESTRICT_ON_SEND = %i[expect_no_offenses].freeze
|
21
|
+
|
22
|
+
def on_send(node)
|
23
|
+
return if node.arguments.one? || !node.arguments[1]&.hash_type?
|
24
|
+
|
25
|
+
range = node.first_argument.source_range.end.join(node.last_argument.source_range.end)
|
26
|
+
|
27
|
+
add_offense(range) do |corrector|
|
28
|
+
corrector.remove(range)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -20,6 +20,7 @@ require_relative 'internal_affairs/offense_location_keyword'
|
|
20
20
|
require_relative 'internal_affairs/processed_source_buffer_name'
|
21
21
|
require_relative 'internal_affairs/redundant_context_config_parameter'
|
22
22
|
require_relative 'internal_affairs/redundant_described_class_as_subject'
|
23
|
+
require_relative 'internal_affairs/redundant_expect_offense_arguments'
|
23
24
|
require_relative 'internal_affairs/redundant_let_rubocop_config_new'
|
24
25
|
require_relative 'internal_affairs/redundant_location_argument'
|
25
26
|
require_relative 'internal_affairs/redundant_message_argument'
|
@@ -6,6 +6,9 @@ module RuboCop
|
|
6
6
|
# Checks the indentation of the first line of the
|
7
7
|
# right-hand-side of a multi-line assignment.
|
8
8
|
#
|
9
|
+
# The indentation of the remaining lines can be corrected with
|
10
|
+
# other cops such as `Layout/IndentationConsistency` and `Layout/EndAlignment`.
|
11
|
+
#
|
9
12
|
# @example
|
10
13
|
# # bad
|
11
14
|
# value =
|
@@ -19,8 +22,6 @@ module RuboCop
|
|
19
22
|
# 'bar'
|
20
23
|
# end
|
21
24
|
#
|
22
|
-
# The indentation of the remaining lines can be corrected with
|
23
|
-
# other cops such as `IndentationConsistency` and `EndAlignment`.
|
24
25
|
class AssignmentIndentation < Base
|
25
26
|
include CheckAssignment
|
26
27
|
include Alignment
|
@@ -121,7 +121,7 @@ module RuboCop
|
|
121
121
|
return if case_node.single_line?
|
122
122
|
return if enforced_style_end? && end_and_last_conditional_same_line?(case_node)
|
123
123
|
|
124
|
-
case_node.
|
124
|
+
case_node.when_branches.each { |when_node| check_when(when_node, 'when') }
|
125
125
|
end
|
126
126
|
|
127
127
|
def on_case_match(case_match_node)
|
@@ -106,7 +106,9 @@ module RuboCop
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def concat_consecutive_comments(comments)
|
109
|
-
consecutive_comments = comments.chunk_while
|
109
|
+
consecutive_comments = comments.chunk_while do |i, j|
|
110
|
+
i.loc.line.succ == j.loc.line && i.loc.column == j.loc.column
|
111
|
+
end
|
110
112
|
|
111
113
|
consecutive_comments.map do |chunk|
|
112
114
|
joined_text = chunk.map { |c| comment_text(c) }.join
|
@@ -27,9 +27,9 @@ module RuboCop
|
|
27
27
|
MSG = 'Add an empty line after magic comments.'
|
28
28
|
|
29
29
|
def on_new_investigation
|
30
|
-
return unless processed_source
|
31
|
-
|
32
|
-
return if
|
30
|
+
return unless (last_magic_comment = last_magic_comment(processed_source))
|
31
|
+
return unless (next_line = processed_source[last_magic_comment.loc.line])
|
32
|
+
return if next_line.strip.empty?
|
33
33
|
|
34
34
|
offending_range = offending_range(last_magic_comment)
|
35
35
|
|
@@ -46,18 +46,25 @@ module RuboCop
|
|
46
46
|
|
47
47
|
# Find the last magic comment in the source file.
|
48
48
|
#
|
49
|
-
# Take all comments that precede the first line of code
|
49
|
+
# Take all comments that precede the first line of code (or just take
|
50
|
+
# them all in the case when there is no code), select the
|
50
51
|
# magic comments, and return the last magic comment in the file.
|
51
52
|
#
|
52
53
|
# @return [Parser::Source::Comment] if magic comments exist before code
|
53
54
|
# @return [nil] otherwise
|
54
55
|
def last_magic_comment(source)
|
55
|
-
source
|
56
|
-
.comments
|
57
|
-
.take_while { |comment| comment.loc.line < source.ast.loc.line }
|
56
|
+
comments_before_code(source)
|
58
57
|
.reverse
|
59
58
|
.find { |comment| MagicComment.parse(comment.text).any? }
|
60
59
|
end
|
60
|
+
|
61
|
+
def comments_before_code(source)
|
62
|
+
if source.ast
|
63
|
+
source.comments.take_while { |comment| comment.loc.line < source.ast.loc.line }
|
64
|
+
else
|
65
|
+
source.comments
|
66
|
+
end
|
67
|
+
end
|
61
68
|
end
|
62
69
|
end
|
63
70
|
end
|
@@ -20,7 +20,9 @@ module RuboCop
|
|
20
20
|
# This `Layout/EndAlignment` cop aligns with keywords (e.g. `if`, `while`, `case`)
|
21
21
|
# by default. On the other hand, `Layout/BeginEndAlignment` cop aligns with
|
22
22
|
# `EnforcedStyleAlignWith: start_of_line` by default due to `||= begin` tends
|
23
|
-
# to align with the start of the line.
|
23
|
+
# to align with the start of the line. `Layout/DefEndAlignment` cop also aligns with
|
24
|
+
# `EnforcedStyleAlignWith: start_of_line` by default.
|
25
|
+
# These style can be configured by each cop.
|
24
26
|
#
|
25
27
|
# @example EnforcedStyleAlignWith: keyword (default)
|
26
28
|
# # bad
|
@@ -83,7 +85,11 @@ module RuboCop
|
|
83
85
|
end
|
84
86
|
|
85
87
|
def on_sclass(node)
|
86
|
-
|
88
|
+
if node.parent&.assignment?
|
89
|
+
check_asgn_alignment(node.parent, node)
|
90
|
+
else
|
91
|
+
check_other_alignment(node)
|
92
|
+
end
|
87
93
|
end
|
88
94
|
|
89
95
|
def on_module(node)
|
@@ -118,8 +118,8 @@ module RuboCop
|
|
118
118
|
#
|
119
119
|
# @example EnforcedStyle: special_for_inner_method_call
|
120
120
|
# # The first argument should normally be indented one step more than
|
121
|
-
# # the preceding line, but if it's
|
122
|
-
# # is itself
|
121
|
+
# # the preceding line, but if it's an argument for a method call that
|
122
|
+
# # is itself an argument in a method call, then the inner argument
|
123
123
|
# # should be indented relative to the inner method.
|
124
124
|
#
|
125
125
|
# # good
|
@@ -5,7 +5,10 @@ module RuboCop
|
|
5
5
|
module Layout
|
6
6
|
# Checks the indentation of the first element in an array literal
|
7
7
|
# where the opening bracket and the first element are on separate lines.
|
8
|
-
# The other elements' indentations are handled by
|
8
|
+
# The other elements' indentations are handled by `Layout/ArrayAlignment` cop.
|
9
|
+
#
|
10
|
+
# This cop will respect `Layout/ArrayAlignment` and will not work when
|
11
|
+
# `EnforcedStyle: with_fixed_indentation` is specified for `Layout/ArrayAlignment`.
|
9
12
|
#
|
10
13
|
# By default, array literals that are arguments in a method call with
|
11
14
|
# parentheses, and where the opening square bracket of the array is on the
|
@@ -89,10 +92,14 @@ module RuboCop
|
|
89
92
|
'in an array, relative to %<base_description>s.'
|
90
93
|
|
91
94
|
def on_array(node)
|
95
|
+
return if style != :consistent && enforce_first_argument_with_fixed_indentation?
|
96
|
+
|
92
97
|
check(node, nil) if node.loc.begin
|
93
98
|
end
|
94
99
|
|
95
100
|
def on_send(node)
|
101
|
+
return if style != :consistent && enforce_first_argument_with_fixed_indentation?
|
102
|
+
|
96
103
|
each_argument_node(node, :array) do |array_node, left_parenthesis|
|
97
104
|
check(array_node, left_parenthesis)
|
98
105
|
end
|
@@ -174,6 +181,16 @@ module RuboCop
|
|
174
181
|
'where the left bracket is.'
|
175
182
|
end
|
176
183
|
end
|
184
|
+
|
185
|
+
def enforce_first_argument_with_fixed_indentation?
|
186
|
+
return false unless array_alignment_config['Enabled']
|
187
|
+
|
188
|
+
array_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
189
|
+
end
|
190
|
+
|
191
|
+
def array_alignment_config
|
192
|
+
config.for_cop('Layout/ArrayAlignment')
|
193
|
+
end
|
177
194
|
end
|
178
195
|
end
|
179
196
|
end
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Checks the indentation of the here document bodies. The bodies
|
7
7
|
# are indented one step.
|
8
8
|
#
|
9
|
-
#
|
9
|
+
# NOTE: When ``Layout/LineLength``'s `AllowHeredoc` is false (not default),
|
10
10
|
# this cop does not add any offenses for long here documents to
|
11
11
|
# avoid ``Layout/LineLength``'s offenses.
|
12
12
|
#
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
107
107
|
return false unless line.end_with?("\\\n")
|
108
108
|
|
109
109
|
# Ensure backslash isn't part of a token spanning to the next line.
|
110
|
-
node.children.none? { |c| c.first_line
|
110
|
+
node.children.none? { |c| (c.first_line...c.last_line).cover?(line_num) && c.multiline? }
|
111
111
|
end
|
112
112
|
|
113
113
|
def autocorrect(corrector, offense_range, insert_pos, spaces)
|
@@ -17,29 +17,29 @@ module RuboCop
|
|
17
17
|
# split across lines. These include arrays, hashes, and
|
18
18
|
# method calls with argument lists.
|
19
19
|
#
|
20
|
-
# If autocorrection is enabled, the following
|
20
|
+
# If autocorrection is enabled, the following cops
|
21
21
|
# are recommended to further format the broken lines.
|
22
22
|
# (Many of these are enabled by default.)
|
23
23
|
#
|
24
|
-
# * ArgumentAlignment
|
25
|
-
# * ArrayAlignment
|
26
|
-
# * BlockAlignment
|
27
|
-
# *
|
28
|
-
# *
|
29
|
-
# *
|
30
|
-
# *
|
31
|
-
# *
|
32
|
-
# *
|
33
|
-
# *
|
34
|
-
# *
|
35
|
-
# *
|
36
|
-
# *
|
37
|
-
# *
|
38
|
-
# *
|
39
|
-
# *
|
40
|
-
# *
|
41
|
-
# *
|
42
|
-
# *
|
24
|
+
# * `Layout/ArgumentAlignment`
|
25
|
+
# * `Layout/ArrayAlignment`
|
26
|
+
# * `Layout/BlockAlignment`
|
27
|
+
# * `Layout/BlockEndNewline`
|
28
|
+
# * `LayoutClosingParenthesisIndentation`
|
29
|
+
# * `LayoutFirstArgumentIndentation`
|
30
|
+
# * `LayoutFirstArrayElementIndentation`
|
31
|
+
# * `LayoutFirstHashElementIndentation`
|
32
|
+
# * `LayoutFirstParameterIndentation`
|
33
|
+
# * `LayoutHashAlignment`
|
34
|
+
# * `LayoutIndentationWidth`
|
35
|
+
# * `LayoutMultilineArrayLineBreaks`
|
36
|
+
# * `LayoutMultilineBlockLayout`
|
37
|
+
# * `LayoutMultilineHashBraceLayout`
|
38
|
+
# * `LayoutMultilineHashKeyLineBreaks`
|
39
|
+
# * `LayoutMultilineMethodArgumentLineBreaks`
|
40
|
+
# * `LayoutMultilineMethodParameterLineBreaks`
|
41
|
+
# * `Layout/ParameterAlignment`
|
42
|
+
# * `Style/BlockDelimiters`
|
43
43
|
#
|
44
44
|
# Together, these cops will pretty print hashes, arrays,
|
45
45
|
# method calls, etc. For example, let's say the max columns
|
@@ -84,8 +84,20 @@ module RuboCop
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def offense?(node)
|
87
|
-
node.multiline?
|
88
|
-
|
87
|
+
return false if !node.multiline? || too_long?(node) || !suitable_as_single_line?(node)
|
88
|
+
return require_backslash?(node) if node.and_type? || node.or_type?
|
89
|
+
|
90
|
+
!index_access_call_chained?(node) && !configured_to_not_be_inspected?(node)
|
91
|
+
end
|
92
|
+
|
93
|
+
def require_backslash?(node)
|
94
|
+
processed_source.lines[node.loc.operator.line - 1].end_with?('\\')
|
95
|
+
end
|
96
|
+
|
97
|
+
def index_access_call_chained?(node)
|
98
|
+
return false unless node.send_type? && node.method?(:[])
|
99
|
+
|
100
|
+
node.children.first.send_type? && node.children.first.method?(:[])
|
89
101
|
end
|
90
102
|
|
91
103
|
def configured_to_not_be_inspected?(node)
|
@@ -180,6 +180,9 @@ module RuboCop
|
|
180
180
|
with_space = range_with_surrounding_space(operator)
|
181
181
|
return if with_space.source.start_with?("\n")
|
182
182
|
|
183
|
+
comment = processed_source.comment_at_line(operator.line)
|
184
|
+
return if comment && with_space.last_column == comment.loc.column
|
185
|
+
|
183
186
|
offense(type, operator, with_space, right_operand) do |msg|
|
184
187
|
add_offense(operator, message: msg) do |corrector|
|
185
188
|
autocorrect(corrector, with_space, right_operand)
|
@@ -81,19 +81,28 @@ module RuboCop
|
|
81
81
|
private
|
82
82
|
|
83
83
|
def check_empty(left_brace, space_plus_brace, used_style)
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
if style_for_empty_braces == used_style
|
85
|
+
handle_different_styles_for_empty_braces(used_style)
|
86
|
+
return
|
87
|
+
elsif !config_to_allow_offenses.key?('Enabled')
|
88
|
+
config_to_allow_offenses['EnforcedStyleForEmptyBraces'] = used_style.to_s
|
89
|
+
end
|
87
90
|
|
88
91
|
if style_for_empty_braces == :space
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
+
range = left_brace
|
93
|
+
msg = MISSING_MSG
|
92
94
|
else
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
95
|
+
range = range_between(space_plus_brace.begin_pos, left_brace.begin_pos)
|
96
|
+
msg = DETECTED_MSG
|
97
|
+
end
|
98
|
+
add_offense(range, message: msg) { |corrector| autocorrect(corrector, range) }
|
99
|
+
end
|
100
|
+
|
101
|
+
def handle_different_styles_for_empty_braces(used_style)
|
102
|
+
if config_to_allow_offenses['EnforcedStyleForEmptyBraces'] &&
|
103
|
+
config_to_allow_offenses['EnforcedStyleForEmptyBraces'].to_sym != used_style
|
104
|
+
config_to_allow_offenses.clear
|
105
|
+
config_to_allow_offenses['Enabled'] = false
|
97
106
|
end
|
98
107
|
end
|
99
108
|
|
@@ -116,7 +116,7 @@ module RuboCop
|
|
116
116
|
|
117
117
|
def incorrect_style_detected(token1, token2,
|
118
118
|
expect_space, is_empty_braces)
|
119
|
-
brace = (token1.
|
119
|
+
brace = (token1.left_brace? ? token1 : token2).pos
|
120
120
|
range = expect_space ? brace : space_range(brace)
|
121
121
|
detected_style = expect_space ? 'no_space' : 'space'
|
122
122
|
|
@@ -25,8 +25,7 @@ module RuboCop
|
|
25
25
|
include RangeHelp
|
26
26
|
extend AutoCorrector
|
27
27
|
|
28
|
-
|
29
|
-
SPACE_MSG = 'Missing space inside string interpolation detected.'
|
28
|
+
MSG = '%<command>s space inside string interpolation.'
|
30
29
|
|
31
30
|
def on_interpolation(begin_node)
|
32
31
|
return if begin_node.multiline?
|
@@ -36,9 +35,9 @@ module RuboCop
|
|
36
35
|
return if empty_brackets?(left, right, tokens: tokens)
|
37
36
|
|
38
37
|
if style == :no_space
|
39
|
-
no_space_offenses(begin_node, left, right,
|
38
|
+
no_space_offenses(begin_node, left, right, MSG)
|
40
39
|
else
|
41
|
-
space_offenses(begin_node, left, right,
|
40
|
+
space_offenses(begin_node, left, right, MSG)
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|