rubocop 1.39.0 → 1.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +65 -9
- data/exe/rubocop +1 -1
- data/lib/rubocop/comment_config.rb +5 -0
- data/lib/rubocop/config.rb +33 -9
- data/lib/rubocop/config_loader.rb +14 -5
- data/lib/rubocop/config_loader_resolver.rb +1 -1
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/badge.rb +9 -4
- data/lib/rubocop/cop/base.rb +26 -17
- data/lib/rubocop/cop/commissioner.rb +8 -3
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +22 -6
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb +46 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines.rb +2 -0
- data/lib/rubocop/cop/layout/extra_spacing.rb +10 -6
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +38 -2
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +49 -2
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +61 -2
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -2
- data/lib/rubocop/cop/layout/indentation_style.rb +3 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +5 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_length.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +51 -2
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +49 -2
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +53 -2
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +58 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +2 -2
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -2
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/constant_resolution.rb +4 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -1
- data/lib/rubocop/cop/lint/deprecated_constants.rb +8 -1
- data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +19 -8
- data/lib/rubocop/cop/lint/empty_block.rb +1 -5
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -5
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +13 -3
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +10 -12
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -4
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -3
- data/lib/rubocop/cop/lint/void.rb +6 -6
- data/lib/rubocop/cop/metrics/block_length.rb +9 -4
- data/lib/rubocop/cop/metrics/class_length.rb +10 -5
- data/lib/rubocop/cop/metrics/method_length.rb +9 -4
- data/lib/rubocop/cop/metrics/module_length.rb +10 -5
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -3
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/annotation_comment.rb +13 -6
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +28 -5
- data/lib/rubocop/cop/mixin/line_length_help.rb +8 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +5 -3
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -3
- data/lib/rubocop/cop/mixin/percent_array.rb +3 -5
- data/lib/rubocop/cop/mixin/require_library.rb +2 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +3 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +15 -1
- data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -0
- data/lib/rubocop/cop/naming/inclusive_language.rb +4 -1
- data/lib/rubocop/cop/registry.rb +29 -14
- data/lib/rubocop/cop/style/array_intersect.rb +111 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +66 -0
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +36 -5
- data/lib/rubocop/cop/style/if_with_semicolon.rb +4 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
- data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -0
- data/lib/rubocop/cop/style/redundant_constant_base.rb +85 -0
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +39 -0
- data/lib/rubocop/cop/style/redundant_return.rb +7 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/require_order.rb +140 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +35 -6
- data/lib/rubocop/cop/style/select_by_regexp.rb +8 -4
- data/lib/rubocop/cop/style/semicolon.rb +2 -1
- data/lib/rubocop/cop/style/string_literals.rb +1 -5
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -4
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +32 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +20 -29
- data/lib/rubocop/cops_documentation_generator.rb +22 -3
- data/lib/rubocop/directive_comment.rb +1 -1
- data/lib/rubocop/file_patterns.rb +43 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +3 -1
- data/lib/rubocop/options.rb +8 -0
- data/lib/rubocop/path_util.rb +34 -16
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +4 -1
- data/lib/rubocop/rspec/support.rb +2 -2
- data/lib/rubocop/server/core.rb +1 -1
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +16 -6
- metadata +10 -3
@@ -28,7 +28,10 @@ module RuboCop
|
|
28
28
|
# put the comment.
|
29
29
|
return if new_line_needed_before_closing_brace?(node)
|
30
30
|
|
31
|
-
|
31
|
+
end_range = last_element_range_with_trailing_comma(node).end
|
32
|
+
|
33
|
+
correct_next_line_brace(corrector, end_range)
|
34
|
+
correct_heredoc_argument_method_chain(corrector, end_range)
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
@@ -40,13 +43,19 @@ module RuboCop
|
|
40
43
|
corrector.insert_before(node.loc.end, "\n")
|
41
44
|
end
|
42
45
|
|
43
|
-
def correct_next_line_brace(corrector)
|
46
|
+
def correct_next_line_brace(corrector, end_range)
|
44
47
|
corrector.remove(range_with_surrounding_space(node.loc.end, side: :left))
|
48
|
+
corrector.insert_before(end_range, content_if_comment_present(corrector, node))
|
49
|
+
end
|
45
50
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
51
|
+
def correct_heredoc_argument_method_chain(corrector, end_range)
|
52
|
+
return unless (parent = node.parent)
|
53
|
+
return unless use_heredoc_argument_method_chain?(parent)
|
54
|
+
|
55
|
+
chained_method = range_between(parent.loc.dot.begin_pos, parent.loc.expression.end_pos)
|
56
|
+
|
57
|
+
corrector.remove(chained_method)
|
58
|
+
corrector.insert_after(end_range, chained_method.source)
|
50
59
|
end
|
51
60
|
|
52
61
|
def content_if_comment_present(corrector, node)
|
@@ -61,6 +70,13 @@ module RuboCop
|
|
61
70
|
end
|
62
71
|
end
|
63
72
|
|
73
|
+
def use_heredoc_argument_method_chain?(parent)
|
74
|
+
return false unless node.respond_to?(:first_argument)
|
75
|
+
return false unless (first_argument = node.first_argument)
|
76
|
+
|
77
|
+
parent.call_type? && first_argument.str_type? && first_argument.heredoc?
|
78
|
+
end
|
79
|
+
|
64
80
|
def select_content_to_be_inserted_after_last_element(corrector, node)
|
65
81
|
range = range_between(
|
66
82
|
node.loc.end.begin_pos,
|
@@ -28,8 +28,9 @@ module RuboCop
|
|
28
28
|
/^\s+# This cop (?<special>#{SPECIAL_WORDS.join('|')})?\s*(?<word>.+?) .*/.freeze
|
29
29
|
REPLACEMENT_REGEX = /^\s+# This cop (#{SPECIAL_WORDS.join('|')})?\s*(.+?) /.freeze
|
30
30
|
|
31
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
31
32
|
def on_class(node)
|
32
|
-
return unless (module_node = node.parent)
|
33
|
+
return unless (module_node = node.parent) && node.parent_class
|
33
34
|
|
34
35
|
description_beginning = first_comment_line(module_node)
|
35
36
|
return unless description_beginning
|
@@ -48,6 +49,7 @@ module RuboCop
|
|
48
49
|
end
|
49
50
|
end
|
50
51
|
end
|
52
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
51
53
|
|
52
54
|
private
|
53
55
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Enforces the use of `node.lambda_or_proc?` instead of `node.lambda? || node.proc?`.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# node.lambda? || node.proc?
|
11
|
+
# node.proc? || node.lambda?
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# node.lambda_or_proc?
|
15
|
+
#
|
16
|
+
class LambdaOrProc < Base
|
17
|
+
extend AutoCorrector
|
18
|
+
|
19
|
+
MSG = 'Use `%<prefer>s`.'
|
20
|
+
|
21
|
+
# @!method lambda_or_proc(node)
|
22
|
+
def_node_matcher :lambda_or_proc, <<~PATTERN
|
23
|
+
{
|
24
|
+
(or $(send _node :lambda?) $(send _node :proc?))
|
25
|
+
(or $(send _node :proc?) $(send _node :lambda?))
|
26
|
+
(or
|
27
|
+
(or _ $(send _node :lambda?)) $(send _node :proc?))
|
28
|
+
(or
|
29
|
+
(or _ $(send _node :proc?)) $(send _node :lambda?))
|
30
|
+
}
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
def on_or(node)
|
34
|
+
return unless (lhs, rhs = lambda_or_proc(node))
|
35
|
+
|
36
|
+
offense = lhs.receiver.source_range.join(rhs.source_range.end)
|
37
|
+
prefer = "#{lhs.receiver.source}.lambda_or_proc?"
|
38
|
+
|
39
|
+
add_offense(offense, message: format(MSG, prefer: prefer)) do |corrector|
|
40
|
+
corrector.replace(offense, prefer)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -6,6 +6,7 @@ require_relative 'internal_affairs/empty_line_between_expect_offense_and_correct
|
|
6
6
|
require_relative 'internal_affairs/example_description'
|
7
7
|
require_relative 'internal_affairs/example_heredoc_delimiter'
|
8
8
|
require_relative 'internal_affairs/inherit_deprecated_cop_class'
|
9
|
+
require_relative 'internal_affairs/lambda_or_proc'
|
9
10
|
require_relative 'internal_affairs/location_line_equality_comparison'
|
10
11
|
require_relative 'internal_affairs/method_name_end_with'
|
11
12
|
require_relative 'internal_affairs/method_name_equal'
|
@@ -27,6 +27,8 @@ module RuboCop
|
|
27
27
|
|
28
28
|
def on_new_investigation
|
29
29
|
return if processed_source.tokens.empty?
|
30
|
+
# Quick check if we possibly have consecutive blank lines.
|
31
|
+
return unless processed_source.raw_source.include?("\n\n\n")
|
30
32
|
|
31
33
|
lines = Set.new
|
32
34
|
processed_source.each_token { |token| lines << token.line }
|
@@ -119,12 +119,16 @@ module RuboCop
|
|
119
119
|
def ignored_ranges(ast)
|
120
120
|
return [] unless ast
|
121
121
|
|
122
|
-
@ignored_ranges ||=
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
122
|
+
@ignored_ranges ||= begin
|
123
|
+
ranges = []
|
124
|
+
on_node(:pair, ast) do |pair|
|
125
|
+
next if pair.parent.single_line?
|
126
|
+
|
127
|
+
key, value = *pair
|
128
|
+
ranges << (key.source_range.end_pos...value.source_range.begin_pos)
|
129
|
+
end
|
130
|
+
ranges
|
131
|
+
end
|
128
132
|
end
|
129
133
|
|
130
134
|
def force_equal_sign_alignment?
|
@@ -6,17 +6,49 @@ module RuboCop
|
|
6
6
|
# Checks for a line break before the first element in a
|
7
7
|
# multi-line array.
|
8
8
|
#
|
9
|
-
# @example
|
9
|
+
# @example AllowMultilineFinalElement: false (default)
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# [ :a,
|
13
|
+
# :b]
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
# [ :a, {
|
17
|
+
# :b => :c
|
18
|
+
# }]
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# [:a, :b]
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# [
|
25
|
+
# :a,
|
26
|
+
# :b]
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# [
|
30
|
+
# :a, {
|
31
|
+
# :b => :c
|
32
|
+
# }]
|
33
|
+
#
|
34
|
+
# @example AllowMultilineFinalElement: true
|
10
35
|
#
|
11
36
|
# # bad
|
12
37
|
# [ :a,
|
13
38
|
# :b]
|
14
39
|
#
|
15
40
|
# # good
|
41
|
+
# [ :a, {
|
42
|
+
# :b => :c
|
43
|
+
# }]
|
44
|
+
#
|
45
|
+
# # good
|
16
46
|
# [
|
17
47
|
# :a,
|
18
48
|
# :b]
|
19
49
|
#
|
50
|
+
# # good
|
51
|
+
# [:a, :b]
|
20
52
|
class FirstArrayElementLineBreak < Base
|
21
53
|
include FirstElementLineBreak
|
22
54
|
extend AutoCorrector
|
@@ -26,7 +58,7 @@ module RuboCop
|
|
26
58
|
def on_array(node)
|
27
59
|
return if !node.loc.begin && !assignment_on_same_line?(node)
|
28
60
|
|
29
|
-
check_children_line_break(node, node.children)
|
61
|
+
check_children_line_break(node, node.children, ignore_last: ignore_last_element?)
|
30
62
|
end
|
31
63
|
|
32
64
|
private
|
@@ -35,6 +67,10 @@ module RuboCop
|
|
35
67
|
source = node.source_range.source_line[0...node.loc.column]
|
36
68
|
/\s*=\s*$/.match?(source)
|
37
69
|
end
|
70
|
+
|
71
|
+
def ignore_last_element?
|
72
|
+
!!cop_config['AllowMultilineFinalElement']
|
73
|
+
end
|
38
74
|
end
|
39
75
|
end
|
40
76
|
end
|
@@ -6,16 +6,55 @@ module RuboCop
|
|
6
6
|
# Checks for a line break before the first element in a
|
7
7
|
# multi-line hash.
|
8
8
|
#
|
9
|
-
# @example
|
9
|
+
# @example AllowMultilineFinalElement: false (default)
|
10
10
|
#
|
11
11
|
# # bad
|
12
12
|
# { a: 1,
|
13
13
|
# b: 2}
|
14
14
|
#
|
15
|
+
# # bad
|
16
|
+
# { a: 1, b: {
|
17
|
+
# c: 3
|
18
|
+
# }}
|
19
|
+
#
|
15
20
|
# # good
|
16
21
|
# {
|
17
22
|
# a: 1,
|
18
23
|
# b: 2 }
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# {
|
27
|
+
# a: 1, b: {
|
28
|
+
# c: 3
|
29
|
+
# }}
|
30
|
+
#
|
31
|
+
# @example AllowMultilineFinalElement: true
|
32
|
+
#
|
33
|
+
# # bad
|
34
|
+
# { a: 1,
|
35
|
+
# b: 2}
|
36
|
+
#
|
37
|
+
# # bad
|
38
|
+
# { a: 1,
|
39
|
+
# b: {
|
40
|
+
# c: 3
|
41
|
+
# }}
|
42
|
+
#
|
43
|
+
# # good
|
44
|
+
# { a: 1, b: {
|
45
|
+
# c: 3
|
46
|
+
# }}
|
47
|
+
#
|
48
|
+
# # good
|
49
|
+
# {
|
50
|
+
# a: 1,
|
51
|
+
# b: 2 }
|
52
|
+
#
|
53
|
+
# # good
|
54
|
+
# {
|
55
|
+
# a: 1, b: {
|
56
|
+
# c: 3
|
57
|
+
# }}
|
19
58
|
class FirstHashElementLineBreak < Base
|
20
59
|
include FirstElementLineBreak
|
21
60
|
extend AutoCorrector
|
@@ -25,7 +64,15 @@ module RuboCop
|
|
25
64
|
def on_hash(node)
|
26
65
|
# node.loc.begin tells us whether the hash opens with a {
|
27
66
|
# If it doesn't, Style/FirstMethodArgumentLineBreak will handle it
|
28
|
-
|
67
|
+
return unless node.loc.begin
|
68
|
+
|
69
|
+
check_children_line_break(node, node.children, ignore_last: ignore_last_element?)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def ignore_last_element?
|
75
|
+
!!cop_config['AllowMultilineFinalElement']
|
29
76
|
end
|
30
77
|
end
|
31
78
|
end
|
@@ -6,17 +6,70 @@ module RuboCop
|
|
6
6
|
# Checks for a line break before the first argument in a
|
7
7
|
# multi-line method call.
|
8
8
|
#
|
9
|
-
# @example
|
9
|
+
# @example AllowMultilineFinalElement: false (default)
|
10
10
|
#
|
11
11
|
# # bad
|
12
12
|
# method(foo, bar,
|
13
13
|
# baz)
|
14
14
|
#
|
15
|
+
# # bad
|
16
|
+
# method(foo, bar, {
|
17
|
+
# baz: "a",
|
18
|
+
# qux: "b",
|
19
|
+
# })
|
20
|
+
#
|
15
21
|
# # good
|
16
22
|
# method(
|
17
23
|
# foo, bar,
|
18
24
|
# baz)
|
19
25
|
#
|
26
|
+
# # good
|
27
|
+
# method(
|
28
|
+
# foo, bar, {
|
29
|
+
# baz: "a",
|
30
|
+
# qux: "b",
|
31
|
+
# })
|
32
|
+
#
|
33
|
+
# # ignored
|
34
|
+
# method foo, bar,
|
35
|
+
# baz
|
36
|
+
#
|
37
|
+
# @example AllowMultilineFinalElement: true
|
38
|
+
#
|
39
|
+
# # bad
|
40
|
+
# method(foo, bar,
|
41
|
+
# baz)
|
42
|
+
#
|
43
|
+
# # bad
|
44
|
+
# method(foo,
|
45
|
+
# bar,
|
46
|
+
# {
|
47
|
+
# baz: "a",
|
48
|
+
# qux: "b",
|
49
|
+
# }
|
50
|
+
# )
|
51
|
+
#
|
52
|
+
# # good
|
53
|
+
# method(foo, bar, {
|
54
|
+
# baz: "a",
|
55
|
+
# qux: "b",
|
56
|
+
# })
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# method(
|
60
|
+
# foo, bar,
|
61
|
+
# baz)
|
62
|
+
#
|
63
|
+
# # good
|
64
|
+
# method(
|
65
|
+
# foo,
|
66
|
+
# bar,
|
67
|
+
# {
|
68
|
+
# baz: "a",
|
69
|
+
# qux: "b",
|
70
|
+
# }
|
71
|
+
# )
|
72
|
+
#
|
20
73
|
# # ignored
|
21
74
|
# method foo, bar,
|
22
75
|
# baz
|
@@ -38,10 +91,16 @@ module RuboCop
|
|
38
91
|
last_arg = args.last
|
39
92
|
args.concat(args.pop.children) if last_arg&.hash_type? && !last_arg&.braces?
|
40
93
|
|
41
|
-
check_method_line_break(node, args)
|
94
|
+
check_method_line_break(node, args, ignore_last: ignore_last_element?)
|
42
95
|
end
|
43
96
|
alias on_csend on_send
|
44
97
|
alias on_super on_send
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def ignore_last_element?
|
102
|
+
!!cop_config['AllowMultilineFinalElement']
|
103
|
+
end
|
45
104
|
end
|
46
105
|
end
|
47
106
|
end
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Checks for a line break before the first parameter in a
|
7
7
|
# multi-line method parameter definition.
|
8
8
|
#
|
9
|
-
# @example
|
9
|
+
# @example AllowMultilineFinalElement: false (default)
|
10
10
|
#
|
11
11
|
# # bad
|
12
12
|
# def method(foo, bar,
|
@@ -14,6 +14,13 @@ module RuboCop
|
|
14
14
|
# do_something
|
15
15
|
# end
|
16
16
|
#
|
17
|
+
# # bad
|
18
|
+
# def method(foo, bar, baz = {
|
19
|
+
# :a => "b",
|
20
|
+
# })
|
21
|
+
# do_something
|
22
|
+
# end
|
23
|
+
#
|
17
24
|
# # good
|
18
25
|
# def method(
|
19
26
|
# foo, bar,
|
@@ -21,11 +28,48 @@ module RuboCop
|
|
21
28
|
# do_something
|
22
29
|
# end
|
23
30
|
#
|
31
|
+
# # good
|
32
|
+
# def method(
|
33
|
+
# foo, bar, baz = {
|
34
|
+
# :a => "b",
|
35
|
+
# })
|
36
|
+
# do_something
|
37
|
+
# end
|
38
|
+
#
|
24
39
|
# # ignored
|
25
40
|
# def method foo,
|
26
41
|
# bar
|
27
42
|
# do_something
|
28
43
|
# end
|
44
|
+
#
|
45
|
+
# @example AllowMultilineFinalElement: true
|
46
|
+
#
|
47
|
+
# # bad
|
48
|
+
# def method(foo, bar,
|
49
|
+
# baz)
|
50
|
+
# do_something
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# # good
|
54
|
+
# def method(foo, bar, baz = {
|
55
|
+
# :a => "b",
|
56
|
+
# })
|
57
|
+
# do_something
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# # good
|
61
|
+
# def method(
|
62
|
+
# foo, bar,
|
63
|
+
# baz)
|
64
|
+
# do_something
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# # ignored
|
68
|
+
# def method foo,
|
69
|
+
# bar
|
70
|
+
# do_something
|
71
|
+
# end
|
72
|
+
#
|
29
73
|
class FirstMethodParameterLineBreak < Base
|
30
74
|
include FirstElementLineBreak
|
31
75
|
extend AutoCorrector
|
@@ -33,9 +77,15 @@ module RuboCop
|
|
33
77
|
MSG = 'Add a line break before the first parameter of a multi-line method parameter list.'
|
34
78
|
|
35
79
|
def on_def(node)
|
36
|
-
check_method_line_break(node, node.arguments)
|
80
|
+
check_method_line_break(node, node.arguments, ignore_last: ignore_last_element?)
|
37
81
|
end
|
38
82
|
alias on_defs on_def
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def ignore_last_element?
|
87
|
+
!!cop_config['AllowMultilineFinalElement']
|
88
|
+
end
|
39
89
|
end
|
40
90
|
end
|
41
91
|
end
|
@@ -90,7 +90,8 @@ module RuboCop
|
|
90
90
|
# which lines start inside a string literal?
|
91
91
|
return [] if ast.nil?
|
92
92
|
|
93
|
-
|
93
|
+
ranges = Set.new
|
94
|
+
ast.each_node(:str, :dstr) do |str|
|
94
95
|
loc = str.location
|
95
96
|
|
96
97
|
if str.heredoc?
|
@@ -99,6 +100,7 @@ module RuboCop
|
|
99
100
|
ranges << loc.expression
|
100
101
|
end
|
101
102
|
end
|
103
|
+
ranges
|
102
104
|
end
|
103
105
|
|
104
106
|
def message(_node)
|
@@ -51,7 +51,11 @@ module RuboCop
|
|
51
51
|
private_constant :LINE_1_ENDING, :LINE_2_BEGINNING,
|
52
52
|
:LEADING_STYLE_OFFENSE, :TRAILING_STYLE_OFFENSE
|
53
53
|
|
54
|
+
# rubocop:disable Metrics/AbcSize
|
54
55
|
def on_dstr(node)
|
56
|
+
# Quick check if we possibly have line continuations.
|
57
|
+
return unless node.source.include?('\\')
|
58
|
+
|
55
59
|
end_of_first_line = node.loc.expression.begin_pos - node.loc.expression.column
|
56
60
|
|
57
61
|
raw_lines(node).each_cons(2) do |raw_line_one, raw_line_two|
|
@@ -66,6 +70,7 @@ module RuboCop
|
|
66
70
|
end
|
67
71
|
end
|
68
72
|
end
|
73
|
+
# rubocop:enable Metrics/AbcSize
|
69
74
|
|
70
75
|
private
|
71
76
|
|
@@ -31,7 +31,10 @@ module RuboCop
|
|
31
31
|
include RangeHelp
|
32
32
|
extend AutoCorrector
|
33
33
|
|
34
|
+
# rubocop:disable Metrics/AbcSize
|
34
35
|
def on_new_investigation
|
36
|
+
return unless processed_source.raw_source.include?('\\')
|
37
|
+
|
35
38
|
last_line = last_line(processed_source)
|
36
39
|
|
37
40
|
@ignored_ranges = string_literal_ranges(processed_source.ast) +
|
@@ -44,6 +47,7 @@ module RuboCop
|
|
44
47
|
investigate(line, line_number)
|
45
48
|
end
|
46
49
|
end
|
50
|
+
# rubocop:enable Metrics/AbcSize
|
47
51
|
|
48
52
|
private
|
49
53
|
|
@@ -92,7 +96,8 @@ module RuboCop
|
|
92
96
|
# which lines start inside a string literal?
|
93
97
|
return [] if ast.nil?
|
94
98
|
|
95
|
-
|
99
|
+
ranges = Set.new
|
100
|
+
ast.each_node(:str, :dstr) do |str|
|
96
101
|
loc = str.location
|
97
102
|
|
98
103
|
if str.heredoc?
|
@@ -101,6 +106,7 @@ module RuboCop
|
|
101
106
|
ranges << loc.expression
|
102
107
|
end
|
103
108
|
end
|
109
|
+
ranges
|
104
110
|
end
|
105
111
|
|
106
112
|
def comment_ranges(comments)
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Ensures that each item in a multi-line array
|
7
7
|
# starts on a separate line.
|
8
8
|
#
|
9
|
-
# @example
|
9
|
+
# @example AllowMultilineFinalElement: false (default)
|
10
10
|
#
|
11
11
|
# # bad
|
12
12
|
# [
|
@@ -14,12 +14,55 @@ module RuboCop
|
|
14
14
|
# c
|
15
15
|
# ]
|
16
16
|
#
|
17
|
+
# # bad
|
18
|
+
# [ a, b, foo(
|
19
|
+
# bar
|
20
|
+
# )]
|
21
|
+
#
|
17
22
|
# # good
|
18
23
|
# [
|
19
24
|
# a,
|
20
25
|
# b,
|
21
26
|
# c
|
22
27
|
# ]
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# [
|
31
|
+
# a,
|
32
|
+
# b,
|
33
|
+
# foo(
|
34
|
+
# bar
|
35
|
+
# )
|
36
|
+
# ]
|
37
|
+
#
|
38
|
+
# @example AllowMultilineFinalElement: true
|
39
|
+
#
|
40
|
+
# # bad
|
41
|
+
# [
|
42
|
+
# a, b,
|
43
|
+
# c
|
44
|
+
# ]
|
45
|
+
#
|
46
|
+
# # good
|
47
|
+
# [ a, b, foo(
|
48
|
+
# bar
|
49
|
+
# )]
|
50
|
+
#
|
51
|
+
# # good
|
52
|
+
# [
|
53
|
+
# a,
|
54
|
+
# b,
|
55
|
+
# c
|
56
|
+
# ]
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# [
|
60
|
+
# a,
|
61
|
+
# b,
|
62
|
+
# foo(
|
63
|
+
# bar
|
64
|
+
# )
|
65
|
+
# ]
|
23
66
|
class MultilineArrayLineBreaks < Base
|
24
67
|
include MultilineElementLineBreaks
|
25
68
|
extend AutoCorrector
|
@@ -27,7 +70,13 @@ module RuboCop
|
|
27
70
|
MSG = 'Each item in a multi-line array must start on a separate line.'
|
28
71
|
|
29
72
|
def on_array(node)
|
30
|
-
check_line_breaks(node, node.children)
|
73
|
+
check_line_breaks(node, node.children, ignore_last: ignore_last_element?)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def ignore_last_element?
|
79
|
+
!!cop_config['AllowMultilineFinalElement']
|
31
80
|
end
|
32
81
|
end
|
33
82
|
end
|