rubocop 1.37.0 → 1.38.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 -0
- data/lib/rubocop/cli/command/suggest_extensions.rb +8 -1
- data/lib/rubocop/comment_config.rb +36 -1
- data/lib/rubocop/cop/commissioner.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/create_empty_file.rb +37 -0
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +111 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +6 -2
- 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/mixin/surrounding_space.rb +4 -3
- data/lib/rubocop/cop/registry.rb +10 -4
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/character_literal.rb +1 -1
- data/lib/rubocop/cop/style/collection_compact.rb +6 -2
- data/lib/rubocop/cop/style/guard_clause.rb +62 -21
- 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/operator_method_call.rb +2 -1
- data/lib/rubocop/cop/style/redundant_each.rb +111 -0
- data/lib/rubocop/cop/style/redundant_string_escape.rb +13 -5
- data/lib/rubocop/cop/team.rb +3 -4
- data/lib/rubocop/cop/variable_force/variable_table.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +4 -2
- 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 +1 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +1 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ed47ef39bb205db15249a399d0502f730c2656f712293357651cc0ddd328715
|
4
|
+
data.tar.gz: 5e6411a2b459e0ac426e0ef0d8b8508b9b1693fea0c5b8cb5d82ed23f71d39b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cfd13ac3c283e77e300f87ee923be282740f2763e26c73d21d27b5ae176629d15d8d580d9d326349acf5b71c74e6335689c2192050a818577b9f2e0a6a4484f
|
7
|
+
data.tar.gz: 27f36547ccdf6cc1336e1c44c5e164410f65344cba77fda76ad2db463054adaa93c96a406939b3826412280463a1d6a2940708f4080bc3170999bcc81594ba9d
|
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.38', 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
@@ -4696,6 +4696,12 @@ Style/RedundantConditional:
|
|
4696
4696
|
Enabled: true
|
4697
4697
|
VersionAdded: '0.50'
|
4698
4698
|
|
4699
|
+
Style/RedundantEach:
|
4700
|
+
Description: 'Checks for redundant `each`.'
|
4701
|
+
Enabled: pending
|
4702
|
+
Safe: false
|
4703
|
+
VersionAdded: '1.38'
|
4704
|
+
|
4699
4705
|
Style/RedundantException:
|
4700
4706
|
Description: "Checks for an obsolete RuntimeException argument in raise/fail."
|
4701
4707
|
StyleGuide: '#no-explicit-runtimeerror'
|
@@ -73,7 +73,14 @@ module RuboCop
|
|
73
73
|
def all_extensions
|
74
74
|
return [] unless lockfile.dependencies.any?
|
75
75
|
|
76
|
-
extensions = @config_store.for_pwd.for_all_cops['SuggestExtensions']
|
76
|
+
extensions = @config_store.for_pwd.for_all_cops['SuggestExtensions']
|
77
|
+
case extensions
|
78
|
+
when true
|
79
|
+
extensions = ConfigLoader.default_configuration.for_all_cops['SuggestExtensions']
|
80
|
+
when false, nil
|
81
|
+
extensions = {}
|
82
|
+
end
|
83
|
+
|
77
84
|
extensions.select { |_, v| (Array(v) & dependent_gems).any? }.keys
|
78
85
|
end
|
79
86
|
|
@@ -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
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Checks for uses of `create_file` with empty string second argument.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# create_file(path, '')
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# create_empty_file(path)
|
15
|
+
#
|
16
|
+
class CreateEmptyFile < Base
|
17
|
+
extend AutoCorrector
|
18
|
+
|
19
|
+
MSG = 'Use `%<replacement>s`.'
|
20
|
+
RESTRICT_ON_SEND = %i[create_file].freeze
|
21
|
+
|
22
|
+
def on_send(node)
|
23
|
+
return if node.receiver
|
24
|
+
return unless (argument = node.arguments[1])
|
25
|
+
return unless argument.str_type? && argument.value.empty?
|
26
|
+
|
27
|
+
replacement = "create_empty_file(#{node.first_argument.source})"
|
28
|
+
message = format(MSG, replacement: replacement)
|
29
|
+
|
30
|
+
add_offense(node, message: message) do |corrector|
|
31
|
+
corrector.replace(node, replacement)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Use `RUBY` for heredoc delimiter of example Ruby code.
|
7
|
+
#
|
8
|
+
# Some editors may apply better syntax highlighting by using appropriate language names for
|
9
|
+
# the delimiter.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# expect_offense(<<~CODE)
|
14
|
+
# example_ruby_code
|
15
|
+
# CODE
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# expect_offense(<<~RUBY)
|
19
|
+
# example_ruby_code
|
20
|
+
# RUBY
|
21
|
+
class ExampleHeredocDelimiter < Base
|
22
|
+
extend AutoCorrector
|
23
|
+
|
24
|
+
EXPECTED_HEREDOC_DELIMITER = 'RUBY'
|
25
|
+
|
26
|
+
MSG = 'Use `RUBY` for heredoc delimiter of example Ruby code.'
|
27
|
+
|
28
|
+
RESTRICT_ON_SEND = %i[
|
29
|
+
expect_correction
|
30
|
+
expect_no_corrections
|
31
|
+
expect_no_offenses
|
32
|
+
expect_offense
|
33
|
+
].freeze
|
34
|
+
|
35
|
+
# @param node [RuboCop::AST::SendNode]
|
36
|
+
# @return [void]
|
37
|
+
def on_send(node)
|
38
|
+
heredoc_node = heredoc_node_from(node)
|
39
|
+
return unless heredoc_node
|
40
|
+
return if expected_heredoc_delimiter?(heredoc_node)
|
41
|
+
return if expected_heredoc_delimiter_in_body?(heredoc_node)
|
42
|
+
|
43
|
+
add_offense(heredoc_node) do |corrector|
|
44
|
+
autocorrect(corrector, heredoc_node)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
51
|
+
# @param node [RuboCop::AST::StrNode]
|
52
|
+
# @return [void]
|
53
|
+
def autocorrect(corrector, node)
|
54
|
+
[
|
55
|
+
heredoc_openning_delimiter_range_from(node),
|
56
|
+
heredoc_closing_delimiter_range_from(node)
|
57
|
+
].each do |range|
|
58
|
+
corrector.replace(range, EXPECTED_HEREDOC_DELIMITER)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param node [RuboCop::AST::StrNode]
|
63
|
+
# @return [Boolean]
|
64
|
+
def expected_heredoc_delimiter_in_body?(node)
|
65
|
+
node.location.heredoc_body.source.lines.any? do |line|
|
66
|
+
line.strip == EXPECTED_HEREDOC_DELIMITER
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param node [RuboCop::AST::StrNode]
|
71
|
+
# @return [Boolean]
|
72
|
+
def expected_heredoc_delimiter?(node)
|
73
|
+
heredoc_delimiter_string_from(node) == EXPECTED_HEREDOC_DELIMITER
|
74
|
+
end
|
75
|
+
|
76
|
+
# @param node [RuboCop::AST::SendNode]
|
77
|
+
# @return [RuboCop::AST::StrNode, nil]
|
78
|
+
def heredoc_node_from(node)
|
79
|
+
return unless node.first_argument.respond_to?(:heredoc?)
|
80
|
+
return unless node.first_argument.heredoc?
|
81
|
+
|
82
|
+
node.first_argument
|
83
|
+
end
|
84
|
+
|
85
|
+
# @param node [RuboCop::AST::StrNode]
|
86
|
+
# @return [String]
|
87
|
+
def heredoc_delimiter_string_from(node)
|
88
|
+
node.source[Heredoc::OPENING_DELIMITER, 2]
|
89
|
+
end
|
90
|
+
|
91
|
+
# @param node [RuboCop::AST::StrNode]
|
92
|
+
# @return [Parser::Source::Range]
|
93
|
+
def heredoc_openning_delimiter_range_from(node)
|
94
|
+
match_data = node.source.match(Heredoc::OPENING_DELIMITER)
|
95
|
+
node.location.expression.begin.adjust(
|
96
|
+
begin_pos: match_data.begin(2),
|
97
|
+
end_pos: match_data.end(2)
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
101
|
+
# @param node [RuboCop::AST::StrNode]
|
102
|
+
# @return [Parser::Source::Range]
|
103
|
+
def heredoc_closing_delimiter_range_from(node)
|
104
|
+
node.location.heredoc_end.end.adjust(
|
105
|
+
begin_pos: -heredoc_delimiter_string_from(node).length
|
106
|
+
)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'internal_affairs/cop_description'
|
4
|
+
require_relative 'internal_affairs/create_empty_file'
|
4
5
|
require_relative 'internal_affairs/empty_line_between_expect_offense_and_correction'
|
5
6
|
require_relative 'internal_affairs/example_description'
|
7
|
+
require_relative 'internal_affairs/example_heredoc_delimiter'
|
6
8
|
require_relative 'internal_affairs/inherit_deprecated_cop_class'
|
7
9
|
require_relative 'internal_affairs/location_line_equality_comparison'
|
8
10
|
require_relative 'internal_affairs/method_name_end_with'
|
@@ -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?
|
@@ -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?
|
@@ -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
|
@@ -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
|
@@ -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
|
data/lib/rubocop/cop/registry.rb
CHANGED
@@ -149,16 +149,22 @@ module RuboCop
|
|
149
149
|
@registry.size
|
150
150
|
end
|
151
151
|
|
152
|
-
def enabled(config
|
153
|
-
select { |cop|
|
152
|
+
def enabled(config)
|
153
|
+
select { |cop| enabled?(cop, config) }
|
154
154
|
end
|
155
155
|
|
156
|
-
def
|
156
|
+
def disabled(config)
|
157
|
+
reject { |cop| enabled?(cop, config) }
|
158
|
+
end
|
159
|
+
|
160
|
+
def enabled?(cop, config)
|
161
|
+
return true if options.fetch(:only, []).include?(cop.cop_name)
|
162
|
+
|
157
163
|
cfg = config.for_cop(cop)
|
158
164
|
|
159
165
|
cop_enabled = cfg.fetch('Enabled') == true || enabled_pending_cop?(cfg, config)
|
160
166
|
|
161
|
-
if
|
167
|
+
if options.fetch(:safe, false)
|
162
168
|
cop_enabled && cfg.fetch('Safe', true)
|
163
169
|
else
|
164
170
|
cop_enabled
|
@@ -85,6 +85,8 @@ module RuboCop
|
|
85
85
|
|
86
86
|
RESTRICT_ON_SEND = %i[private protected public module_function].freeze
|
87
87
|
|
88
|
+
ALLOWED_NODE_TYPES = %i[pair block].freeze
|
89
|
+
|
88
90
|
# @!method access_modifier_with_symbol?(node)
|
89
91
|
def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
|
90
92
|
(send nil? {:private :protected :public :module_function} (sym _))
|
@@ -92,7 +94,7 @@ module RuboCop
|
|
92
94
|
|
93
95
|
def on_send(node)
|
94
96
|
return unless node.access_modifier?
|
95
|
-
return if node.parent&.
|
97
|
+
return if ALLOWED_NODE_TYPES.include?(node.parent&.type)
|
96
98
|
return if allow_modifiers_on_symbols?(node)
|
97
99
|
|
98
100
|
if offense?(node)
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
def offense?(node)
|
31
31
|
# we don't register an offense for things like ?\C-\M-d
|
32
|
-
node.
|
32
|
+
node.character_literal? && node.source.size.between?(2, 3)
|
33
33
|
end
|
34
34
|
|
35
35
|
def autocorrect(corrector, node)
|
@@ -8,7 +8,9 @@ module RuboCop
|
|
8
8
|
#
|
9
9
|
# @safety
|
10
10
|
# It is unsafe by default because false positives may occur in the
|
11
|
-
# `nil` check of block arguments to the receiver object.
|
11
|
+
# `nil` check of block arguments to the receiver object. Additionally,
|
12
|
+
# we can't know the type of the receiver object for sure, which may
|
13
|
+
# result in false positives as well.
|
12
14
|
#
|
13
15
|
# For example, `[[1, 2], [3, nil]].reject { |first, second| second.nil? }`
|
14
16
|
# and `[[1, 2], [3, nil]].compact` are not compatible. This will work fine
|
@@ -96,7 +98,9 @@ module RuboCop
|
|
96
98
|
end
|
97
99
|
|
98
100
|
def to_enum_method?(node)
|
99
|
-
|
101
|
+
return false unless node.receiver.send_type?
|
102
|
+
|
103
|
+
TO_ENUM_METHODS.include?(node.receiver.method_name)
|
100
104
|
end
|
101
105
|
|
102
106
|
def good_method_name(node)
|