rubocop 1.49.0 → 1.50.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 +6 -5
- data/lib/rubocop/config_loader.rb +8 -8
- data/lib/rubocop/cop/layout/class_structure.rb +1 -0
- data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
- data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +102 -0
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
- data/lib/rubocop/cop/metrics/class_length.rb +1 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -1
- data/lib/rubocop/cop/style/class_equality_comparison.rb +27 -7
- data/lib/rubocop/cop/style/copyright.rb +1 -1
- data/lib/rubocop/cop/style/file_empty.rb +3 -3
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +6 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +30 -5
- data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
- data/lib/rubocop/cops_documentation_generator.rb +10 -3
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b29d7b756beef5910c678a948e4c5e6a852978e39b6d4436eadaf9087731a742
|
|
4
|
+
data.tar.gz: 139e8da95a5f9f5d84c6286bfccad4f41aa93790c7387b5e9737f5e8a3b0dd6b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4c642f1f939b5fd5c91669422f4cc901bc889b1999d0f44ab6e576a4b9aa84c5a0f77540a8b9ad613dd42d71c560699b7218fa5f5d9320721bb8f2ccf9b97aee
|
|
7
|
+
data.tar.gz: 7980c7461a8e5d7d7cb1e19bdcba86696490b3c016adaca99011c100373e1db5944fb20642d270db11f68aa5604dc9b26fcd25733f4285e777f5ab8a504b025f
|
data/README.md
CHANGED
|
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
|
53
53
|
in your `Gemfile`:
|
|
54
54
|
|
|
55
55
|
```rb
|
|
56
|
-
gem 'rubocop', '~> 1.
|
|
56
|
+
gem 'rubocop', '~> 1.50', require: false
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
data/config/default.yml
CHANGED
|
@@ -1016,8 +1016,6 @@ Layout/LineContinuationLeadingSpace:
|
|
|
1016
1016
|
Layout/LineContinuationSpacing:
|
|
1017
1017
|
Description: 'Checks the spacing in front of backslash in line continuations.'
|
|
1018
1018
|
Enabled: pending
|
|
1019
|
-
AutoCorrect: true
|
|
1020
|
-
SafeAutoCorrect: true
|
|
1021
1019
|
VersionAdded: '1.31'
|
|
1022
1020
|
EnforcedStyle: space
|
|
1023
1021
|
SupportedStyles:
|
|
@@ -1752,6 +1750,11 @@ Lint/DuplicateMagicComment:
|
|
|
1752
1750
|
Enabled: pending
|
|
1753
1751
|
VersionAdded: '1.37'
|
|
1754
1752
|
|
|
1753
|
+
Lint/DuplicateMatchPattern:
|
|
1754
|
+
Description: 'Do not repeat patterns in `in` keywords.'
|
|
1755
|
+
Enabled: pending
|
|
1756
|
+
VersionAdded: '1.50'
|
|
1757
|
+
|
|
1755
1758
|
Lint/DuplicateMethods:
|
|
1756
1759
|
Description: 'Check for duplicate method definitions.'
|
|
1757
1760
|
Enabled: true
|
|
@@ -3743,7 +3746,6 @@ Style/FileEmpty:
|
|
|
3743
3746
|
Prefer to use `File.empty?('path/to/file')` when checking if a file is empty.
|
|
3744
3747
|
Enabled: pending
|
|
3745
3748
|
Safe: false
|
|
3746
|
-
SafeAutoCorrect: false
|
|
3747
3749
|
VersionAdded: '1.48'
|
|
3748
3750
|
|
|
3749
3751
|
Style/FileRead:
|
|
@@ -4571,11 +4573,10 @@ Style/NumericPredicate:
|
|
|
4571
4573
|
Checks for the use of predicate- or comparison methods for
|
|
4572
4574
|
numeric comparisons.
|
|
4573
4575
|
StyleGuide: '#predicate-methods'
|
|
4574
|
-
Safe: false
|
|
4575
4576
|
# This will change to a new method call which isn't guaranteed to be on the
|
|
4576
4577
|
# object. Switching these methods has to be done with knowledge of the types
|
|
4577
4578
|
# of the variables which rubocop doesn't have.
|
|
4578
|
-
|
|
4579
|
+
Safe: false
|
|
4579
4580
|
Enabled: true
|
|
4580
4581
|
VersionAdded: '0.42'
|
|
4581
4582
|
VersionChanged: '0.59'
|
|
@@ -23,6 +23,14 @@ module RuboCop
|
|
|
23
23
|
class << self
|
|
24
24
|
include FileFinder
|
|
25
25
|
|
|
26
|
+
PENDING_BANNER = <<~BANNER
|
|
27
|
+
The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.
|
|
28
|
+
|
|
29
|
+
Please also note that you can opt-in to new cops by default by adding this to your config:
|
|
30
|
+
AllCops:
|
|
31
|
+
NewCops: enable
|
|
32
|
+
BANNER
|
|
33
|
+
|
|
26
34
|
attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops,
|
|
27
35
|
:ignore_unrecognized_cops
|
|
28
36
|
attr_writer :default_configuration
|
|
@@ -165,14 +173,6 @@ module RuboCop
|
|
|
165
173
|
ConfigFinder.project_root
|
|
166
174
|
end
|
|
167
175
|
|
|
168
|
-
PENDING_BANNER = <<~BANNER
|
|
169
|
-
The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.
|
|
170
|
-
|
|
171
|
-
Please also note that you can opt-in to new cops by default by adding this to your config:
|
|
172
|
-
AllCops:
|
|
173
|
-
NewCops: enable
|
|
174
|
-
BANNER
|
|
175
|
-
|
|
176
176
|
def warn_on_pending_cops(pending_cops)
|
|
177
177
|
warn Rainbow(PENDING_BANNER).yellow
|
|
178
178
|
|
|
@@ -137,7 +137,7 @@ module RuboCop
|
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
def current_token(comment)
|
|
140
|
-
processed_source.
|
|
140
|
+
processed_source.tokens.find { |token| token.pos == comment.source_range }
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
def previous_token(node)
|
|
@@ -31,7 +31,7 @@ module RuboCop
|
|
|
31
31
|
return unless processed_source.raw_source.include?("\n\n\n")
|
|
32
32
|
|
|
33
33
|
lines = Set.new
|
|
34
|
-
processed_source.
|
|
34
|
+
processed_source.tokens.each { |token| lines << token.line }
|
|
35
35
|
|
|
36
36
|
each_extra_empty_line(lines.sort) do |range|
|
|
37
37
|
add_offense(range) do |corrector|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks that there are no repeated patterns used in `in` keywords.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
#
|
|
10
|
+
# # bad
|
|
11
|
+
# case x
|
|
12
|
+
# in 'first'
|
|
13
|
+
# do_something
|
|
14
|
+
# in 'first'
|
|
15
|
+
# do_something_else
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# # good
|
|
19
|
+
# case x
|
|
20
|
+
# in 'first'
|
|
21
|
+
# do_something
|
|
22
|
+
# in 'second'
|
|
23
|
+
# do_something_else
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# # bad - repeated alternate patterns with the same conditions don't depend on the order
|
|
27
|
+
# case x
|
|
28
|
+
# in foo | bar
|
|
29
|
+
# first_method
|
|
30
|
+
# in bar | foo
|
|
31
|
+
# second_method
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# # good
|
|
35
|
+
# case x
|
|
36
|
+
# in foo | bar
|
|
37
|
+
# first_method
|
|
38
|
+
# in bar | baz
|
|
39
|
+
# second_method
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# # bad - repeated hash patterns with the same conditions don't depend on the order
|
|
43
|
+
# case x
|
|
44
|
+
# in foo: a, bar: b
|
|
45
|
+
# first_method
|
|
46
|
+
# in bar: b, foo: a
|
|
47
|
+
# second_method
|
|
48
|
+
# end
|
|
49
|
+
#
|
|
50
|
+
# # good
|
|
51
|
+
# case x
|
|
52
|
+
# in foo: a, bar: b
|
|
53
|
+
# first_method
|
|
54
|
+
# in bar: b, baz: c
|
|
55
|
+
# second_method
|
|
56
|
+
# end
|
|
57
|
+
#
|
|
58
|
+
# # bad - repeated array patterns with elements in the same order
|
|
59
|
+
# case x
|
|
60
|
+
# in [foo, bar]
|
|
61
|
+
# first_method
|
|
62
|
+
# in [foo, bar]
|
|
63
|
+
# second_method
|
|
64
|
+
# end
|
|
65
|
+
#
|
|
66
|
+
# # good
|
|
67
|
+
# case x
|
|
68
|
+
# in [foo, bar]
|
|
69
|
+
# first_method
|
|
70
|
+
# in [bar, foo]
|
|
71
|
+
# second_method
|
|
72
|
+
# end
|
|
73
|
+
#
|
|
74
|
+
class DuplicateMatchPattern < Base
|
|
75
|
+
extend TargetRubyVersion
|
|
76
|
+
|
|
77
|
+
MSG = 'Duplicate `in` pattern detected.'
|
|
78
|
+
|
|
79
|
+
minimum_target_ruby_version 2.7
|
|
80
|
+
|
|
81
|
+
def on_case_match(case_node)
|
|
82
|
+
case_node.in_pattern_branches.each_with_object(Set.new) do |in_pattern_node, previous|
|
|
83
|
+
pattern = in_pattern_node.pattern
|
|
84
|
+
next if previous.add?(pattern_identity(pattern))
|
|
85
|
+
|
|
86
|
+
add_offense(pattern)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
def pattern_identity(pattern)
|
|
93
|
+
if pattern.hash_pattern_type? || pattern.match_alt_type?
|
|
94
|
+
pattern.children.map(&:source).sort
|
|
95
|
+
else
|
|
96
|
+
pattern.source
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
# Checks for string conversion in string interpolation,
|
|
6
|
+
# Checks for string conversion in string interpolation, `print`, `puts`, and `warn` arguments,
|
|
7
7
|
# which is redundant.
|
|
8
8
|
#
|
|
9
9
|
# @example
|
|
@@ -11,18 +11,26 @@ module RuboCop
|
|
|
11
11
|
# # bad
|
|
12
12
|
#
|
|
13
13
|
# "result is #{something.to_s}"
|
|
14
|
+
# print something.to_s
|
|
15
|
+
# puts something.to_s
|
|
16
|
+
# warn something.to_s
|
|
14
17
|
#
|
|
15
18
|
# @example
|
|
16
19
|
#
|
|
17
20
|
# # good
|
|
18
21
|
#
|
|
19
22
|
# "result is #{something}"
|
|
23
|
+
# print something
|
|
24
|
+
# puts something
|
|
25
|
+
# warn something
|
|
26
|
+
#
|
|
20
27
|
class RedundantStringCoercion < Base
|
|
21
28
|
include Interpolation
|
|
22
29
|
extend AutoCorrector
|
|
23
30
|
|
|
24
|
-
MSG_DEFAULT = 'Redundant use of `Object#to_s` in
|
|
25
|
-
MSG_SELF = 'Use `self` instead of `Object#to_s` in
|
|
31
|
+
MSG_DEFAULT = 'Redundant use of `Object#to_s` in %<context>s.'
|
|
32
|
+
MSG_SELF = 'Use `self` instead of `Object#to_s` in %<context>s.'
|
|
33
|
+
RESTRICT_ON_SEND = %i[print puts warn].freeze
|
|
26
34
|
|
|
27
35
|
# @!method to_s_without_args?(node)
|
|
28
36
|
def_node_matcher :to_s_without_args?, '(send _ :to_s)'
|
|
@@ -32,18 +40,30 @@ module RuboCop
|
|
|
32
40
|
|
|
33
41
|
return unless to_s_without_args?(final_node)
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
register_offense(final_node, 'interpolation')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def on_send(node)
|
|
47
|
+
return if node.receiver
|
|
48
|
+
|
|
49
|
+
node.each_child_node(:send) do |child|
|
|
50
|
+
next unless child.method?(:to_s)
|
|
51
|
+
|
|
52
|
+
register_offense(child, "`#{node.method_name}`")
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def register_offense(node, context)
|
|
59
|
+
receiver = node.receiver
|
|
60
|
+
template = receiver ? MSG_DEFAULT : MSG_SELF
|
|
61
|
+
message = format(template, context: context)
|
|
62
|
+
|
|
63
|
+
add_offense(node.loc.selector, message: message) do |corrector|
|
|
64
|
+
replacement = receiver ? receiver.source : 'self'
|
|
65
|
+
|
|
66
|
+
corrector.replace(node, replacement)
|
|
47
67
|
end
|
|
48
68
|
end
|
|
49
69
|
end
|
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
|
10
10
|
include Util
|
|
11
11
|
|
|
12
12
|
FOLDABLE_TYPES = %i[array hash heredoc send csend].freeze
|
|
13
|
-
CLASSLIKE_TYPES = %i[class module].freeze
|
|
13
|
+
CLASSLIKE_TYPES = %i[class module sclass].freeze
|
|
14
14
|
private_constant :FOLDABLE_TYPES, :CLASSLIKE_TYPES
|
|
15
15
|
|
|
16
16
|
def initialize(node, processed_source, count_comments: false, foldable_types: [])
|
|
@@ -69,7 +69,7 @@ module RuboCop
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def first_line_comment(node)
|
|
72
|
-
comment = processed_source.
|
|
72
|
+
comment = processed_source.comments.find { |c| same_line?(c, node) }
|
|
73
73
|
return unless comment
|
|
74
74
|
|
|
75
75
|
comment_source = comment.source
|
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
|
57
57
|
CONSTANT_MSG = 'Use only ascii symbols in constants.'
|
|
58
58
|
|
|
59
59
|
def on_new_investigation
|
|
60
|
-
processed_source.
|
|
60
|
+
processed_source.tokens.each do |token|
|
|
61
61
|
next if !should_check?(token) || token.text.ascii_only?
|
|
62
62
|
|
|
63
63
|
message = token.type == :tIDENTIFIER ? IDENTIFIER_MSG : CONSTANT_MSG
|
|
@@ -72,7 +72,7 @@ module RuboCop
|
|
|
72
72
|
include AllowedPattern
|
|
73
73
|
extend AutoCorrector
|
|
74
74
|
|
|
75
|
-
MSG = 'Use `instance_of
|
|
75
|
+
MSG = 'Use `instance_of?%<class_argument>s` instead of comparing classes.'
|
|
76
76
|
|
|
77
77
|
RESTRICT_ON_SEND = %i[== equal? eql?].freeze
|
|
78
78
|
CLASS_NAME_METHODS = %i[name to_s inspect].freeze
|
|
@@ -92,10 +92,12 @@ module RuboCop
|
|
|
92
92
|
|
|
93
93
|
class_comparison_candidate?(node) do |receiver_node, class_node|
|
|
94
94
|
range = offense_range(receiver_node, node)
|
|
95
|
-
class_name = class_name(class_node, node)
|
|
95
|
+
class_argument = (class_name = class_name(class_node, node)) ? "(#{class_name})" : ''
|
|
96
96
|
|
|
97
|
-
add_offense(range, message: format(MSG,
|
|
98
|
-
|
|
97
|
+
add_offense(range, message: format(MSG, class_argument: class_argument)) do |corrector|
|
|
98
|
+
next unless class_name
|
|
99
|
+
|
|
100
|
+
corrector.replace(range, "instance_of?#{class_argument}")
|
|
99
101
|
end
|
|
100
102
|
end
|
|
101
103
|
end
|
|
@@ -104,12 +106,18 @@ module RuboCop
|
|
|
104
106
|
|
|
105
107
|
def class_name(class_node, node)
|
|
106
108
|
if class_name_method?(node.children.first.method_name)
|
|
107
|
-
|
|
109
|
+
if (receiver = class_node.receiver) && class_name_method?(class_node.method_name)
|
|
110
|
+
return receiver.source
|
|
111
|
+
end
|
|
108
112
|
|
|
109
113
|
if class_node.str_type?
|
|
110
|
-
value = class_node
|
|
111
|
-
value.prepend('::') if class_node
|
|
114
|
+
value = trim_string_quotes(class_node)
|
|
115
|
+
value.prepend('::') if require_cbase?(class_node)
|
|
112
116
|
return value
|
|
117
|
+
elsif unable_to_determine_type?(class_node)
|
|
118
|
+
# When a variable or return value of a method is used, it returns nil
|
|
119
|
+
# because the type is not known and cannot be suggested.
|
|
120
|
+
return
|
|
113
121
|
end
|
|
114
122
|
end
|
|
115
123
|
|
|
@@ -120,6 +128,18 @@ module RuboCop
|
|
|
120
128
|
CLASS_NAME_METHODS.include?(method_name)
|
|
121
129
|
end
|
|
122
130
|
|
|
131
|
+
def require_cbase?(class_node)
|
|
132
|
+
class_node.each_ancestor(:class, :module).any?
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def unable_to_determine_type?(class_node)
|
|
136
|
+
class_node.variable? || class_node.call_type?
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def trim_string_quotes(class_node)
|
|
140
|
+
class_node.source.delete('"').delete("'")
|
|
141
|
+
end
|
|
142
|
+
|
|
123
143
|
def offense_range(receiver_node, node)
|
|
124
144
|
range_between(receiver_node.loc.selector.begin_pos, node.source_range.end_pos)
|
|
125
145
|
end
|
|
@@ -82,7 +82,7 @@ module RuboCop
|
|
|
82
82
|
def notice_found?(processed_source)
|
|
83
83
|
notice_found = false
|
|
84
84
|
notice_regexp = Regexp.new(notice)
|
|
85
|
-
processed_source.
|
|
85
|
+
processed_source.tokens.each do |token|
|
|
86
86
|
break unless token.comment?
|
|
87
87
|
|
|
88
88
|
notice_found = notice_regexp.match?(token.text)
|
|
@@ -6,9 +6,9 @@ module RuboCop
|
|
|
6
6
|
# Prefer to use `File.empty?('path/to/file')` when checking if a file is empty.
|
|
7
7
|
#
|
|
8
8
|
# @safety
|
|
9
|
-
# This cop
|
|
10
|
-
#
|
|
11
|
-
#
|
|
9
|
+
# This cop is unsafe, because `File.size`, `File.read`, and `File.binread`
|
|
10
|
+
# raise `ENOENT` exception when there is no file corresponding to the path,
|
|
11
|
+
# while `File.empty?` does not raise an exception.
|
|
12
12
|
#
|
|
13
13
|
# @example
|
|
14
14
|
# # bad
|
|
@@ -28,14 +28,17 @@ module RuboCop
|
|
|
28
28
|
return unless node.arguments?
|
|
29
29
|
return if opening_line(node) == closing_line(node)
|
|
30
30
|
return if correction_exceeds_max_line_length?(node)
|
|
31
|
+
return unless (begin_of_arguments = node.arguments.loc.begin)
|
|
31
32
|
|
|
32
|
-
add_offense(node)
|
|
33
|
+
add_offense(node) do |corrector|
|
|
34
|
+
autocorrect(corrector, node, begin_of_arguments)
|
|
35
|
+
end
|
|
33
36
|
end
|
|
34
37
|
alias on_defs on_def
|
|
35
38
|
|
|
36
39
|
private
|
|
37
40
|
|
|
38
|
-
def autocorrect(corrector, node)
|
|
41
|
+
def autocorrect(corrector, node, begin_of_arguments)
|
|
39
42
|
arguments = node.arguments
|
|
40
43
|
joined_arguments = arguments.map(&:source).join(', ')
|
|
41
44
|
last_line_source_of_arguments = last_line_source_of_arguments(arguments)
|
|
@@ -47,7 +50,7 @@ module RuboCop
|
|
|
47
50
|
end
|
|
48
51
|
|
|
49
52
|
corrector.remove(arguments_range(node))
|
|
50
|
-
corrector.insert_after(
|
|
53
|
+
corrector.insert_after(begin_of_arguments, joined_arguments)
|
|
51
54
|
end
|
|
52
55
|
|
|
53
56
|
def last_line_source_of_arguments(arguments)
|
|
@@ -69,6 +69,7 @@ module RuboCop
|
|
|
69
69
|
extend AutoCorrector
|
|
70
70
|
|
|
71
71
|
MSG = 'Redundant line continuation.'
|
|
72
|
+
ALLOWED_STRING_TOKENS = %i[tSTRING tSTRING_CONTENT].freeze
|
|
72
73
|
|
|
73
74
|
def on_new_investigation
|
|
74
75
|
return unless processed_source.ast
|
|
@@ -88,7 +89,8 @@ module RuboCop
|
|
|
88
89
|
def require_line_continuation?(range)
|
|
89
90
|
!ends_with_backslash_without_comment?(range.source_line) ||
|
|
90
91
|
string_concatenation?(range.source_line) ||
|
|
91
|
-
|
|
92
|
+
start_with_arithmetic_operator?(processed_source[range.line]) ||
|
|
93
|
+
inside_string_literal?(range)
|
|
92
94
|
end
|
|
93
95
|
|
|
94
96
|
def ends_with_backslash_without_comment?(source_line)
|
|
@@ -99,18 +101,30 @@ module RuboCop
|
|
|
99
101
|
/["']\s*\\\z/.match?(source_line)
|
|
100
102
|
end
|
|
101
103
|
|
|
104
|
+
def inside_string_literal?(range)
|
|
105
|
+
processed_source.tokens.each.any? do |token|
|
|
106
|
+
ALLOWED_STRING_TOKENS.include?(token.type) && token.pos.overlaps?(range)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
102
110
|
def redundant_line_continuation?(range)
|
|
103
111
|
return true unless (node = find_node_for_line(range.line))
|
|
104
112
|
return false if argument_newline?(node)
|
|
105
113
|
|
|
106
|
-
|
|
114
|
+
source = node.parent ? node.parent.source : node.source
|
|
115
|
+
parse(source.gsub(/\\\n/, "\n")).valid_syntax?
|
|
107
116
|
end
|
|
108
117
|
|
|
109
118
|
def argument_newline?(node)
|
|
110
119
|
node = node.children.first if node.root? && node.begin_type?
|
|
111
|
-
return if !node.send_type? || node.arguments.empty?
|
|
112
120
|
|
|
113
|
-
|
|
121
|
+
if argument_is_method?(node)
|
|
122
|
+
argument_newline?(node.first_argument)
|
|
123
|
+
else
|
|
124
|
+
return false unless method_call_with_arguments?(node)
|
|
125
|
+
|
|
126
|
+
node.loc.selector.line != node.first_argument.loc.line
|
|
127
|
+
end
|
|
114
128
|
end
|
|
115
129
|
|
|
116
130
|
def find_node_for_line(line)
|
|
@@ -133,7 +147,18 @@ module RuboCop
|
|
|
133
147
|
end
|
|
134
148
|
end
|
|
135
149
|
|
|
136
|
-
def
|
|
150
|
+
def argument_is_method?(node)
|
|
151
|
+
return false unless node.send_type?
|
|
152
|
+
return false unless (first_argument = node.first_argument)
|
|
153
|
+
|
|
154
|
+
method_call_with_arguments?(first_argument)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def method_call_with_arguments?(node)
|
|
158
|
+
node.call_type? && !node.arguments.empty?
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def start_with_arithmetic_operator?(source_line)
|
|
137
162
|
%r{\A\s*[+\-*/%]}.match?(source_line)
|
|
138
163
|
end
|
|
139
164
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
3
5
|
# Class for generating documentation of all cops departments
|
|
4
6
|
# @api private
|
|
5
7
|
class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
@@ -14,6 +16,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
|
14
16
|
@departments = departments.map(&:to_sym).sort!
|
|
15
17
|
@cops = RuboCop::Cop::Registry.global
|
|
16
18
|
@config = RuboCop::ConfigLoader.default_configuration
|
|
19
|
+
@docs_path = "#{Dir.pwd}/docs/modules/ROOT/pages/"
|
|
20
|
+
FileUtils.mkdir_p(@docs_path)
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
def call
|
|
@@ -27,7 +31,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
|
27
31
|
|
|
28
32
|
private
|
|
29
33
|
|
|
30
|
-
attr_reader :departments, :cops, :config
|
|
34
|
+
attr_reader :departments, :cops, :config, :docs_path
|
|
31
35
|
|
|
32
36
|
def cops_of_department(department)
|
|
33
37
|
cops.with_department(department).sort!
|
|
@@ -252,7 +256,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
|
252
256
|
content = +"= #{department}\n"
|
|
253
257
|
selected_cops.each { |cop| content << print_cop_with_doc(cop) }
|
|
254
258
|
content << footer_for_department(department)
|
|
255
|
-
file_name = "#{
|
|
259
|
+
file_name = "#{docs_path}/#{department_to_basename(department)}.adoc"
|
|
256
260
|
File.open(file_name, 'w') do |file|
|
|
257
261
|
puts "* generated #{file_name}"
|
|
258
262
|
file.write("#{content.strip}\n")
|
|
@@ -298,7 +302,10 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
|
298
302
|
end
|
|
299
303
|
|
|
300
304
|
def print_table_of_contents
|
|
301
|
-
path = "#{
|
|
305
|
+
path = "#{docs_path}/cops.adoc"
|
|
306
|
+
|
|
307
|
+
File.write(path, table_contents) and return unless File.exist?(path)
|
|
308
|
+
|
|
302
309
|
original = File.read(path)
|
|
303
310
|
content = +"// START_COP_LIST\n\n"
|
|
304
311
|
|
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
|
@@ -299,6 +299,7 @@ require_relative 'rubocop/cop/lint/duplicate_case_condition'
|
|
|
299
299
|
require_relative 'rubocop/cop/lint/duplicate_elsif_condition'
|
|
300
300
|
require_relative 'rubocop/cop/lint/duplicate_hash_key'
|
|
301
301
|
require_relative 'rubocop/cop/lint/duplicate_magic_comment'
|
|
302
|
+
require_relative 'rubocop/cop/lint/duplicate_match_pattern'
|
|
302
303
|
require_relative 'rubocop/cop/lint/duplicate_methods'
|
|
303
304
|
require_relative 'rubocop/cop/lint/duplicate_regexp_character_class_element'
|
|
304
305
|
require_relative 'rubocop/cop/lint/duplicate_require'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.50.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bozhidar Batsov
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: exe
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2023-04-
|
|
13
|
+
date: 2023-04-11 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: json
|
|
@@ -420,6 +420,7 @@ files:
|
|
|
420
420
|
- lib/rubocop/cop/lint/duplicate_elsif_condition.rb
|
|
421
421
|
- lib/rubocop/cop/lint/duplicate_hash_key.rb
|
|
422
422
|
- lib/rubocop/cop/lint/duplicate_magic_comment.rb
|
|
423
|
+
- lib/rubocop/cop/lint/duplicate_match_pattern.rb
|
|
423
424
|
- lib/rubocop/cop/lint/duplicate_methods.rb
|
|
424
425
|
- lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb
|
|
425
426
|
- lib/rubocop/cop/lint/duplicate_require.rb
|
|
@@ -990,7 +991,7 @@ metadata:
|
|
|
990
991
|
homepage_uri: https://rubocop.org/
|
|
991
992
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
|
992
993
|
source_code_uri: https://github.com/rubocop/rubocop/
|
|
993
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
|
994
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.50/
|
|
994
995
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
|
995
996
|
rubygems_mfa_required: 'true'
|
|
996
997
|
post_install_message:
|