rubocop 1.39.0 → 1.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +91 -10
- data/exe/rubocop +1 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/comment_config.rb +5 -0
- data/lib/rubocop/config.rb +39 -15
- data/lib/rubocop/config_loader.rb +14 -5
- data/lib/rubocop/config_loader_resolver.rb +6 -2
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/badge.rb +9 -4
- data/lib/rubocop/cop/base.rb +84 -74
- data/lib/rubocop/cop/commissioner.rb +8 -3
- data/lib/rubocop/cop/cop.rb +29 -29
- data/lib/rubocop/cop/corrector.rb +23 -11
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +22 -6
- data/lib/rubocop/cop/gemspec/dependency_version.rb +16 -18
- 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/class_structure.rb +32 -11
- data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
- 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 +7 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +5 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -5
- 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_block_layout.rb +1 -1
- 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/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +11 -4
- 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/out_of_range_regexp_ref.rb +19 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +15 -3
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +3 -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/unused_method_argument.rb +2 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -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/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -4
- 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/preceding_following_alignment.rb +1 -1
- 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/block_forwarding.rb +1 -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 +51 -36
- data/lib/rubocop/cop/security/compound_hash.rb +2 -1
- data/lib/rubocop/cop/style/alias.rb +9 -1
- data/lib/rubocop/cop/style/array_intersect.rb +111 -0
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +86 -0
- data/lib/rubocop/cop/style/documentation.rb +11 -5
- data/lib/rubocop/cop/style/guard_clause.rb +44 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +10 -7
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
- 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/map_to_set.rb +61 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
- data/lib/rubocop/cop/style/min_max_comparison.rb +73 -0
- 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/redundant_string_escape.rb +6 -3
- data/lib/rubocop/cop/style/require_order.rb +142 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +35 -6
- data/lib/rubocop/cop/style/select_by_regexp.rb +13 -5
- data/lib/rubocop/cop/style/semicolon.rb +2 -1
- data/lib/rubocop/cop/style/signal_exception.rb +8 -6
- data/lib/rubocop/cop/style/string_literals.rb +1 -5
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -4
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
- data/lib/rubocop/cop/style/word_array.rb +41 -0
- data/lib/rubocop/cop/style/yoda_expression.rb +74 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +31 -14
- data/lib/rubocop/cop/team.rb +30 -30
- 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 +17 -29
- data/lib/rubocop/cops_documentation_generator.rb +33 -11
- 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 +5 -1
- data/lib/rubocop/options.rb +8 -0
- data/lib/rubocop/path_util.rb +39 -16
- data/lib/rubocop/result_cache.rb +2 -2
- data/lib/rubocop/rspec/cop_helper.rb +4 -1
- data/lib/rubocop/rspec/support.rb +2 -2
- data/lib/rubocop/runner.rb +10 -3
- data/lib/rubocop/server/core.rb +1 -1
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +1 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +19 -6
- metadata +19 -9
@@ -154,7 +154,9 @@ module RuboCop
|
|
154
154
|
end
|
155
155
|
|
156
156
|
def less_indented?(line)
|
157
|
-
|
157
|
+
rule = config.for_cop('Layout/AccessModifierIndentation')['EnforcedStyle'] == 'outdent'
|
158
|
+
access_modifier = 'private|protected|public'
|
159
|
+
/\A\s*(end\b|[)}\]])/.match?(line) || (rule && /\A\s*(#{access_modifier})\b/.match?(line))
|
158
160
|
end
|
159
161
|
|
160
162
|
def two_alternatives?(line)
|
@@ -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
|
@@ -40,10 +40,13 @@ module RuboCop
|
|
40
40
|
MSG = '%<type>s detected in indentation.'
|
41
41
|
|
42
42
|
def on_new_investigation
|
43
|
-
str_ranges =
|
43
|
+
str_ranges = nil
|
44
44
|
|
45
45
|
processed_source.lines.each.with_index(1) do |line, lineno|
|
46
46
|
next unless (range = find_offense(line, lineno))
|
47
|
+
|
48
|
+
# Perform costly calculation only when needed.
|
49
|
+
str_ranges ||= string_literal_ranges(processed_source.ast)
|
47
50
|
next if in_string_literal?(str_ranges, range)
|
48
51
|
|
49
52
|
add_offense(range) { |corrector| autocorrect(corrector, range) }
|
@@ -90,7 +93,8 @@ module RuboCop
|
|
90
93
|
# which lines start inside a string literal?
|
91
94
|
return [] if ast.nil?
|
92
95
|
|
93
|
-
|
96
|
+
ranges = Set.new
|
97
|
+
ast.each_node(:str, :dstr) do |str|
|
94
98
|
loc = str.location
|
95
99
|
|
96
100
|
if str.heredoc?
|
@@ -99,6 +103,7 @@ module RuboCop
|
|
99
103
|
ranges << loc.expression
|
100
104
|
end
|
101
105
|
end
|
106
|
+
ranges
|
102
107
|
end
|
103
108
|
|
104
109
|
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
|
|
@@ -32,10 +32,9 @@ module RuboCop
|
|
32
32
|
extend AutoCorrector
|
33
33
|
|
34
34
|
def on_new_investigation
|
35
|
-
|
35
|
+
return unless processed_source.raw_source.include?('\\')
|
36
36
|
|
37
|
-
|
38
|
-
comment_ranges(processed_source.comments)
|
37
|
+
last_line = last_line(processed_source)
|
39
38
|
|
40
39
|
processed_source.raw_source.lines.each_with_index do |line, index|
|
41
40
|
break if index >= last_line
|
@@ -92,7 +91,8 @@ module RuboCop
|
|
92
91
|
# which lines start inside a string literal?
|
93
92
|
return [] if ast.nil?
|
94
93
|
|
95
|
-
|
94
|
+
ranges = Set.new
|
95
|
+
ast.each_node(:str, :dstr) do |str|
|
96
96
|
loc = str.location
|
97
97
|
|
98
98
|
if str.heredoc?
|
@@ -101,6 +101,7 @@ module RuboCop
|
|
101
101
|
ranges << loc.expression
|
102
102
|
end
|
103
103
|
end
|
104
|
+
ranges
|
104
105
|
end
|
105
106
|
|
106
107
|
def comment_ranges(comments)
|
@@ -114,7 +115,12 @@ module RuboCop
|
|
114
115
|
end
|
115
116
|
|
116
117
|
def ignore_range?(backtick_range)
|
117
|
-
|
118
|
+
ignored_ranges.any? { |range| range.contains?(backtick_range) }
|
119
|
+
end
|
120
|
+
|
121
|
+
def ignored_ranges
|
122
|
+
@ignored_ranges ||= string_literal_ranges(processed_source.ast) +
|
123
|
+
comment_ranges(processed_source.comments)
|
118
124
|
end
|
119
125
|
|
120
126
|
def no_space_style?
|
@@ -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
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Ensures that each key in a multi-line hash
|
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,54 @@ module RuboCop
|
|
14
14
|
# c: 3
|
15
15
|
# }
|
16
16
|
#
|
17
|
+
# # bad
|
18
|
+
# { a: 1, b: {
|
19
|
+
# c: 3,
|
20
|
+
# }}
|
21
|
+
#
|
17
22
|
# # good
|
18
23
|
# {
|
19
24
|
# a: 1,
|
20
25
|
# b: 2,
|
21
26
|
# c: 3
|
22
27
|
# }
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# {
|
31
|
+
# a: 1,
|
32
|
+
# b: {
|
33
|
+
# c: 3,
|
34
|
+
# }
|
35
|
+
# }
|
36
|
+
#
|
37
|
+
# @example AllowMultilineFinalElement: true
|
38
|
+
#
|
39
|
+
# # bad
|
40
|
+
# {
|
41
|
+
# a: 1, b: 2,
|
42
|
+
# c: 3
|
43
|
+
# }
|
44
|
+
#
|
45
|
+
# # good
|
46
|
+
# { a: 1, b: {
|
47
|
+
# c: 3,
|
48
|
+
# }}
|
49
|
+
#
|
50
|
+
# # good
|
51
|
+
# {
|
52
|
+
# a: 1,
|
53
|
+
# b: 2,
|
54
|
+
# c: 3
|
55
|
+
# }
|
56
|
+
#
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# {
|
60
|
+
# a: 1,
|
61
|
+
# b: {
|
62
|
+
# c: 3,
|
63
|
+
# }
|
64
|
+
# }
|
23
65
|
class MultilineHashKeyLineBreaks < Base
|
24
66
|
include MultilineElementLineBreaks
|
25
67
|
extend AutoCorrector
|
@@ -31,8 +73,9 @@ module RuboCop
|
|
31
73
|
# braces like {foo: 1}. That is, not a kwargs hashes.
|
32
74
|
# Style/MultilineMethodArgumentLineBreaks handles those.
|
33
75
|
return unless starts_with_curly_brace?(node)
|
76
|
+
return unless node.loc.begin
|
34
77
|
|
35
|
-
check_line_breaks(node, node.children
|
78
|
+
check_line_breaks(node, node.children, ignore_last: ignore_last_element?)
|
36
79
|
end
|
37
80
|
|
38
81
|
private
|
@@ -40,6 +83,10 @@ module RuboCop
|
|
40
83
|
def starts_with_curly_brace?(node)
|
41
84
|
node.loc.begin
|
42
85
|
end
|
86
|
+
|
87
|
+
def ignore_last_element?
|
88
|
+
!!cop_config['AllowMultilineFinalElement']
|
89
|
+
end
|
43
90
|
end
|
44
91
|
end
|
45
92
|
end
|