rubocop 1.40.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 +18 -0
- data/lib/rubocop/config.rb +28 -5
- data/lib/rubocop/config_loader.rb +9 -0
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/badge.rb +9 -4
- data/lib/rubocop/cop/base.rb +25 -9
- data/lib/rubocop/cop/commissioner.rb +8 -3
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.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 +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/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/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -19
- 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/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 +5 -1
- 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 +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 +6 -3
- 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 +5 -1
- 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/redundant_constant_base.rb +13 -0
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +39 -0
- data/lib/rubocop/cop/style/require_order.rb +61 -9
- data/lib/rubocop/cop/style/semicolon.rb +2 -1
- data/lib/rubocop/cop/util.rb +31 -4
- 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/options.rb +1 -1
- data/lib/rubocop/path_util.rb +20 -14
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +3 -1
- metadata +6 -4
- data/lib/rubocop/optimized_patterns.rb +0 -38
@@ -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
|
@@ -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
|
@@ -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..]
|
@@ -109,10 +109,14 @@ module RuboCop
|
|
109
109
|
def extract_heredocs(ast)
|
110
110
|
return [] unless ast
|
111
111
|
|
112
|
-
|
112
|
+
heredocs = []
|
113
|
+
ast.each_node(:str, :dstr, :xstr) do |node|
|
114
|
+
next unless node.heredoc?
|
115
|
+
|
113
116
|
body = node.location.heredoc_body
|
114
|
-
[node, body.first_line...body.last_line]
|
117
|
+
heredocs << [node, body.first_line...body.last_line]
|
115
118
|
end
|
119
|
+
heredocs
|
116
120
|
end
|
117
121
|
|
118
122
|
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)
|
@@ -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) }
|