rubocop 1.37.0 → 1.38.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 +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)
|