rubocop 1.40.0 → 1.43.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 +52 -2
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +34 -11
- data/lib/rubocop/config_loader.rb +9 -0
- data/lib/rubocop/config_loader_resolver.rb +5 -1
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/badge.rb +9 -4
- data/lib/rubocop/cop/base.rb +83 -66
- 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/gemspec/dependency_version.rb +16 -18
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +3 -1
- 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/constant_resolution.rb +4 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -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/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/redundant_cop_disable_directive.rb +3 -1
- 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 +8 -19
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +71 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -3
- data/lib/rubocop/cop/metrics/class_length.rb +1 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
- 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 +2 -2
- 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 +14 -2
- 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 +2 -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 +28 -25
- data/lib/rubocop/cop/security/compound_hash.rb +2 -1
- data/lib/rubocop/cop/style/alias.rb +9 -1
- 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 +17 -9
- data/lib/rubocop/cop/style/hash_each_methods.rb +13 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +11 -7
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -3
- 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_call_with_args_parentheses/omit_parentheses.rb +12 -9
- 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/missing_else.rb +13 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +15 -1
- data/lib/rubocop/cop/style/redundant_constant_base.rb +13 -0
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +39 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -3
- data/lib/rubocop/cop/style/require_order.rb +63 -9
- data/lib/rubocop/cop/style/select_by_regexp.rb +6 -2
- 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_hash_keys.rb +4 -1
- 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 +81 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +31 -14
- data/lib/rubocop/cop/team.rb +29 -29
- data/lib/rubocop/cop/util.rb +31 -4
- data/lib/rubocop/cop/variable_force.rb +0 -3
- 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.rb +2 -0
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/path_util.rb +38 -22
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/runner.rb +10 -3
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +0 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +7 -1
- metadata +16 -10
- data/lib/rubocop/optimized_patterns.rb +0 -38
@@ -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
|
@@ -9,13 +9,18 @@ module RuboCop
|
|
9
9
|
# NOTE: This cop does not move the first argument, if you want that to
|
10
10
|
# be on a separate line, see `Layout/FirstMethodArgumentLineBreak`.
|
11
11
|
#
|
12
|
-
# @example
|
12
|
+
# @example AllowMultilineFinalElement: false (default)
|
13
13
|
#
|
14
14
|
# # bad
|
15
15
|
# foo(a, b,
|
16
16
|
# c
|
17
17
|
# )
|
18
18
|
#
|
19
|
+
# # bad
|
20
|
+
# foo(a, b, {
|
21
|
+
# foo: "bar",
|
22
|
+
# })
|
23
|
+
#
|
19
24
|
# # good
|
20
25
|
# foo(
|
21
26
|
# a,
|
@@ -25,6 +30,46 @@ module RuboCop
|
|
25
30
|
#
|
26
31
|
# # good
|
27
32
|
# foo(a, b, c)
|
33
|
+
#
|
34
|
+
# # good
|
35
|
+
# foo(
|
36
|
+
# a,
|
37
|
+
# b,
|
38
|
+
# {
|
39
|
+
# foo: "bar",
|
40
|
+
# }
|
41
|
+
# )
|
42
|
+
#
|
43
|
+
# @example AllowMultilineFinalElement: true
|
44
|
+
#
|
45
|
+
# # bad
|
46
|
+
# foo(a, b,
|
47
|
+
# c
|
48
|
+
# )
|
49
|
+
#
|
50
|
+
# # good
|
51
|
+
# foo(a, b, {
|
52
|
+
# foo: "bar",
|
53
|
+
# })
|
54
|
+
#
|
55
|
+
# # good
|
56
|
+
# foo(
|
57
|
+
# a,
|
58
|
+
# b,
|
59
|
+
# c
|
60
|
+
# )
|
61
|
+
#
|
62
|
+
# # good
|
63
|
+
# foo(a, b, c)
|
64
|
+
#
|
65
|
+
# # good
|
66
|
+
# foo(
|
67
|
+
# a,
|
68
|
+
# b,
|
69
|
+
# {
|
70
|
+
# foo: "bar",
|
71
|
+
# }
|
72
|
+
# )
|
28
73
|
class MultilineMethodArgumentLineBreaks < Base
|
29
74
|
include MultilineElementLineBreaks
|
30
75
|
extend AutoCorrector
|
@@ -45,7 +90,13 @@ module RuboCop
|
|
45
90
|
last_arg = args.last
|
46
91
|
args = args[0...-1] + last_arg.children if last_arg&.hash_type? && !last_arg&.braces?
|
47
92
|
|
48
|
-
check_line_breaks(node, args)
|
93
|
+
check_line_breaks(node, args, ignore_last: ignore_last_element?)
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def ignore_last_element?
|
99
|
+
!!cop_config['AllowMultilineFinalElement']
|
49
100
|
end
|
50
101
|
end
|
51
102
|
end
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
# NOTE: This cop does not move the first argument, if you want that to
|
10
10
|
# be on a separate line, see `Layout/FirstMethodParameterLineBreak`.
|
11
11
|
#
|
12
|
-
# @example
|
12
|
+
# @example AllowMultilineFinalElement: false (default)
|
13
13
|
#
|
14
14
|
# # bad
|
15
15
|
# def foo(a, b,
|
@@ -17,6 +17,47 @@ module RuboCop
|
|
17
17
|
# )
|
18
18
|
# end
|
19
19
|
#
|
20
|
+
# # bad
|
21
|
+
# def foo(a, b = {
|
22
|
+
# foo: "bar",
|
23
|
+
# })
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# def foo(
|
28
|
+
# a,
|
29
|
+
# b,
|
30
|
+
# c
|
31
|
+
# )
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# # good
|
35
|
+
# def foo(
|
36
|
+
# a,
|
37
|
+
# b = {
|
38
|
+
# foo: "bar",
|
39
|
+
# }
|
40
|
+
# )
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# # good
|
44
|
+
# def foo(a, b, c)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# @example AllowMultilineFinalElement: true
|
48
|
+
#
|
49
|
+
# # bad
|
50
|
+
# def foo(a, b,
|
51
|
+
# c
|
52
|
+
# )
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# # good
|
56
|
+
# def foo(a, b = {
|
57
|
+
# foo: "bar",
|
58
|
+
# })
|
59
|
+
# end
|
60
|
+
#
|
20
61
|
# # good
|
21
62
|
# def foo(
|
22
63
|
# a,
|
@@ -26,6 +67,15 @@ module RuboCop
|
|
26
67
|
# end
|
27
68
|
#
|
28
69
|
# # good
|
70
|
+
# def foo(
|
71
|
+
# a,
|
72
|
+
# b = {
|
73
|
+
# foo: "bar",
|
74
|
+
# }
|
75
|
+
# )
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# # good
|
29
79
|
# def foo(a, b, c)
|
30
80
|
# end
|
31
81
|
class MultilineMethodParameterLineBreaks < Base
|
@@ -37,7 +87,13 @@ module RuboCop
|
|
37
87
|
def on_def(node)
|
38
88
|
return if node.arguments.empty?
|
39
89
|
|
40
|
-
check_line_breaks(node, node.arguments)
|
90
|
+
check_line_breaks(node, node.arguments, ignore_last: ignore_last_element?)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def ignore_last_element?
|
96
|
+
!!cop_config['AllowMultilineFinalElement']
|
41
97
|
end
|
42
98
|
end
|
43
99
|
end
|
@@ -84,11 +84,11 @@ module RuboCop
|
|
84
84
|
return true if other_cop_takes_precedence?(node)
|
85
85
|
|
86
86
|
!cop_config['InspectBlocks'] && (node.block_type? ||
|
87
|
-
node
|
87
|
+
any_descendant?(node, :block, &:multiline?))
|
88
88
|
end
|
89
89
|
|
90
90
|
def other_cop_takes_precedence?(node)
|
91
|
-
single_line_block_chain_enabled? && node
|
91
|
+
single_line_block_chain_enabled? && any_descendant?(node, :block) do |block_node|
|
92
92
|
block_node.parent.send_type? && block_node.parent.loc.dot && !block_node.multiline?
|
93
93
|
end
|
94
94
|
end
|
@@ -256,7 +256,7 @@ module RuboCop
|
|
256
256
|
# regular dotted method calls bind more tightly than operators
|
257
257
|
# so we need to climb up the AST past them
|
258
258
|
node.each_ancestor do |ancestor|
|
259
|
-
return true if ancestor.and_type? || ancestor.or_type?
|
259
|
+
return true if ancestor.and_type? || ancestor.or_type? || ancestor.range_type?
|
260
260
|
return false unless ancestor.send_type?
|
261
261
|
return true if ancestor.operator_method?
|
262
262
|
end
|
@@ -79,7 +79,7 @@ module RuboCop
|
|
79
79
|
def ends_in_end?(processed_source)
|
80
80
|
buffer = processed_source.buffer
|
81
81
|
|
82
|
-
return true if buffer.source.
|
82
|
+
return true if buffer.source.match?(/\s*__END__/)
|
83
83
|
return false if processed_source.tokens.empty?
|
84
84
|
|
85
85
|
extra = buffer.source[processed_source.tokens.last.end_pos..]
|
@@ -47,7 +47,6 @@ module RuboCop
|
|
47
47
|
MSG = 'Trailing whitespace detected.'
|
48
48
|
|
49
49
|
def on_new_investigation
|
50
|
-
@heredocs = extract_heredocs(processed_source.ast)
|
51
50
|
processed_source.lines.each_with_index do |line, index|
|
52
51
|
next unless line.end_with?(' ', "\t")
|
53
52
|
|
@@ -102,17 +101,25 @@ module RuboCop
|
|
102
101
|
end
|
103
102
|
|
104
103
|
def find_heredoc(line_number)
|
105
|
-
|
104
|
+
heredocs.each { |node, r| return node if r.include?(line_number) }
|
106
105
|
nil
|
107
106
|
end
|
108
107
|
|
108
|
+
def heredocs
|
109
|
+
@heredocs ||= extract_heredocs(processed_source.ast)
|
110
|
+
end
|
111
|
+
|
109
112
|
def extract_heredocs(ast)
|
110
113
|
return [] unless ast
|
111
114
|
|
112
|
-
|
115
|
+
heredocs = []
|
116
|
+
ast.each_node(:str, :dstr, :xstr) do |node|
|
117
|
+
next unless node.heredoc?
|
118
|
+
|
113
119
|
body = node.location.heredoc_body
|
114
|
-
[node, body.first_line...body.last_line]
|
120
|
+
heredocs << [node, body.first_line...body.last_line]
|
115
121
|
end
|
122
|
+
heredocs
|
116
123
|
end
|
117
124
|
|
118
125
|
def offense_range(lineno, line)
|
@@ -16,6 +16,10 @@ module RuboCop
|
|
16
16
|
# using the same name a namespace and a class. To avoid too many unnecessary
|
17
17
|
# offenses, Enable this cop with `Only: [The, Constant, Names, Causing, Issues]`
|
18
18
|
#
|
19
|
+
# NOTE: `Style/RedundantConstantBase` cop is disabled if this cop is enabled to prevent
|
20
|
+
# conflicting rules. Because it respects user configurations that want to enable
|
21
|
+
# this cop which is disabled by default.
|
22
|
+
#
|
19
23
|
# @example
|
20
24
|
# # By default checks every constant
|
21
25
|
#
|
@@ -96,8 +96,10 @@ module RuboCop
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def debugger_method?(send_node)
|
99
|
+
method_name = send_node.method_name
|
100
|
+
|
99
101
|
debugger_methods.any? do |method|
|
100
|
-
next unless method[:method_name] ==
|
102
|
+
next unless method[:method_name] == method_name
|
101
103
|
|
102
104
|
if method[:receiver].nil?
|
103
105
|
send_node.receiver.nil?
|
@@ -57,19 +57,20 @@ module RuboCop
|
|
57
57
|
def initialize(config = nil, options = nil)
|
58
58
|
super
|
59
59
|
@definitions = {}
|
60
|
+
@scopes = Hash.new { |hash, key| hash[key] = [] }
|
60
61
|
end
|
61
62
|
|
62
63
|
def on_def(node)
|
63
64
|
# if a method definition is inside an if, it is very likely
|
64
65
|
# that a different definition is used depending on platform, etc.
|
65
|
-
return if node.
|
66
|
+
return if node.each_ancestor.any?(&:if_type?)
|
66
67
|
return if possible_dsl?(node)
|
67
68
|
|
68
69
|
found_instance_method(node, node.method_name)
|
69
70
|
end
|
70
71
|
|
71
72
|
def on_defs(node)
|
72
|
-
return if node.
|
73
|
+
return if node.each_ancestor.any?(&:if_type?)
|
73
74
|
return if possible_dsl?(node)
|
74
75
|
|
75
76
|
if node.receiver.const_type?
|
@@ -157,16 +158,18 @@ module RuboCop
|
|
157
158
|
|
158
159
|
def found_method(node, method_name)
|
159
160
|
key = method_key(node, method_name)
|
161
|
+
scope = node.each_ancestor(:rescue, :ensure).first&.type
|
160
162
|
|
161
163
|
if @definitions.key?(key)
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
164
|
+
if scope && !@scopes[scope].include?(key)
|
165
|
+
@definitions[key] = node
|
166
|
+
@scopes[scope] << key
|
167
|
+
return
|
168
|
+
end
|
169
|
+
|
167
170
|
message = message_for_dup(node, method_name, key)
|
168
171
|
|
169
|
-
add_offense(
|
172
|
+
add_offense(location(node), message: message)
|
170
173
|
else
|
171
174
|
@definitions[key] = node
|
172
175
|
end
|
@@ -180,6 +183,14 @@ module RuboCop
|
|
180
183
|
end
|
181
184
|
end
|
182
185
|
|
186
|
+
def location(node)
|
187
|
+
if DEF_TYPES.include?(node.type)
|
188
|
+
node.loc.keyword.join(node.loc.name)
|
189
|
+
else
|
190
|
+
node.loc.expression
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
183
194
|
def on_attr(node, attr_name, args)
|
184
195
|
case attr_name
|
185
196
|
when :attr
|
@@ -44,7 +44,6 @@ module RuboCop
|
|
44
44
|
class NonAtomicFileOperation < Base
|
45
45
|
extend AutoCorrector
|
46
46
|
include Alignment
|
47
|
-
include RangeHelp
|
48
47
|
|
49
48
|
MSG_REMOVE_FILE_EXIST_CHECK = 'Remove unnecessary existence check ' \
|
50
49
|
'`%<receiver>s.%<method_name>s`.'
|
@@ -101,10 +100,11 @@ module RuboCop
|
|
101
100
|
def register_offense(node, exist_node)
|
102
101
|
add_offense(node, message: message_change_force_method(node)) unless force_method?(node)
|
103
102
|
|
104
|
-
|
105
|
-
|
103
|
+
parent = node.parent
|
104
|
+
range = parent.loc.keyword.begin.join(parent.condition.source_range.end)
|
105
|
+
|
106
106
|
add_offense(range, message: message_remove_file_exist_check(exist_node)) do |corrector|
|
107
|
-
autocorrect(corrector, node, range) unless
|
107
|
+
autocorrect(corrector, node, range) unless parent.elsif?
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -120,7 +120,12 @@ module RuboCop
|
|
120
120
|
def autocorrect(corrector, node, range)
|
121
121
|
corrector.remove(range)
|
122
122
|
autocorrect_replace_method(corrector, node)
|
123
|
-
|
123
|
+
|
124
|
+
if node.parent.modifier_form?
|
125
|
+
corrector.remove(node.source_range.end.join(node.parent.loc.keyword.begin))
|
126
|
+
else
|
127
|
+
corrector.remove(node.parent.loc.end)
|
128
|
+
end
|
124
129
|
end
|
125
130
|
|
126
131
|
def autocorrect_replace_method(corrector, node)
|
@@ -68,6 +68,12 @@ module RuboCop
|
|
68
68
|
@valid_ref = regexp_conditions.map { |condition| check_regexp(condition) }.compact.max
|
69
69
|
end
|
70
70
|
|
71
|
+
def on_in_pattern(node)
|
72
|
+
regexp_patterns = patterns(node).select(&:regexp_type?)
|
73
|
+
|
74
|
+
@valid_ref = regexp_patterns.map { |pattern| check_regexp(pattern) }.compact.max
|
75
|
+
end
|
76
|
+
|
71
77
|
def on_nth_ref(node)
|
72
78
|
backref, = *node
|
73
79
|
return if @valid_ref.nil? || backref <= @valid_ref
|
@@ -84,6 +90,19 @@ module RuboCop
|
|
84
90
|
|
85
91
|
private
|
86
92
|
|
93
|
+
def patterns(pattern_node)
|
94
|
+
pattern = pattern_node.node_parts[0]
|
95
|
+
|
96
|
+
case pattern.type
|
97
|
+
when :array_pattern, :match_alt
|
98
|
+
pattern.children
|
99
|
+
when :match_as
|
100
|
+
patterns(pattern)
|
101
|
+
else
|
102
|
+
[pattern]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
87
106
|
def check_regexp(node)
|
88
107
|
return if node.interpolation?
|
89
108
|
|
@@ -128,6 +128,7 @@ module RuboCop
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
131
132
|
def each_already_disabled(cop, line_ranges)
|
132
133
|
line_ranges.each_cons(2) do |previous_range, range|
|
133
134
|
next if ignore_offense?(range)
|
@@ -152,9 +153,10 @@ module RuboCop
|
|
152
153
|
cop
|
153
154
|
end
|
154
155
|
|
155
|
-
yield comment, redundant
|
156
|
+
yield comment, redundant if redundant
|
156
157
|
end
|
157
158
|
end
|
159
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
158
160
|
|
159
161
|
def find_redundant_cop(cop, range)
|
160
162
|
cop_offenses = offenses_to_check.select { |offense| offense.cop_name == cop }
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
42
42
|
MSG = 'Unnecessary enabling of %<cop>s.'
|
43
43
|
|
44
44
|
def on_new_investigation
|
45
|
-
return if processed_source.blank?
|
45
|
+
return if processed_source.blank? || !processed_source.raw_source.include?('enable')
|
46
46
|
|
47
47
|
offenses = processed_source.comment_config.extra_enabled_comments
|
48
48
|
offenses.each { |comment, cop_names| register_offense(comment, cop_names) }
|