rubocop 1.37.1 → 1.39.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 +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
|