rubocop 1.37.1 → 1.39.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +10 -2
- data/lib/rubocop/comment_config.rb +36 -1
- data/lib/rubocop/cop/commissioner.rb +3 -1
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +29 -8
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +3 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +34 -0
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +6 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +17 -8
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -3
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +11 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +10 -2
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +23 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +4 -3
- data/lib/rubocop/cop/mixin/visibility_help.rb +40 -5
- data/lib/rubocop/cop/registry.rb +10 -4
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -25
- data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/class_equality_comparison.rb +7 -5
- data/lib/rubocop/cop/style/collection_compact.rb +4 -2
- data/lib/rubocop/cop/style/guard_clause.rb +62 -21
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +1 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +32 -10
- data/lib/rubocop/cop/style/hash_except.rb +4 -0
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +25 -2
- data/lib/rubocop/cop/style/module_function.rb +28 -6
- data/lib/rubocop/cop/style/object_then.rb +3 -0
- data/lib/rubocop/cop/style/operator_method_call.rb +13 -0
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/redundant_each.rb +116 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -3
- data/lib/rubocop/cop/team.rb +3 -4
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable_table.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +2 -1
- data/lib/rubocop/ext/processed_source.rb +2 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +8 -5
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +6 -3
- data/lib/rubocop/options.rb +6 -2
- data/lib/rubocop/rspec/cop_helper.rb +21 -1
- data/lib/rubocop/rspec/shared_contexts.rb +13 -12
- data/lib/rubocop/runner.rb +15 -11
- data/lib/rubocop/server/core.rb +16 -0
- 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: 881807be0f0f6eea20bd13bd8f08fdb158a5b155c8d3a22fd748683a68c1fef1
|
4
|
+
data.tar.gz: 2a8e7d4b02f1ba468e02a4c20f8e3b830ce2a1d8ff0210f86aaeafab597c8c88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11ea36bec754b07912e06b5481f964d10a6dbf5bfd56f99d8a8842ca46d56ae03a342a283d843336f977760c28a697ee995aa98268254a55b1218fa57a9fb5c7
|
7
|
+
data.tar.gz: b5096cb4589d9bafdab0b6ab409ea9e7841dc06b274aeb7f7d5a26e703cb216c2a428d695fb2a087637467f1cdd5ac005398c66ee3e7d28d49cb4b203a87667d
|
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.39', 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
@@ -2808,6 +2808,7 @@ Naming/MethodParameterName:
|
|
2808
2808
|
- by
|
2809
2809
|
- db
|
2810
2810
|
- id
|
2811
|
+
- if
|
2811
2812
|
- in
|
2812
2813
|
- io
|
2813
2814
|
- ip
|
@@ -3448,7 +3449,7 @@ Style/Copyright:
|
|
3448
3449
|
|
3449
3450
|
Style/DateTime:
|
3450
3451
|
Description: 'Use Time over DateTime.'
|
3451
|
-
StyleGuide: '#date
|
3452
|
+
StyleGuide: '#date-time'
|
3452
3453
|
Enabled: false
|
3453
3454
|
VersionAdded: '0.51'
|
3454
3455
|
VersionChanged: '0.92'
|
@@ -3819,8 +3820,9 @@ Style/HashExcept:
|
|
3819
3820
|
Checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods
|
3820
3821
|
that can be replaced with `Hash#except` method.
|
3821
3822
|
Enabled: pending
|
3823
|
+
Safe: false
|
3822
3824
|
VersionAdded: '1.7'
|
3823
|
-
VersionChanged: '1.
|
3825
|
+
VersionChanged: '1.39'
|
3824
3826
|
|
3825
3827
|
Style/HashLikeCase:
|
3826
3828
|
Description: >-
|
@@ -4696,6 +4698,12 @@ Style/RedundantConditional:
|
|
4696
4698
|
Enabled: true
|
4697
4699
|
VersionAdded: '0.50'
|
4698
4700
|
|
4701
|
+
Style/RedundantEach:
|
4702
|
+
Description: 'Checks for redundant `each`.'
|
4703
|
+
Enabled: pending
|
4704
|
+
Safe: false
|
4705
|
+
VersionAdded: '1.38'
|
4706
|
+
|
4699
4707
|
Style/RedundantException:
|
4700
4708
|
Description: "Checks for an obsolete RuntimeException argument in raise/fail."
|
4701
4709
|
StyleGuide: '#no-explicit-runtimeerror'
|
@@ -4,10 +4,31 @@ module RuboCop
|
|
4
4
|
# This class parses the special `rubocop:disable` comments in a source
|
5
5
|
# and provides a way to check if each cop is enabled at arbitrary line.
|
6
6
|
class CommentConfig
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
CONFIG_DISABLED_LINE_RANGE_MIN = -Float::INFINITY
|
10
|
+
|
11
|
+
# This class provides an API compatible with RuboCop::DirectiveComment
|
12
|
+
# to be used for cops that are disabled in the config file
|
13
|
+
class ConfigDisabledCopDirectiveComment
|
14
|
+
attr_reader :text, :loc, :line_number
|
15
|
+
|
16
|
+
Loc = Struct.new(:expression)
|
17
|
+
Expression = Struct.new(:line)
|
18
|
+
|
19
|
+
def initialize(cop_name)
|
20
|
+
@text = "# rubocop:disable #{cop_name}"
|
21
|
+
@line_number = CONFIG_DISABLED_LINE_RANGE_MIN
|
22
|
+
@loc = Loc.new(Expression.new(CONFIG_DISABLED_LINE_RANGE_MIN))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
7
26
|
CopAnalysis = Struct.new(:line_ranges, :start_line_number)
|
8
27
|
|
9
28
|
attr_reader :processed_source
|
10
29
|
|
30
|
+
def_delegators :@processed_source, :config, :registry
|
31
|
+
|
11
32
|
def initialize(processed_source)
|
12
33
|
@processed_source = processed_source
|
13
34
|
end
|
@@ -25,7 +46,11 @@ module RuboCop
|
|
25
46
|
end
|
26
47
|
|
27
48
|
def extra_enabled_comments
|
28
|
-
|
49
|
+
disable_count = Hash.new(0)
|
50
|
+
registry.disabled(config).each do |cop|
|
51
|
+
disable_count[cop.cop_name] += 1
|
52
|
+
end
|
53
|
+
extra_enabled_comments_with_names(extras: Hash.new { |h, k| h[k] = [] }, names: disable_count)
|
29
54
|
end
|
30
55
|
|
31
56
|
def comment_only_line?(line_number)
|
@@ -50,6 +75,7 @@ module RuboCop
|
|
50
75
|
|
51
76
|
def analyze # rubocop:todo Metrics/AbcSize
|
52
77
|
analyses = Hash.new { |hash, key| hash[key] = CopAnalysis.new([], nil) }
|
78
|
+
inject_disabled_cops_directives(analyses)
|
53
79
|
|
54
80
|
each_directive do |directive|
|
55
81
|
directive.cop_names.each do |cop_name|
|
@@ -64,6 +90,15 @@ module RuboCop
|
|
64
90
|
end
|
65
91
|
end
|
66
92
|
|
93
|
+
def inject_disabled_cops_directives(analyses)
|
94
|
+
registry.disabled(config).each do |cop|
|
95
|
+
analyses[cop.cop_name] = analyze_cop(
|
96
|
+
analyses[cop.cop_name],
|
97
|
+
DirectiveComment.new(ConfigDisabledCopDirectiveComment.new(cop.cop_name))
|
98
|
+
)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
67
102
|
def analyze_cop(analysis, directive)
|
68
103
|
# Disabling cops after comments like `#=SomeDslDirective` does not related to single line
|
69
104
|
if !comment_only_line?(directive.line_number) || directive.single_line?
|
@@ -159,9 +159,11 @@ module RuboCop
|
|
159
159
|
def with_cop_error_handling(cop, node = nil)
|
160
160
|
yield
|
161
161
|
rescue StandardError => e
|
162
|
-
raise e if @options[:raise_error]
|
162
|
+
raise e if @options[:raise_error] # For internal testing
|
163
163
|
|
164
164
|
err = ErrorWithAnalyzedFileLocation.new(cause: e, node: node, cop: cop)
|
165
|
+
raise err if @options[:raise_cop_error] # From user-input option
|
166
|
+
|
165
167
|
@errors << err
|
166
168
|
end
|
167
169
|
end
|
@@ -90,7 +90,7 @@ module RuboCop
|
|
90
90
|
# which lines start inside a string literal?
|
91
91
|
return [] if ast.nil?
|
92
92
|
|
93
|
-
ast.each_node(:str, :dstr).
|
93
|
+
ast.each_node(:str, :dstr).with_object(Set.new) do |str, ranges|
|
94
94
|
loc = str.location
|
95
95
|
|
96
96
|
if str.heredoc?
|
@@ -42,6 +42,14 @@ module RuboCop
|
|
42
42
|
# ' long'
|
43
43
|
class LineContinuationLeadingSpace < Base
|
44
44
|
include RangeHelp
|
45
|
+
extend AutoCorrector
|
46
|
+
|
47
|
+
LINE_1_ENDING = /['"]\s*\\\n/.freeze
|
48
|
+
LINE_2_BEGINNING = /\A\s*['"]/.freeze
|
49
|
+
LEADING_STYLE_OFFENSE = /(?<trailing_spaces>\s+)(?<ending>#{LINE_1_ENDING})/.freeze
|
50
|
+
TRAILING_STYLE_OFFENSE = /(?<beginning>#{LINE_2_BEGINNING})(?<leading_spaces>\s+)/.freeze
|
51
|
+
private_constant :LINE_1_ENDING, :LINE_2_BEGINNING,
|
52
|
+
:LEADING_STYLE_OFFENSE, :TRAILING_STYLE_OFFENSE
|
45
53
|
|
46
54
|
def on_dstr(node)
|
47
55
|
end_of_first_line = node.loc.expression.begin_pos - node.loc.expression.column
|
@@ -52,9 +60,9 @@ module RuboCop
|
|
52
60
|
next unless continuation?(raw_line_one)
|
53
61
|
|
54
62
|
if enforced_style_leading?
|
55
|
-
investigate_leading_style(raw_line_one, end_of_first_line)
|
63
|
+
investigate_leading_style(raw_line_one, raw_line_two, end_of_first_line)
|
56
64
|
else
|
57
|
-
investigate_trailing_style(raw_line_two, end_of_first_line)
|
65
|
+
investigate_trailing_style(raw_line_one, raw_line_two, end_of_first_line)
|
58
66
|
end
|
59
67
|
end
|
60
68
|
end
|
@@ -65,24 +73,37 @@ module RuboCop
|
|
65
73
|
processed_source.raw_source.lines[node.first_line - 1, line_range(node).size]
|
66
74
|
end
|
67
75
|
|
68
|
-
def investigate_leading_style(first_line, end_of_first_line)
|
69
|
-
matches = first_line.match(
|
76
|
+
def investigate_leading_style(first_line, second_line, end_of_first_line)
|
77
|
+
matches = first_line.match(LEADING_STYLE_OFFENSE)
|
70
78
|
return if matches.nil?
|
71
79
|
|
72
|
-
|
80
|
+
offense_range = leading_offense_range(end_of_first_line, matches)
|
81
|
+
add_offense(offense_range) do |corrector|
|
82
|
+
insert_pos = end_of_first_line + second_line[LINE_2_BEGINNING].length
|
83
|
+
autocorrect(corrector, offense_range, insert_pos, matches[:trailing_spaces])
|
84
|
+
end
|
73
85
|
end
|
74
86
|
|
75
|
-
def investigate_trailing_style(second_line, end_of_first_line)
|
76
|
-
matches = second_line.match(
|
87
|
+
def investigate_trailing_style(first_line, second_line, end_of_first_line)
|
88
|
+
matches = second_line.match(TRAILING_STYLE_OFFENSE)
|
77
89
|
return if matches.nil?
|
78
90
|
|
79
|
-
|
91
|
+
offense_range = trailing_offense_range(end_of_first_line, matches)
|
92
|
+
add_offense(offense_range) do |corrector|
|
93
|
+
insert_pos = end_of_first_line - first_line[LINE_1_ENDING].length
|
94
|
+
autocorrect(corrector, offense_range, insert_pos, matches[:leading_spaces])
|
95
|
+
end
|
80
96
|
end
|
81
97
|
|
82
98
|
def continuation?(line)
|
83
99
|
line.end_with?("\\\n")
|
84
100
|
end
|
85
101
|
|
102
|
+
def autocorrect(corrector, offense_range, insert_pos, spaces)
|
103
|
+
corrector.remove(offense_range)
|
104
|
+
corrector.replace(range_between(insert_pos, insert_pos), spaces)
|
105
|
+
end
|
106
|
+
|
86
107
|
def leading_offense_range(end_of_first_line, matches)
|
87
108
|
end_pos = end_of_first_line - matches[:ending].length
|
88
109
|
begin_pos = end_pos - matches[:trailing_spaces].length
|
@@ -92,7 +92,7 @@ module RuboCop
|
|
92
92
|
# which lines start inside a string literal?
|
93
93
|
return [] if ast.nil?
|
94
94
|
|
95
|
-
ast.each_node(:str, :dstr).
|
95
|
+
ast.each_node(:str, :dstr).with_object(Set.new) do |str, ranges|
|
96
96
|
loc = str.location
|
97
97
|
|
98
98
|
if str.heredoc?
|
@@ -6,6 +6,9 @@ module RuboCop
|
|
6
6
|
# Checks for unnecessary additional spaces inside array percent literals
|
7
7
|
# (i.e. %i/%w).
|
8
8
|
#
|
9
|
+
# Note that blank percent literals (e.g. `%i( )`) are checked by
|
10
|
+
# `Layout/SpaceInsidePercentLiteralDelimiters`.
|
11
|
+
#
|
9
12
|
# @example
|
10
13
|
#
|
11
14
|
# # bad
|
@@ -8,14 +8,31 @@ module RuboCop
|
|
8
8
|
#
|
9
9
|
# @example
|
10
10
|
#
|
11
|
+
# # bad
|
12
|
+
# %i( foo bar baz )
|
13
|
+
#
|
11
14
|
# # good
|
12
15
|
# %i(foo bar baz)
|
13
16
|
#
|
14
17
|
# # bad
|
15
18
|
# %w( foo bar baz )
|
16
19
|
#
|
20
|
+
# # good
|
21
|
+
# %w(foo bar baz)
|
22
|
+
#
|
17
23
|
# # bad
|
18
24
|
# %x( ls -l )
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# %x(ls -l)
|
28
|
+
#
|
29
|
+
# # bad
|
30
|
+
# %w( )
|
31
|
+
# %w(
|
32
|
+
# )
|
33
|
+
#
|
34
|
+
# # good
|
35
|
+
# %w()
|
19
36
|
class SpaceInsidePercentLiteralDelimiters < Base
|
20
37
|
include MatchRange
|
21
38
|
include PercentLiteral
|
@@ -34,11 +51,21 @@ module RuboCop
|
|
34
51
|
end
|
35
52
|
|
36
53
|
def on_percent_literal(node)
|
54
|
+
add_offenses_for_blank_spaces(node)
|
37
55
|
add_offenses_for_unnecessary_spaces(node)
|
38
56
|
end
|
39
57
|
|
40
58
|
private
|
41
59
|
|
60
|
+
def add_offenses_for_blank_spaces(node)
|
61
|
+
range = body_range(node)
|
62
|
+
return if range.source.empty? || !range.source.strip.empty?
|
63
|
+
|
64
|
+
add_offense(range) do |corrector|
|
65
|
+
corrector.remove(range)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
42
69
|
def add_offenses_for_unnecessary_spaces(node)
|
43
70
|
return unless node.single_line?
|
44
71
|
|
@@ -54,6 +81,13 @@ module RuboCop
|
|
54
81
|
each_match_range(contents_range(node), regex, &blk)
|
55
82
|
end
|
56
83
|
end
|
84
|
+
|
85
|
+
def body_range(node)
|
86
|
+
node.location.expression.with(
|
87
|
+
begin_pos: node.location.begin.end_pos,
|
88
|
+
end_pos: node.location.end.begin_pos
|
89
|
+
)
|
90
|
+
end
|
57
91
|
end
|
58
92
|
end
|
59
93
|
end
|
@@ -38,6 +38,8 @@ module RuboCop
|
|
38
38
|
# # bad
|
39
39
|
# foo[ ]
|
40
40
|
# foo[ ]
|
41
|
+
# foo[
|
42
|
+
# ]
|
41
43
|
#
|
42
44
|
# # good
|
43
45
|
# foo[]
|
@@ -49,6 +51,8 @@ module RuboCop
|
|
49
51
|
# # bad
|
50
52
|
# foo[]
|
51
53
|
# foo[ ]
|
54
|
+
# foo[
|
55
|
+
# ]
|
52
56
|
#
|
53
57
|
# # good
|
54
58
|
# foo[ ]
|
@@ -64,8 +68,6 @@ module RuboCop
|
|
64
68
|
RESTRICT_ON_SEND = %i[[] []=].freeze
|
65
69
|
|
66
70
|
def on_send(node)
|
67
|
-
return if node.multiline?
|
68
|
-
|
69
71
|
tokens = processed_source.tokens_within(node)
|
70
72
|
left_token = left_ref_bracket(node, tokens)
|
71
73
|
return unless left_token
|
@@ -76,6 +78,8 @@ module RuboCop
|
|
76
78
|
return empty_offenses(node, left_token, right_token, EMPTY_MSG)
|
77
79
|
end
|
78
80
|
|
81
|
+
return if node.multiline?
|
82
|
+
|
79
83
|
if style == :no_space
|
80
84
|
no_space_offenses(node, left_token, right_token, MSG)
|
81
85
|
else
|
@@ -51,8 +51,8 @@ module RuboCop
|
|
51
51
|
# alias bar foo
|
52
52
|
class DuplicateMethods < Base
|
53
53
|
MSG = 'Method `%<method>s` is defined at both %<defined>s and %<current>s.'
|
54
|
-
|
55
54
|
RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr].freeze
|
55
|
+
DEF_TYPES = %i[def defs].freeze
|
56
56
|
|
57
57
|
def initialize(config = nil, options = nil)
|
58
58
|
super
|
@@ -127,8 +127,8 @@ module RuboCop
|
|
127
127
|
found_method(node, "#{enclosing}.#{name}")
|
128
128
|
end
|
129
129
|
|
130
|
-
def message_for_dup(node, method_name)
|
131
|
-
format(MSG, method: method_name, defined: source_location(@definitions[
|
130
|
+
def message_for_dup(node, method_name, key)
|
131
|
+
format(MSG, method: method_name, defined: source_location(@definitions[key]),
|
132
132
|
current: source_location(node))
|
133
133
|
end
|
134
134
|
|
@@ -156,18 +156,27 @@ module RuboCop
|
|
156
156
|
end
|
157
157
|
|
158
158
|
def found_method(node, method_name)
|
159
|
-
|
160
|
-
|
161
|
-
|
159
|
+
key = method_key(node, method_name)
|
160
|
+
|
161
|
+
if @definitions.key?(key)
|
162
|
+
loc = if DEF_TYPES.include?(node.type)
|
162
163
|
node.loc.keyword.join(node.loc.name)
|
163
164
|
else
|
164
165
|
node.loc.expression
|
165
166
|
end
|
166
|
-
message = message_for_dup(node, method_name)
|
167
|
+
message = message_for_dup(node, method_name, key)
|
167
168
|
|
168
169
|
add_offense(loc, message: message)
|
169
170
|
else
|
170
|
-
@definitions[
|
171
|
+
@definitions[key] = node
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def method_key(node, method_name)
|
176
|
+
if (ancestor_def = node.each_ancestor(*DEF_TYPES).first)
|
177
|
+
"#{ancestor_def.method_name}.#{method_name}"
|
178
|
+
else
|
179
|
+
method_name
|
171
180
|
end
|
172
181
|
end
|
173
182
|
|
@@ -141,7 +141,7 @@ module RuboCop
|
|
141
141
|
if empty_if_branch?(node) && else_branch?(node)
|
142
142
|
node.source_range.with(end_pos: node.loc.else.begin_pos)
|
143
143
|
elsif node.loc.else
|
144
|
-
node.source_range.with(end_pos: node.loc.
|
144
|
+
node.source_range.with(end_pos: node.condition.loc.expression.end_pos)
|
145
145
|
elsif all_branches_body_missing?(node)
|
146
146
|
if_node = node.ancestors.detect(&:if?)
|
147
147
|
node.source_range.with(end_pos: if_node.loc.end.end_pos)
|
@@ -50,9 +50,7 @@ module RuboCop
|
|
50
50
|
|
51
51
|
def on_new_investigation
|
52
52
|
each_missing_enable do |cop, line_range|
|
53
|
-
|
54
|
-
# the case when max_range is Float::INFINITY
|
55
|
-
next if line_range.max - line_range.min < max_range + 2
|
53
|
+
next if acceptable_range?(cop, line_range)
|
56
54
|
|
57
55
|
range = source_range(processed_source.buffer, line_range.min, (0..0))
|
58
56
|
comment = processed_source.comment_at_line(line_range.begin)
|
@@ -69,6 +67,23 @@ module RuboCop
|
|
69
67
|
end
|
70
68
|
end
|
71
69
|
|
70
|
+
def acceptable_range?(cop, line_range)
|
71
|
+
# This has to remain a strict inequality to handle
|
72
|
+
# the case when max_range is Float::INFINITY
|
73
|
+
return true if line_range.max - line_range.min < max_range + 2
|
74
|
+
# This cop is disabled in the config, it is not expected to be re-enabled
|
75
|
+
return true if line_range.min == CommentConfig::CONFIG_DISABLED_LINE_RANGE_MIN
|
76
|
+
|
77
|
+
cop_class = RuboCop::Cop::Registry.global.find_by_cop_name cop
|
78
|
+
if cop_class &&
|
79
|
+
!processed_source.registry.enabled?(cop_class, config) &&
|
80
|
+
line_range.max == Float::INFINITY
|
81
|
+
return true
|
82
|
+
end
|
83
|
+
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
72
87
|
def max_range
|
73
88
|
@max_range ||= cop_config['MaximumRangeSize']
|
74
89
|
end
|
@@ -113,6 +113,7 @@ module RuboCop
|
|
113
113
|
def each_line_range(cop, line_ranges)
|
114
114
|
line_ranges.each_with_index do |line_range, line_range_index|
|
115
115
|
next if ignore_offense?(line_range)
|
116
|
+
next if expected_final_disable?(cop, line_range)
|
116
117
|
|
117
118
|
comment = processed_source.comment_at_line(line_range.begin)
|
118
119
|
redundant = if all_disabled?(comment)
|
@@ -179,11 +180,21 @@ module RuboCop
|
|
179
180
|
end
|
180
181
|
|
181
182
|
def ignore_offense?(line_range)
|
183
|
+
return true if line_range.min == CommentConfig::CONFIG_DISABLED_LINE_RANGE_MIN
|
184
|
+
|
182
185
|
disabled_ranges.any? do |range|
|
183
186
|
range.cover?(line_range.min) && range.cover?(line_range.max)
|
184
187
|
end
|
185
188
|
end
|
186
189
|
|
190
|
+
def expected_final_disable?(cop, line_range)
|
191
|
+
# A cop which is disabled in the config is being re-disabled until end of file
|
192
|
+
cop_class = RuboCop::Cop::Registry.global.find_by_cop_name cop
|
193
|
+
cop_class &&
|
194
|
+
!processed_source.registry.enabled?(cop_class, config) &&
|
195
|
+
line_range.max == Float::INFINITY
|
196
|
+
end
|
197
|
+
|
187
198
|
def department_disabled?(cop, comment)
|
188
199
|
directive = DirectiveComment.new(comment)
|
189
200
|
directive.in_directive_department?(cop) && !directive.overridden_by_department?(cop)
|
@@ -20,6 +20,7 @@ module RuboCop
|
|
20
20
|
# * 2.5+ ... Add `pp` above
|
21
21
|
# * 2.7+ ... Add `ruby2_keywords` above
|
22
22
|
# * 3.1+ ... Add `fiber` above
|
23
|
+
# * 3.2+ ... `set`
|
23
24
|
#
|
24
25
|
# This cop target those features.
|
25
26
|
#
|
@@ -48,7 +49,13 @@ module RuboCop
|
|
48
49
|
return unless redundant_require_statement?(node)
|
49
50
|
|
50
51
|
add_offense(node) do |corrector|
|
51
|
-
|
52
|
+
if node.parent.respond_to?(:modifier_form?) && node.parent.modifier_form?
|
53
|
+
corrector.insert_after(node.parent, "\nend")
|
54
|
+
|
55
|
+
range = range_with_surrounding_space(node.loc.expression, side: :right)
|
56
|
+
else
|
57
|
+
range = range_by_whole_lines(node.source_range, include_final_newline: true)
|
58
|
+
end
|
52
59
|
|
53
60
|
corrector.remove(range)
|
54
61
|
end
|
@@ -63,7 +70,8 @@ module RuboCop
|
|
63
70
|
(target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
|
64
71
|
(target_ruby_version >= 2.5 && feature_name == 'pp') ||
|
65
72
|
(target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
|
66
|
-
(target_ruby_version >= 3.1 && feature_name == 'fiber')
|
73
|
+
(target_ruby_version >= 3.1 && feature_name == 'fiber') ||
|
74
|
+
(target_ruby_version >= 3.2 && feature_name == 'set')
|
67
75
|
end
|
68
76
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
69
77
|
end
|
@@ -116,7 +116,7 @@ module RuboCop
|
|
116
116
|
private
|
117
117
|
|
118
118
|
def comment_between_rescue_and_end?(node)
|
119
|
-
ancestor = node.each_ancestor(:kwbegin, :def, :defs, :block).first
|
119
|
+
ancestor = node.each_ancestor(:kwbegin, :def, :defs, :block, :numblock).first
|
120
120
|
return unless ancestor
|
121
121
|
|
122
122
|
end_line = ancestor.loc.end.line
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
20
20
|
#
|
21
21
|
# @example CountRepeatedAttributes: false (default is true)
|
22
22
|
#
|
23
|
-
# # `model` and `current_user`,
|
23
|
+
# # `model` and `current_user`, referenced 3 times each,
|
24
24
|
# # are each counted as only 1 branch each if
|
25
25
|
# # `CountRepeatedAttributes` is set to 'false'
|
26
26
|
#
|
@@ -126,6 +126,29 @@ module RuboCop
|
|
126
126
|
pos += size * step while condition && src[pos + offset, size] == needle
|
127
127
|
pos.negative? ? 0 : pos
|
128
128
|
end
|
129
|
+
|
130
|
+
def range_with_comments_and_lines(node)
|
131
|
+
range_by_whole_lines(range_with_comments(node), include_final_newline: true)
|
132
|
+
end
|
133
|
+
|
134
|
+
def range_with_comments(node)
|
135
|
+
ranges = [
|
136
|
+
node,
|
137
|
+
*@processed_source.ast_with_comments[node]
|
138
|
+
].map do |element|
|
139
|
+
element.location.expression
|
140
|
+
end
|
141
|
+
ranges.reduce do |result, range|
|
142
|
+
add_range(result, range)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def add_range(range1, range2)
|
147
|
+
range1.with(
|
148
|
+
begin_pos: [range1.begin_pos, range2.begin_pos].min,
|
149
|
+
end_pos: [range1.end_pos, range2.end_pos].max
|
150
|
+
)
|
151
|
+
end
|
129
152
|
end
|
130
153
|
end
|
131
154
|
end
|
@@ -118,14 +118,15 @@ module RuboCop
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def offending_empty_no_space?(config, left_token, right_token)
|
121
|
-
config == 'no_space' && !
|
121
|
+
config == 'no_space' && !no_character_between?(left_token, right_token)
|
122
122
|
end
|
123
123
|
|
124
124
|
def space_between?(left_bracket_token, right_bracket_token)
|
125
|
-
left_bracket_token.end_pos + 1 == right_bracket_token.begin_pos
|
125
|
+
left_bracket_token.end_pos + 1 == right_bracket_token.begin_pos &&
|
126
|
+
processed_source.buffer.source[left_bracket_token.end_pos] == ' '
|
126
127
|
end
|
127
128
|
|
128
|
-
def
|
129
|
+
def no_character_between?(left_bracket_token, right_bracket_token)
|
129
130
|
left_bracket_token.end_pos == right_bracket_token.begin_pos
|
130
131
|
end
|
131
132
|
end
|
@@ -1,18 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'set'
|
4
|
+
|
3
5
|
module RuboCop
|
4
6
|
module Cop
|
5
7
|
# Help methods for determining node visibility.
|
6
8
|
module VisibilityHelp
|
7
9
|
extend NodePattern::Macros
|
8
10
|
|
9
|
-
VISIBILITY_SCOPES =
|
11
|
+
VISIBILITY_SCOPES = ::Set[:private, :protected, :public].freeze
|
10
12
|
|
11
13
|
private
|
12
14
|
|
13
15
|
def node_visibility(node)
|
14
|
-
|
15
|
-
|
16
|
+
node_visibility_from_visibility_inline(node) ||
|
17
|
+
node_visibility_from_visibility_block(node) ||
|
18
|
+
:public
|
19
|
+
end
|
20
|
+
|
21
|
+
def node_visibility_from_visibility_inline(node)
|
22
|
+
return unless node.def_type?
|
23
|
+
|
24
|
+
node_visibility_from_visibility_inline_on_def(node) ||
|
25
|
+
node_visibility_from_visibility_inline_on_method_name(node)
|
26
|
+
end
|
27
|
+
|
28
|
+
def node_visibility_from_visibility_inline_on_def(node)
|
29
|
+
parent = node.parent
|
30
|
+
parent.method_name if visibility_inline_on_def?(parent)
|
31
|
+
end
|
32
|
+
|
33
|
+
def node_visibility_from_visibility_inline_on_method_name(node)
|
34
|
+
node.right_siblings.reverse.find do |sibling|
|
35
|
+
visibility_inline_on_method_name?(sibling, method_name: node.method_name)
|
36
|
+
end&.method_name
|
37
|
+
end
|
38
|
+
|
39
|
+
def node_visibility_from_visibility_block(node)
|
40
|
+
find_visibility_start(node)&.method_name
|
16
41
|
end
|
17
42
|
|
18
43
|
def find_visibility_start(node)
|
@@ -21,7 +46,7 @@ module RuboCop
|
|
21
46
|
|
22
47
|
# Navigate to find the last protected method
|
23
48
|
def find_visibility_end(node)
|
24
|
-
possible_visibilities = VISIBILITY_SCOPES - [node_visibility(node)]
|
49
|
+
possible_visibilities = VISIBILITY_SCOPES - ::Set[node_visibility(node)]
|
25
50
|
right = node.right_siblings
|
26
51
|
right.find do |child_node|
|
27
52
|
possible_visibilities.include?(node_visibility(child_node))
|
@@ -30,7 +55,17 @@ module RuboCop
|
|
30
55
|
|
31
56
|
# @!method visibility_block?(node)
|
32
57
|
def_node_matcher :visibility_block?, <<~PATTERN
|
33
|
-
(send nil?
|
58
|
+
(send nil? VISIBILITY_SCOPES)
|
59
|
+
PATTERN
|
60
|
+
|
61
|
+
# @!method visibility_inline_on_def?(node)
|
62
|
+
def_node_matcher :visibility_inline_on_def?, <<~PATTERN
|
63
|
+
(send nil? VISIBILITY_SCOPES def)
|
64
|
+
PATTERN
|
65
|
+
|
66
|
+
# @!method visibility_inline_on_method_name?(node, method_name:)
|
67
|
+
def_node_matcher :visibility_inline_on_method_name?, <<~PATTERN
|
68
|
+
(send nil? VISIBILITY_SCOPES (sym %method_name))
|
34
69
|
PATTERN
|
35
70
|
end
|
36
71
|
end
|