rubocop 1.92.0 → 1.92.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/default.yml +1 -0
- data/lib/rubocop/config.rb +0 -4
- data/lib/rubocop/config_obsoletion.rb +9 -0
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +16 -1
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +34 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/class_structure.rb +21 -7
- data/lib/rubocop/cop/layout/dot_position.rb +25 -15
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +11 -7
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +9 -3
- data/lib/rubocop/cop/layout/end_alignment.rb +5 -15
- data/lib/rubocop/cop/layout/extra_spacing.rb +18 -7
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +26 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +15 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +11 -5
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +5 -3
- data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
- data/lib/rubocop/cop/layout/line_length.rb +127 -11
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +6 -4
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +16 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +3 -3
- data/lib/rubocop/cop/layout/space_around_operators.rb +31 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +12 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +29 -11
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +20 -17
- data/lib/rubocop/cop/lint/nested_percent_literal.rb +3 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +2 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +22 -1
- data/lib/rubocop/cop/lint/percent_string_array.rb +75 -9
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +27 -8
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +11 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +47 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +7 -6
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +3 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +36 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +26 -5
- data/lib/rubocop/cop/mixin/statement_modifier.rb +17 -3
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +30 -2
- data/lib/rubocop/cop/style/and_or.rb +34 -11
- data/lib/rubocop/cop/style/arguments_forwarding.rb +28 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +6 -0
- data/lib/rubocop/cop/style/case_equality.rb +14 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
- data/lib/rubocop/cop/style/class_methods_definitions.rb +7 -0
- data/lib/rubocop/cop/style/collection_querying.rb +79 -46
- data/lib/rubocop/cop/style/combinable_loops.rb +4 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +13 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +53 -11
- data/lib/rubocop/cop/style/endless_method.rb +38 -6
- data/lib/rubocop/cop/style/float_division.rb +16 -1
- data/lib/rubocop/cop/style/for.rb +14 -1
- data/lib/rubocop/cop/style/guard_clause.rb +22 -21
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +4 -0
- data/lib/rubocop/cop/style/hash_lookup_method.rb +10 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +19 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +63 -2
- data/lib/rubocop/cop/style/lambda.rb +16 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +36 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +9 -1
- data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
- data/lib/rubocop/cop/style/mutable_constant.rb +25 -7
- data/lib/rubocop/cop/style/numeric_predicate.rb +7 -0
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +19 -1
- data/lib/rubocop/cop/style/quoted_symbols.rb +5 -7
- data/lib/rubocop/cop/style/raise_args.rb +80 -11
- data/lib/rubocop/cop/style/reduce_to_hash.rb +32 -34
- data/lib/rubocop/cop/style/redundant_begin.rb +26 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +13 -9
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -2
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +24 -1
- data/lib/rubocop/cop/style/redundant_self.rb +9 -1
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +28 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +38 -4
- data/lib/rubocop/cop/style/require_order.rb +16 -8
- data/lib/rubocop/cop/style/rescue_modifier.rb +6 -0
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +26 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +12 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +6 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +23 -23
- data/lib/rubocop/plugin/configuration_integrator.rb +24 -3
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/server/cache.rb +4 -4
- data/lib/rubocop/target_ruby.rb +21 -9
- data/lib/rubocop/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2e582386de45680cecfa5173359f6ccb24894b2440ef9d6fec5ec5c0d28d0b41
|
|
4
|
+
data.tar.gz: ef3bdbb7e39a1960f5e1feb41df80f7afef2f35148a44693566f725b99715a3a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dff3c8ee84b5334d4aabb751f7de89b2cf2b87d65ad7970913132f558909d80da6306f60707f0ba1001d826a22c3491d9ab716c82defb20bb10216654cf75902
|
|
7
|
+
data.tar.gz: 6c6913ed8f1d4f30ee0044df54c2c370aa59b2f1f91de340f33295af795fcd56138b75583c37049c3fd117ffd51241600bd24e0c5e82d41b58304821a8170a25
|
data/config/default.yml
CHANGED
data/lib/rubocop/config.rb
CHANGED
|
@@ -56,10 +56,6 @@ module RuboCop
|
|
|
56
56
|
deprecated_config = @for_cop[deprecated_cop_name]
|
|
57
57
|
next if deprecated_config.empty?
|
|
58
58
|
|
|
59
|
-
warn Rainbow(<<~WARNING).yellow
|
|
60
|
-
Warning: Using `#{deprecated_cop_name}` configuration in #{loaded_path} for `#{cop}`.
|
|
61
|
-
WARNING
|
|
62
|
-
|
|
63
59
|
cop_options.merge!(@for_cop[deprecated_cop_name])
|
|
64
60
|
end
|
|
65
61
|
end
|
|
@@ -76,6 +76,15 @@ module RuboCop
|
|
|
76
76
|
raise ValidationError, messages.join("\n")
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
+
# Messages for every violated rule, regardless of severity, without raising.
|
|
80
|
+
# Used for configuration the user does not own (a plugin's defaults), where an
|
|
81
|
+
# obsolete key should be reported but must not stop the run. Extracted cops are
|
|
82
|
+
# left out: whether their gem is loaded is only known once every plugin has been
|
|
83
|
+
# integrated, and this is called while plugins are still loading.
|
|
84
|
+
def messages
|
|
85
|
+
rules.grep_v(ExtractedCop).select(&:violated?).map(&:message)
|
|
86
|
+
end
|
|
87
|
+
|
|
79
88
|
def legacy_cop_names
|
|
80
89
|
# Used by DepartmentName#qualified_legacy_cop_name
|
|
81
90
|
cop_rules.map(&:old_name)
|
data/lib/rubocop/cop/badge.rb
CHANGED
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
|
29
29
|
format(
|
|
30
30
|
CORRECTION_WITH_ARGUMENTS,
|
|
31
31
|
collection: collection_node.source,
|
|
32
|
-
variables:
|
|
32
|
+
variables: loop_variables
|
|
33
33
|
)
|
|
34
34
|
else
|
|
35
35
|
format(CORRECTION_WITHOUT_ARGUMENTS, enumerable: collection_node.source)
|
|
@@ -38,6 +38,21 @@ module RuboCop
|
|
|
38
38
|
padding_needed?(offending_range.end_pos) ? "#{keyword} " : keyword
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
def loop_variables
|
|
42
|
+
variables = argument_node.children.map { |argument| loop_variable(argument) }.join(', ')
|
|
43
|
+
|
|
44
|
+
argument_node.source.match?(/,\s*\|\z/) ? "#{variables}," : variables
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def loop_variable(argument)
|
|
48
|
+
return argument.source unless argument.mlhs_type?
|
|
49
|
+
|
|
50
|
+
variables = argument.children.map { |child| loop_variable(child) }.join(', ')
|
|
51
|
+
lone_target = argument.children.one? && !argument.children.first.restarg_type?
|
|
52
|
+
|
|
53
|
+
lone_target ? "(#{variables},)" : "(#{variables})"
|
|
54
|
+
end
|
|
55
|
+
|
|
41
56
|
def closing_keyword
|
|
42
57
|
padding_needed?(block_node.loc.end.begin_pos - 1) ? ' end' : 'end'
|
|
43
58
|
end
|
|
@@ -76,8 +76,8 @@ module RuboCop
|
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def remove_trailing_whitespace(corrector)
|
|
79
|
-
|
|
80
|
-
corrector.
|
|
79
|
+
whitespace = arguments.source_range.end.join(block_begin.begin)
|
|
80
|
+
corrector.replace(whitespace, ' ') if whitespace.size > 1
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def replace_delimiters(corrector)
|
|
@@ -27,6 +27,7 @@ module RuboCop
|
|
|
27
27
|
# corrected. The user must handle the delicate decision of where to
|
|
28
28
|
# put the comment.
|
|
29
29
|
return if new_line_needed_before_closing_brace?(node)
|
|
30
|
+
return if nested_closing_bracket_moved_before_comment?
|
|
30
31
|
|
|
31
32
|
end_range = last_element_range_with_trailing_comma(node).end
|
|
32
33
|
|
|
@@ -43,6 +44,39 @@ module RuboCop
|
|
|
43
44
|
corrector.insert_before(node.loc.end, "\n")
|
|
44
45
|
end
|
|
45
46
|
|
|
47
|
+
def nested_closing_bracket_moved_before_comment?
|
|
48
|
+
last_element = children(node).last
|
|
49
|
+
return false unless (comment = processed_source.comment_at_line(last_element.last_line - 1))
|
|
50
|
+
return false unless (nested = nested_literal_with_closing_bracket_on_own_line(last_element))
|
|
51
|
+
|
|
52
|
+
own_line_comment?(comment) || !(nested.chained? || nested.argument?)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def nested_literal_with_closing_bracket_on_own_line(last_element)
|
|
56
|
+
last_line = last_element.last_line
|
|
57
|
+
|
|
58
|
+
last_element.each_node.find do |descendant|
|
|
59
|
+
same_kind_as_node?(descendant) && closing_bracket_on_own_line?(descendant, last_line)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def same_kind_as_node?(descendant)
|
|
64
|
+
descendant.type == node.type || (descendant.call_type? && node.call_type?)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def closing_bracket_on_own_line?(descendant, line)
|
|
68
|
+
return false unless descendant.loc?(:end) && descendant.loc.end.is?('}', ']', ')')
|
|
69
|
+
|
|
70
|
+
closing_bracket = descendant.loc.end
|
|
71
|
+
return false if closing_bracket.line != line
|
|
72
|
+
|
|
73
|
+
closing_bracket.source_line[0...closing_bracket.column].strip.empty?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def own_line_comment?(comment)
|
|
77
|
+
comment.source_range.source_line.lstrip.start_with?('#')
|
|
78
|
+
end
|
|
79
|
+
|
|
46
80
|
def correct_next_line_brace(corrector, end_range)
|
|
47
81
|
corrector.remove(range_with_surrounding_space(node.loc.end, side: :left))
|
|
48
82
|
corrector.insert_before(end_range, content_if_comment_present(corrector, node))
|
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
|
53
53
|
|
|
54
54
|
def on_send(node)
|
|
55
55
|
return if !multiple_arguments?(node) || (node.call_type? && node.method?(:[]=)) ||
|
|
56
|
-
autocorrect_incompatible_with_other_cops?
|
|
56
|
+
binary_operator_call?(node) || autocorrect_incompatible_with_other_cops?
|
|
57
57
|
|
|
58
58
|
items = flattened_arguments(node)
|
|
59
59
|
|
|
@@ -64,6 +64,10 @@ module RuboCop
|
|
|
64
64
|
|
|
65
65
|
private
|
|
66
66
|
|
|
67
|
+
def binary_operator_call?(node)
|
|
68
|
+
node.binary_operation? && !node.method?(:[]) && !node.loc.dot
|
|
69
|
+
end
|
|
70
|
+
|
|
67
71
|
def autocorrect_incompatible_with_other_cops?
|
|
68
72
|
with_first_argument_style? && enforce_hash_argument_with_separator?
|
|
69
73
|
end
|
|
@@ -341,9 +341,26 @@ module RuboCop
|
|
|
341
341
|
|
|
342
342
|
return "#{node_visibility(node)}_methods"
|
|
343
343
|
end
|
|
344
|
+
return class_method_category(node) if node.defs_type?
|
|
345
|
+
|
|
344
346
|
HUMANIZED_NODE_TYPE[node.type] || node.type
|
|
345
347
|
end
|
|
346
348
|
|
|
349
|
+
# Only `private_class_method` reaches a singleton method; a bare `private` does not.
|
|
350
|
+
# Such a call follows the definition it names, so only right siblings are searched.
|
|
351
|
+
def class_method_category(node)
|
|
352
|
+
modifier = node.right_siblings.reverse.find do |sibling|
|
|
353
|
+
class_method_visibility_modifier?(sibling, method_name: node.method_name)
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
modifier ? :"#{modifier.method_name}s" : HUMANIZED_NODE_TYPE[node.type]
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# @!method class_method_visibility_modifier?(node, method_name:)
|
|
360
|
+
def_node_matcher :class_method_visibility_modifier?, <<~PATTERN
|
|
361
|
+
(send nil? {:private_class_method :public_class_method} <(sym %method_name) ...>)
|
|
362
|
+
PATTERN
|
|
363
|
+
|
|
347
364
|
def dynamic_constant?(node)
|
|
348
365
|
return false unless node.casgn_type? && node.namespace.nil?
|
|
349
366
|
|
|
@@ -429,12 +446,9 @@ module RuboCop
|
|
|
429
446
|
end
|
|
430
447
|
|
|
431
448
|
def end_position_for(node)
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
return heredoc.location.heredoc_end.end_pos if heredoc
|
|
435
|
-
end
|
|
449
|
+
heredoc_end_lines = heredocs(node).map { |heredoc| heredoc.loc.heredoc_end.line }
|
|
450
|
+
end_line = [node.last_line, *heredoc_end_lines].max
|
|
436
451
|
|
|
437
|
-
end_line = buffer.line_for_position(node.source_range.end_pos)
|
|
438
452
|
buffer.line_range(end_line).end_pos
|
|
439
453
|
end
|
|
440
454
|
|
|
@@ -457,8 +471,8 @@ module RuboCop
|
|
|
457
471
|
buffer.line_range(node.loc.line).begin_pos - 1
|
|
458
472
|
end
|
|
459
473
|
|
|
460
|
-
def
|
|
461
|
-
node.each_node(:any_str).
|
|
474
|
+
def heredocs(node)
|
|
475
|
+
node.each_node(:any_str).select(&:heredoc?)
|
|
462
476
|
end
|
|
463
477
|
|
|
464
478
|
def buffer
|
|
@@ -27,10 +27,6 @@ module RuboCop
|
|
|
27
27
|
include RangeHelp
|
|
28
28
|
extend AutoCorrector
|
|
29
29
|
|
|
30
|
-
def self.autocorrect_incompatible_with
|
|
31
|
-
[Style::RedundantSelf]
|
|
32
|
-
end
|
|
33
|
-
|
|
34
30
|
def on_send(node)
|
|
35
31
|
return unless node.dot? || node.safe_navigation?
|
|
36
32
|
|
|
@@ -46,21 +42,35 @@ module RuboCop
|
|
|
46
42
|
|
|
47
43
|
private
|
|
48
44
|
|
|
45
|
+
# The dot and the gap it moves across are replaced in one action, so that another
|
|
46
|
+
# correction that rewrites a range spanning the dot clashes with this one instead of
|
|
47
|
+
# leaving the moved dot behind.
|
|
49
48
|
def autocorrect(corrector, dot, node)
|
|
50
|
-
dot_range =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
case style
|
|
57
|
-
when :leading
|
|
58
|
-
corrector.insert_before(selector_range(node), dot.source)
|
|
59
|
-
when :trailing
|
|
60
|
-
corrector.insert_after(node.receiver, dot.source)
|
|
49
|
+
dot_range = removed_dot_range(dot)
|
|
50
|
+
|
|
51
|
+
if style == :leading
|
|
52
|
+
move_dot_before_selector(corrector, dot, dot_range, selector_range(node))
|
|
53
|
+
else
|
|
54
|
+
move_dot_after_receiver(corrector, dot, dot_range, node.receiver)
|
|
61
55
|
end
|
|
62
56
|
end
|
|
63
57
|
|
|
58
|
+
def removed_dot_range(dot)
|
|
59
|
+
return dot unless processed_source[dot.line - 1].strip == '.'
|
|
60
|
+
|
|
61
|
+
range_by_whole_lines(dot, include_final_newline: true)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def move_dot_before_selector(corrector, dot, dot_range, selector)
|
|
65
|
+
gap = range_between(dot_range.end_pos, selector.begin_pos)
|
|
66
|
+
corrector.replace(dot_range.join(gap), "#{gap.source}#{dot.source}")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def move_dot_after_receiver(corrector, dot, dot_range, receiver)
|
|
70
|
+
gap = range_between(receiver.source_range.end_pos, dot_range.begin_pos)
|
|
71
|
+
corrector.replace(gap.join(dot_range), "#{dot.source}#{gap.source}")
|
|
72
|
+
end
|
|
73
|
+
|
|
64
74
|
def message(dot)
|
|
65
75
|
"Place the #{dot.source} on the " +
|
|
66
76
|
case style
|
|
@@ -61,23 +61,23 @@ module RuboCop
|
|
|
61
61
|
return if node.ternary?
|
|
62
62
|
|
|
63
63
|
if node.modifier_form?
|
|
64
|
-
check_condition(node.condition) if node
|
|
64
|
+
check_condition(node.condition, node.right_sibling) if followed_by_statement?(node)
|
|
65
65
|
else
|
|
66
66
|
check_condition(node.condition, node.if_branch)
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def on_while(node)
|
|
71
|
-
return if node.modifier_form? && !node
|
|
71
|
+
return if node.modifier_form? && !followed_by_statement?(node)
|
|
72
72
|
|
|
73
|
-
check_condition(node.condition, node.modifier_form? ?
|
|
73
|
+
check_condition(node.condition, node.modifier_form? ? node.right_sibling : node.body)
|
|
74
74
|
end
|
|
75
75
|
alias on_until on_while
|
|
76
76
|
|
|
77
77
|
def on_while_post(node)
|
|
78
|
-
return unless node
|
|
78
|
+
return unless followed_by_statement?(node)
|
|
79
79
|
|
|
80
|
-
check_condition(node.condition)
|
|
80
|
+
check_condition(node.condition, node.right_sibling)
|
|
81
81
|
end
|
|
82
82
|
alias on_until_post on_while_post
|
|
83
83
|
|
|
@@ -106,10 +106,14 @@ module RuboCop
|
|
|
106
106
|
|
|
107
107
|
private
|
|
108
108
|
|
|
109
|
-
def
|
|
109
|
+
def followed_by_statement?(node)
|
|
110
|
+
node.parent&.type?(:begin, :kwbegin) && node.right_sibling
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def check_condition(condition, following_node)
|
|
110
114
|
return unless condition.multiline?
|
|
111
115
|
return if next_line_empty?(condition.last_line)
|
|
112
|
-
return if body_on_line?(
|
|
116
|
+
return if body_on_line?(following_node, condition.last_line)
|
|
113
117
|
|
|
114
118
|
add_offense(condition, &autocorrect(condition))
|
|
115
119
|
end
|
|
@@ -38,13 +38,19 @@ module RuboCop
|
|
|
38
38
|
KIND = 'block'
|
|
39
39
|
|
|
40
40
|
def on_block(node)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
check(node, node.body, adjusted_first_line: first_line)
|
|
41
|
+
check(node, node.body, adjusted_first_line: body_start_line(node))
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
alias on_numblock on_block
|
|
47
45
|
alias on_itblock on_block
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def body_start_line(node)
|
|
50
|
+
return node.loc.begin.line unless node.arguments?
|
|
51
|
+
|
|
52
|
+
[node.loc.begin.line, node.arguments.last_line].max
|
|
53
|
+
end
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
56
|
end
|
|
@@ -80,10 +80,6 @@ module RuboCop
|
|
|
80
80
|
include RangeHelp
|
|
81
81
|
extend AutoCorrector
|
|
82
82
|
|
|
83
|
-
def on_class(node)
|
|
84
|
-
check_other_alignment(node)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
83
|
def on_sclass(node)
|
|
88
84
|
if node.parent&.assignment?
|
|
89
85
|
check_asgn_alignment(node.parent, node)
|
|
@@ -91,10 +87,8 @@ module RuboCop
|
|
|
91
87
|
check_other_alignment(node)
|
|
92
88
|
end
|
|
93
89
|
end
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
check_other_alignment(node)
|
|
97
|
-
end
|
|
90
|
+
alias on_class on_sclass
|
|
91
|
+
alias on_module on_sclass
|
|
98
92
|
|
|
99
93
|
def on_if(node)
|
|
100
94
|
check_other_alignment(node) unless node.ternary?
|
|
@@ -177,13 +171,7 @@ module RuboCop
|
|
|
177
171
|
when :keyword
|
|
178
172
|
node
|
|
179
173
|
when :variable
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
while (parent = align_to.parent) && parent.send_type? && same_line?(align_to, parent)
|
|
183
|
-
align_to = parent
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
align_to
|
|
174
|
+
alignment_node_for_variable_style(node)
|
|
187
175
|
else
|
|
188
176
|
start_line_range(node)
|
|
189
177
|
end
|
|
@@ -213,6 +201,8 @@ module RuboCop
|
|
|
213
201
|
leading_node(extract_rhs(ancestor)).equal?(node)
|
|
214
202
|
elsif ancestor.send_type? && ancestor.operator_method?
|
|
215
203
|
!leading_node(ancestor).equal?(node)
|
|
204
|
+
elsif ancestor.send_type?
|
|
205
|
+
leading_node(ancestor.last_argument).equal?(node)
|
|
216
206
|
end
|
|
217
207
|
end
|
|
218
208
|
end
|
|
@@ -30,6 +30,7 @@ module RuboCop
|
|
|
30
30
|
# some_object.method(arg) # this is some comment
|
|
31
31
|
class ExtraSpacing < Base
|
|
32
32
|
extend AutoCorrector
|
|
33
|
+
include LineLengthHelp
|
|
33
34
|
include PrecedingFollowingAlignment
|
|
34
35
|
include RangeHelp
|
|
35
36
|
|
|
@@ -37,7 +38,7 @@ module RuboCop
|
|
|
37
38
|
MSG_UNALIGNED_ASGN = '`=` is not aligned with the %<location>s assignment.'
|
|
38
39
|
|
|
39
40
|
def self.autocorrect_incompatible_with
|
|
40
|
-
[Style::SelfAssignment]
|
|
41
|
+
[Layout::RedundantLineBreak, Style::SelfAssignment]
|
|
41
42
|
end
|
|
42
43
|
|
|
43
44
|
def on_new_investigation
|
|
@@ -77,9 +78,14 @@ module RuboCop
|
|
|
77
78
|
def check_assignment(token)
|
|
78
79
|
return unless aligned_with_preceding_equals_operator(token) == :no
|
|
79
80
|
|
|
81
|
+
tokens, align_to = equal_sign_alignment(token.line)
|
|
82
|
+
return if exceeds_max_line_length?(tokens, align_to)
|
|
83
|
+
|
|
80
84
|
message = format(MSG_UNALIGNED_ASGN, location: 'preceding')
|
|
81
85
|
add_offense(token.pos, message: message) do |corrector|
|
|
82
|
-
|
|
86
|
+
tokens.each do |asgn_token|
|
|
87
|
+
align_equal_sign(corrector, asgn_token, align_to)
|
|
88
|
+
end
|
|
83
89
|
end
|
|
84
90
|
end
|
|
85
91
|
|
|
@@ -240,14 +246,19 @@ module RuboCop
|
|
|
240
246
|
cop_config['ForceEqualSignAlignment']
|
|
241
247
|
end
|
|
242
248
|
|
|
243
|
-
def
|
|
244
|
-
lines = all_relevant_assignment_lines(
|
|
249
|
+
def equal_sign_alignment(line_number)
|
|
250
|
+
lines = all_relevant_assignment_lines(line_number)
|
|
245
251
|
tokens = assignment_tokens.select { |t| lines.include?(t.line) }
|
|
246
252
|
|
|
247
|
-
|
|
248
|
-
|
|
253
|
+
[tokens, tokens.map { |t| align_column(t) }.max]
|
|
254
|
+
end
|
|
249
255
|
|
|
250
|
-
|
|
256
|
+
def exceeds_max_line_length?(tokens, align_to)
|
|
257
|
+
max_line_length && tokens.any? do |token|
|
|
258
|
+
padding = align_to - token.pos.last_column
|
|
259
|
+
|
|
260
|
+
padding.positive? && line_length(token.pos.source_line) + padding > max_line_length
|
|
261
|
+
end
|
|
251
262
|
end
|
|
252
263
|
|
|
253
264
|
def align_equal_sign(corrector, token, align_to)
|
|
@@ -152,6 +152,10 @@ module RuboCop
|
|
|
152
152
|
|
|
153
153
|
MSG = 'Indent the first argument one step more than %<base>s.'
|
|
154
154
|
|
|
155
|
+
def self.autocorrect_incompatible_with
|
|
156
|
+
[Layout::ArgumentAlignment, Layout::HashAlignment]
|
|
157
|
+
end
|
|
158
|
+
|
|
155
159
|
def on_send(node)
|
|
156
160
|
return unless should_check?(node)
|
|
157
161
|
return if same_line?(node, node.first_argument)
|
|
@@ -180,7 +184,13 @@ module RuboCop
|
|
|
180
184
|
|
|
181
185
|
top_level_send = find_top_level_send(send_node)
|
|
182
186
|
node_to_correct =
|
|
183
|
-
should_correct_entire_chain?(send_node, top_level_send)
|
|
187
|
+
if should_correct_entire_chain?(send_node, top_level_send)
|
|
188
|
+
top_level_send
|
|
189
|
+
elsif hash_elements_aligned_by_argument_alignment?(node)
|
|
190
|
+
node.children.first
|
|
191
|
+
else
|
|
192
|
+
node
|
|
193
|
+
end
|
|
184
194
|
|
|
185
195
|
AlignmentCorrector.correct(corrector, processed_source, node_to_correct, column_delta)
|
|
186
196
|
end
|
|
@@ -210,6 +220,21 @@ module RuboCop
|
|
|
210
220
|
top_level_send
|
|
211
221
|
end
|
|
212
222
|
|
|
223
|
+
# `Layout/ArgumentAlignment` with `with_fixed_indentation` indents the pairs of an
|
|
224
|
+
# unbraced hash to a fixed column, so they must not move along with the first element.
|
|
225
|
+
def hash_elements_aligned_by_argument_alignment?(node)
|
|
226
|
+
return false if !node.hash_type? || node.braces?
|
|
227
|
+
return false unless enforce_first_argument_with_fixed_indentation?
|
|
228
|
+
|
|
229
|
+
argument_alignment_applies?(node.parent) && !enforce_hash_argument_with_separator?
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def enforce_hash_argument_with_separator?
|
|
233
|
+
HashAlignment::SEPARATOR_ALIGNMENT_STYLES.any? do |style|
|
|
234
|
+
config.for_enabled_cop('Layout/HashAlignment')[style]&.include?('separator')
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
213
238
|
def bare_operator?(node)
|
|
214
239
|
node.operator_method? && !node.dot?
|
|
215
240
|
end
|
|
@@ -6,6 +6,10 @@ module RuboCop
|
|
|
6
6
|
# Checks for a line break before the first element in a
|
|
7
7
|
# multi-line array.
|
|
8
8
|
#
|
|
9
|
+
# NOTE: An array whose first element is an array literal is not checked when
|
|
10
|
+
# `Layout/SpaceInsideArrayLiteralBrackets` is enabled with `EnforcedStyle: compact`,
|
|
11
|
+
# since that style joins the two opening brackets.
|
|
12
|
+
#
|
|
9
13
|
# @example
|
|
10
14
|
#
|
|
11
15
|
# # bad
|
|
@@ -70,6 +74,7 @@ module RuboCop
|
|
|
70
74
|
def on_array(node)
|
|
71
75
|
return if !node.loc.begin && !assignment_on_same_line?(node)
|
|
72
76
|
return if allow_implicit_array_brackets? && !node.bracketed?
|
|
77
|
+
return if compact_nested_array?(node)
|
|
73
78
|
|
|
74
79
|
check_children_line_break(node, node.children, ignore_last: ignore_last_element?)
|
|
75
80
|
end
|
|
@@ -85,6 +90,16 @@ module RuboCop
|
|
|
85
90
|
!!cop_config['AllowImplicitArrayLiterals']
|
|
86
91
|
end
|
|
87
92
|
|
|
93
|
+
def compact_nested_array?(node)
|
|
94
|
+
node.square_brackets? && node.children.first&.source&.start_with?('[') &&
|
|
95
|
+
compact_array_brackets_enforced?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def compact_array_brackets_enforced?
|
|
99
|
+
config.cop_enabled?('Layout/SpaceInsideArrayLiteralBrackets') &&
|
|
100
|
+
config.for_cop('Layout/SpaceInsideArrayLiteralBrackets')['EnforcedStyle'] == 'compact'
|
|
101
|
+
end
|
|
102
|
+
|
|
88
103
|
def ignore_last_element?
|
|
89
104
|
!!cop_config['AllowMultilineFinalElement']
|
|
90
105
|
end
|
|
@@ -156,16 +156,22 @@ module RuboCop
|
|
|
156
156
|
if first_pair
|
|
157
157
|
return if same_line?(first_pair, left_brace)
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
check_based_on_longest_key(hash_node, left_brace, left_parenthesis)
|
|
161
|
-
else
|
|
162
|
-
check_first(first_pair, left_brace, left_parenthesis, 0)
|
|
163
|
-
end
|
|
159
|
+
check_first_pair(hash_node, first_pair, left_brace, left_parenthesis)
|
|
164
160
|
end
|
|
165
161
|
|
|
166
162
|
check_right_brace(hash_node.loc.end, first_pair, left_brace, left_parenthesis)
|
|
167
163
|
end
|
|
168
164
|
|
|
165
|
+
def check_first_pair(hash_node, first_pair, left_brace, left_parenthesis)
|
|
166
|
+
return unless begins_its_line?(first_pair.source_range)
|
|
167
|
+
|
|
168
|
+
if separator_style?(first_pair)
|
|
169
|
+
check_based_on_longest_key(hash_node, left_brace, left_parenthesis)
|
|
170
|
+
else
|
|
171
|
+
check_first(first_pair, left_brace, left_parenthesis, 0)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
169
175
|
def check_right_brace(right_brace, first_pair, left_brace, left_parenthesis)
|
|
170
176
|
# if the right brace is on the same line as the last value, accept
|
|
171
177
|
return if /\S/.match?(right_brace.source_line[0...right_brace.column])
|
|
@@ -57,8 +57,10 @@ module RuboCop
|
|
|
57
57
|
MSG = 'Put the closing parenthesis for a method call with a ' \
|
|
58
58
|
'HEREDOC parameter on the same line as the HEREDOC opening.'
|
|
59
59
|
|
|
60
|
+
# `Layout/MultilineMethodCallBraceLayout` can move the same closing parenthesis after
|
|
61
|
+
# the last argument in the same pass, and both insertions are kept.
|
|
60
62
|
def self.autocorrect_incompatible_with
|
|
61
|
-
[Style::TrailingCommaInArguments]
|
|
63
|
+
[Layout::MultilineMethodCallBraceLayout, Style::TrailingCommaInArguments]
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
def on_send(node)
|
|
@@ -231,8 +233,8 @@ module RuboCop
|
|
|
231
233
|
end
|
|
232
234
|
|
|
233
235
|
def find_most_bottom_of_heredoc_end(arguments)
|
|
234
|
-
arguments.filter_map do |
|
|
235
|
-
|
|
236
|
+
arguments.flat_map { |argument| argument.each_node(:any_str).to_a }.filter_map do |node|
|
|
237
|
+
node.loc.heredoc_end.end_pos if node.loc?(:heredoc_end)
|
|
236
238
|
end.max
|
|
237
239
|
end
|
|
238
240
|
|
|
@@ -178,10 +178,24 @@ module RuboCop
|
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
def check_normal_style(node)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
items = node.children.reject { |child| bare_access_modifier?(child) }
|
|
182
|
+
|
|
183
|
+
check_alignment(items, base_column_for_normal_style(node) || governed_base_column(items))
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def governed_base_column(items)
|
|
187
|
+
return unless config.cop_enabled?('Layout/IndentationWidth')
|
|
188
|
+
return if items.empty? || indentation_width_enabled_at?(items.first)
|
|
189
|
+
|
|
190
|
+
governed_item = items.find { |item| indentation_width_enabled_at?(item) }
|
|
191
|
+
|
|
192
|
+
display_column(governed_item.source_range) if governed_item
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def indentation_width_enabled_at?(node)
|
|
196
|
+
comment_config = processed_source.comment_config
|
|
197
|
+
|
|
198
|
+
comment_config.cop_enabled_at_line?('Layout/IndentationWidth', node.first_line)
|
|
185
199
|
end
|
|
186
200
|
|
|
187
201
|
def check_indented_internal_methods_style(node)
|
|
@@ -197,7 +211,10 @@ module RuboCop
|
|
|
197
211
|
children_to_check.last << child
|
|
198
212
|
end
|
|
199
213
|
end
|
|
200
|
-
|
|
214
|
+
|
|
215
|
+
children_to_check.each do |group|
|
|
216
|
+
check_alignment(group, governed_base_column(group))
|
|
217
|
+
end
|
|
201
218
|
end
|
|
202
219
|
end
|
|
203
220
|
end
|