rubocop 1.57.2 → 1.62.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 +4 -4
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +87 -15
- data/lib/rubocop/cli/command/auto_generate_config.rb +12 -3
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli.rb +6 -1
- data/lib/rubocop/config.rb +4 -2
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_obsoletion.rb +11 -8
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +17 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
- 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/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- 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 +123 -29
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/end_alignment.rb +8 -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 +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -3
- 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_around_operators.rb +50 -20
- 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/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 +2 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.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/next_without_accumulator.rb +6 -21
- 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_safe_navigation.rb +54 -6
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -4
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- 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/symbol_conversion.rb +7 -2
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +7 -2
- 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_times.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +20 -2
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.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/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/registry.rb +1 -1
- 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/arguments_forwarding.rb +152 -21
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- 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/case_like_if.rb +5 -5
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +18 -8
- data/lib/rubocop/cop/style/combinable_loops.rb +13 -7
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -7
- 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_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 +2 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +105 -11
- data/lib/rubocop/cop/style/hash_except.rb +2 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +44 -2
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +8 -10
- data/lib/rubocop/cop/style/map_to_hash.rb +17 -7
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +14 -5
- 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/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
- data/lib/rubocop/cop/style/next.rb +1 -1
- 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/object_then.rb +5 -3
- data/lib/rubocop/cop/style/operator_method_call.rb +2 -2
- 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/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +4 -3
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +4 -3
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +3 -3
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +27 -7
- data/lib/rubocop/cop/style/redundant_parentheses.rb +33 -10
- data/lib/rubocop/cop/style/redundant_return.rb +7 -1
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- 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/sample.rb +3 -4
- 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 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +5 -2
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- 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_proc.rb +36 -0
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +15 -3
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/html_formatter.rb +31 -12
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +2 -2
- data/lib/rubocop/lsp/runtime.rb +1 -1
- data/lib/rubocop/lsp/server.rb +5 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +29 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +11 -8
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/result_cache.rb +0 -1
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +8 -8
- data/lib/rubocop/rspec/shared_contexts.rb +40 -15
- data/lib/rubocop/rspec/support.rb +2 -0
- data/lib/rubocop/runner.rb +10 -3
- data/lib/rubocop/server/cache.rb +1 -2
- data/lib/rubocop/server/client_command/exec.rb +0 -1
- 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 +18 -3
- data/lib/rubocop.rb +4 -0
- metadata +18 -10
- /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,62 +48,131 @@ module RuboCop
|
|
40
48
|
return if node.arguments.none?
|
41
49
|
return unless valid_method_name?(node)
|
42
50
|
|
43
|
-
actual_name = node.
|
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
|
54
63
|
|
55
64
|
def valid_method_name?(node)
|
56
|
-
node.
|
65
|
+
node.first_argument.str_type? || node.first_argument.sym_type?
|
57
66
|
end
|
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
|
@@ -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'
|
@@ -19,6 +20,7 @@ require_relative 'internal_affairs/offense_location_keyword'
|
|
19
20
|
require_relative 'internal_affairs/processed_source_buffer_name'
|
20
21
|
require_relative 'internal_affairs/redundant_context_config_parameter'
|
21
22
|
require_relative 'internal_affairs/redundant_described_class_as_subject'
|
23
|
+
require_relative 'internal_affairs/redundant_expect_offense_arguments'
|
22
24
|
require_relative 'internal_affairs/redundant_let_rubocop_config_new'
|
23
25
|
require_relative 'internal_affairs/redundant_location_argument'
|
24
26
|
require_relative 'internal_affairs/redundant_message_argument'
|
@@ -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)
|
@@ -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
|
|
@@ -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
|
@@ -25,7 +28,7 @@ module RuboCop
|
|
25
28
|
# # element are on separate lines is indented one step (two spaces) more
|
26
29
|
# # than the position inside the opening parenthesis.
|
27
30
|
#
|
28
|
-
# #bad
|
31
|
+
# # bad
|
29
32
|
# array = [
|
30
33
|
# :value
|
31
34
|
# ]
|
@@ -33,7 +36,7 @@ module RuboCop
|
|
33
36
|
# :no_difference
|
34
37
|
# ])
|
35
38
|
#
|
36
|
-
# #good
|
39
|
+
# # good
|
37
40
|
# array = [
|
38
41
|
# :value
|
39
42
|
# ]
|
@@ -47,7 +50,7 @@ module RuboCop
|
|
47
50
|
# # separate lines is indented the same as an array literal which is not
|
48
51
|
# # defined inside a method call.
|
49
52
|
#
|
50
|
-
# #bad
|
53
|
+
# # bad
|
51
54
|
# # consistent
|
52
55
|
# array = [
|
53
56
|
# :value
|
@@ -56,7 +59,7 @@ module RuboCop
|
|
56
59
|
# :its_like_this
|
57
60
|
# ])
|
58
61
|
#
|
59
|
-
# #good
|
62
|
+
# # good
|
60
63
|
# array = [
|
61
64
|
# :value
|
62
65
|
# ]
|
@@ -68,13 +71,13 @@ module RuboCop
|
|
68
71
|
# # The `align_brackets` style enforces that the opening and closing
|
69
72
|
# # brackets are indented to the same position.
|
70
73
|
#
|
71
|
-
# #bad
|
74
|
+
# # bad
|
72
75
|
# # align_brackets
|
73
76
|
# and_now_for_something = [
|
74
77
|
# :completely_different
|
75
78
|
# ]
|
76
79
|
#
|
77
|
-
# #good
|
80
|
+
# # good
|
78
81
|
# # align_brackets
|
79
82
|
# and_now_for_something = [
|
80
83
|
# :completely_different
|
@@ -93,6 +96,8 @@ module RuboCop
|
|
93
96
|
end
|
94
97
|
|
95
98
|
def on_send(node)
|
99
|
+
return if style != :consistent && enforce_first_argument_with_fixed_indentation?
|
100
|
+
|
96
101
|
each_argument_node(node, :array) do |array_node, left_parenthesis|
|
97
102
|
check(array_node, left_parenthesis)
|
98
103
|
end
|
@@ -174,6 +179,16 @@ module RuboCop
|
|
174
179
|
'where the left bracket is.'
|
175
180
|
end
|
176
181
|
end
|
182
|
+
|
183
|
+
def enforce_first_argument_with_fixed_indentation?
|
184
|
+
return false unless array_alignment_config['Enabled']
|
185
|
+
|
186
|
+
array_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
187
|
+
end
|
188
|
+
|
189
|
+
def array_alignment_config
|
190
|
+
config.for_cop('Layout/ArrayAlignment')
|
191
|
+
end
|
177
192
|
end
|
178
193
|
end
|
179
194
|
end
|
@@ -72,7 +72,7 @@ module RuboCop
|
|
72
72
|
return if ignored_node?(def_node)
|
73
73
|
|
74
74
|
left_parenthesis = def_node.arguments.loc.begin
|
75
|
-
first_elem = def_node.
|
75
|
+
first_elem = def_node.first_argument
|
76
76
|
return unless first_elem
|
77
77
|
return if same_line?(first_elem, left_parenthesis)
|
78
78
|
|
@@ -182,7 +182,7 @@ module RuboCop
|
|
182
182
|
end
|
183
183
|
|
184
184
|
def add_correct_closing_paren(node, corrector)
|
185
|
-
corrector.insert_after(node.
|
185
|
+
corrector.insert_after(node.last_argument, ')')
|
186
186
|
end
|
187
187
|
|
188
188
|
def remove_incorrect_closing_paren(node, corrector)
|
@@ -271,7 +271,7 @@ module RuboCop
|
|
271
271
|
def add_correct_external_trailing_comma(node, corrector)
|
272
272
|
return unless external_trailing_comma?(node)
|
273
273
|
|
274
|
-
corrector.insert_after(node.
|
274
|
+
corrector.insert_after(node.last_argument, ',')
|
275
275
|
end
|
276
276
|
|
277
277
|
def remove_incorrect_external_trailing_comma(node, corrector)
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
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
|
-
# avoid
|
11
|
+
# avoid ``Layout/LineLength``'s offenses.
|
12
12
|
#
|
13
13
|
# @example
|
14
14
|
# # bad
|
@@ -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)
|
@@ -62,6 +62,7 @@ module RuboCop
|
|
62
62
|
|
63
63
|
register_offense(node)
|
64
64
|
end
|
65
|
+
alias on_csend on_send
|
65
66
|
|
66
67
|
private
|
67
68
|
|
@@ -83,8 +84,20 @@ module RuboCop
|
|
83
84
|
end
|
84
85
|
|
85
86
|
def offense?(node)
|
86
|
-
node.multiline?
|
87
|
-
|
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?(:[])
|
88
101
|
end
|
89
102
|
|
90
103
|
def configured_to_not_be_inspected?(node)
|
@@ -135,7 +148,7 @@ module RuboCop
|
|
135
148
|
.gsub(/" *\\\n\s*'/, %q(" + ')) # Double quote, backslash, and then single quote
|
136
149
|
.gsub(/' *\\\n\s*"/, %q(' + ")) # Single quote, backslash, and then double quote
|
137
150
|
.gsub(/(["']) *\\\n\s*\1/, '') # Double or single quote, backslash, then same quote
|
138
|
-
.gsub(/\n\s*(
|
151
|
+
.gsub(/\n\s*(?=(&)?\.\w)/, '') # Extra space within method chaining which includes `&.`
|
139
152
|
.gsub(/\s*\\?\n\s*/, ' ') # Any other line break, with or without backslash
|
140
153
|
end
|
141
154
|
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
MSG = '`%<kw_loc>s` at %<kw_loc_line>d, %<kw_loc_column>d is not ' \
|
30
30
|
'aligned with `%<beginning>s` at ' \
|
31
31
|
'%<begin_loc_line>d, %<begin_loc_column>d.'
|
32
|
-
ANCESTOR_TYPES = %i[kwbegin def defs class module block].freeze
|
32
|
+
ANCESTOR_TYPES = %i[kwbegin def defs class module block numblock].freeze
|
33
33
|
ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS = %i[def defs].freeze
|
34
34
|
ALTERNATIVE_ACCESS_MODIFIERS = %i[public_class_method private_class_method].freeze
|
35
35
|
|
@@ -95,7 +95,7 @@ module RuboCop
|
|
95
95
|
def alignment_source(node, starting_loc)
|
96
96
|
ending_loc =
|
97
97
|
case node.type
|
98
|
-
when :block, :kwbegin
|
98
|
+
when :block, :numblock, :kwbegin
|
99
99
|
node.loc.begin
|
100
100
|
when :def, :defs, :class, :module,
|
101
101
|
:lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
|
@@ -104,8 +104,8 @@ module RuboCop
|
|
104
104
|
mlhs_node, = *node
|
105
105
|
mlhs_node.source_range
|
106
106
|
else
|
107
|
-
# It is a wrapper with access modifier.
|
108
|
-
node.child_nodes.first.loc.name
|
107
|
+
# It is a wrapper with receiver of object attribute or access modifier.
|
108
|
+
node.receiver&.source_range || node.child_nodes.first.loc.name
|
109
109
|
end
|
110
110
|
|
111
111
|
range_between(starting_loc.begin_pos, ending_loc.end_pos).source
|
@@ -25,10 +25,15 @@ module RuboCop
|
|
25
25
|
|
26
26
|
MSG = 'Put method call on a separate line if chained to a single line block.'
|
27
27
|
|
28
|
+
def self.autocorrect_incompatible_with
|
29
|
+
[Style::MapToHash]
|
30
|
+
end
|
31
|
+
|
28
32
|
def on_send(node)
|
29
33
|
range = offending_range(node)
|
30
34
|
add_offense(range) { |corrector| corrector.insert_before(range, "\n") } if range
|
31
35
|
end
|
36
|
+
alias on_csend on_send
|
32
37
|
|
33
38
|
private
|
34
39
|
|