rubocop 1.36.0 → 1.37.1
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 +21 -1
- data/lib/rubocop/arguments_env.rb +17 -0
- data/lib/rubocop/arguments_file.rb +17 -0
- data/lib/rubocop/cli/command/execute_runner.rb +7 -7
- data/lib/rubocop/cli/command/suggest_extensions.rb +8 -1
- data/lib/rubocop/cop/generator.rb +1 -2
- 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/first_argument_indentation.rb +1 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +13 -9
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +28 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_magic_comment.rb +73 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +11 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +25 -6
- data/lib/rubocop/cop/lint/empty_class.rb +3 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +19 -7
- data/lib/rubocop/cop/lint/nested_method_definition.rb +50 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +4 -5
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +12 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +7 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +29 -9
- data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +0 -10
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +3 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/unused_method_argument.rb +4 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +12 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +6 -3
- data/lib/rubocop/cop/mixin/rescue_node.rb +3 -1
- data/lib/rubocop/cop/mixin/surrounding_space.rb +6 -5
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +24 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +7 -3
- 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/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_compact.rb +8 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +1 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +4 -0
- data/lib/rubocop/cop/style/format_string_token.rb +1 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +13 -2
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +40 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +5 -2
- data/lib/rubocop/cop/style/redundant_initialize.rb +3 -1
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +8 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +181 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
- data/lib/rubocop/cop/style/static_class.rb +32 -1
- data/lib/rubocop/cop/style/symbol_array.rb +2 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +2 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +8 -2
- data/lib/rubocop/options.rb +13 -13
- data/lib/rubocop/rspec/shared_contexts.rb +13 -1
- data/lib/rubocop/server/cache.rb +5 -1
- data/lib/rubocop/server/cli.rb +9 -2
- data/lib/rubocop/server/client_command/exec.rb +5 -0
- data/lib/rubocop/server/core.rb +2 -1
- data/lib/rubocop/server/socket_reader.rb +5 -1
- data/lib/rubocop/server.rb +1 -1
- data/lib/rubocop/version.rb +8 -3
- data/lib/rubocop.rb +3 -0
- metadata +12 -5
@@ -92,13 +92,17 @@ module RuboCop
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def remove_empty_branch(corrector, node)
|
95
|
-
|
95
|
+
if empty_if_branch?(node) && else_branch?(node)
|
96
|
+
corrector.remove(branch_range(node))
|
97
|
+
else
|
98
|
+
corrector.remove(deletion_range(branch_range(node)))
|
99
|
+
end
|
96
100
|
end
|
97
101
|
|
98
102
|
def correct_other_branches(corrector, node)
|
99
103
|
return unless require_other_branches_correction?(node)
|
100
104
|
|
101
|
-
if node.else_branch
|
105
|
+
if node.else_branch&.if_type?
|
102
106
|
# Replace an orphaned `elsif` with `if`
|
103
107
|
corrector.replace(node.else_branch.loc.keyword, 'if')
|
104
108
|
else
|
@@ -108,10 +112,10 @@ module RuboCop
|
|
108
112
|
end
|
109
113
|
|
110
114
|
def require_other_branches_correction?(node)
|
111
|
-
return false unless node.if_type? && node.
|
115
|
+
return false unless node.if_type? && node.else?
|
112
116
|
return false if !empty_if_branch?(node) && node.elsif?
|
113
117
|
|
114
|
-
!
|
118
|
+
!empty_elsif_branch?(node)
|
115
119
|
end
|
116
120
|
|
117
121
|
def empty_if_branch?(node)
|
@@ -122,13 +126,21 @@ module RuboCop
|
|
122
126
|
if_branch.if_type? && !if_branch.body
|
123
127
|
end
|
124
128
|
|
125
|
-
def
|
126
|
-
|
129
|
+
def empty_elsif_branch?(node)
|
130
|
+
return false unless (else_branch = node.else_branch)
|
131
|
+
|
132
|
+
else_branch.if_type? && !else_branch.body
|
133
|
+
end
|
134
|
+
|
135
|
+
def else_branch?(node)
|
136
|
+
node.else_branch && !node.else_branch.if_type?
|
127
137
|
end
|
128
138
|
|
129
139
|
# rubocop:disable Metrics/AbcSize
|
130
140
|
def branch_range(node)
|
131
|
-
if node
|
141
|
+
if empty_if_branch?(node) && else_branch?(node)
|
142
|
+
node.source_range.with(end_pos: node.loc.else.begin_pos)
|
143
|
+
elsif node.loc.else
|
132
144
|
node.source_range.with(end_pos: node.loc.else.begin_pos - 1)
|
133
145
|
elsif all_branches_body_missing?(node)
|
134
146
|
if_node = node.ancestors.detect(&:if?)
|
@@ -30,6 +30,9 @@ module RuboCop
|
|
30
30
|
#
|
31
31
|
# # good
|
32
32
|
#
|
33
|
+
# # `class_eval`, `instance_eval`, `module_eval`, `class_exec`, `instance_exec`, and
|
34
|
+
# # `module_exec` blocks are allowed by default.
|
35
|
+
#
|
33
36
|
# def foo
|
34
37
|
# self.class.class_eval do
|
35
38
|
# def bar
|
@@ -54,7 +57,47 @@ module RuboCop
|
|
54
57
|
# end
|
55
58
|
# end
|
56
59
|
# end
|
60
|
+
#
|
61
|
+
# @example AllowedMethods: [] (default)
|
62
|
+
# # bad
|
63
|
+
# def do_something
|
64
|
+
# has_many :articles do
|
65
|
+
# def find_or_create_by_name(name)
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# @example AllowedMethods: ['has_many']
|
71
|
+
# # bad
|
72
|
+
# def do_something
|
73
|
+
# has_many :articles do
|
74
|
+
# def find_or_create_by_name(name)
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# @example AllowedPatterns: [] (default)
|
80
|
+
# # bad
|
81
|
+
# def foo(obj)
|
82
|
+
# obj.do_baz do
|
83
|
+
# def bar
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# @example AllowedPatterns: ['baz']
|
89
|
+
# # good
|
90
|
+
# def foo(obj)
|
91
|
+
# obj.do_baz do
|
92
|
+
# def bar
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
# end
|
96
|
+
#
|
57
97
|
class NestedMethodDefinition < Base
|
98
|
+
include AllowedMethods
|
99
|
+
include AllowedPattern
|
100
|
+
|
58
101
|
MSG = 'Method definitions must not be nested. Use `lambda` instead.'
|
59
102
|
|
60
103
|
def on_def(node)
|
@@ -77,7 +120,13 @@ module RuboCop
|
|
77
120
|
|
78
121
|
def scoping_method_call?(child)
|
79
122
|
child.sclass_type? || eval_call?(child) || exec_call?(child) ||
|
80
|
-
class_or_module_or_struct_new_call?(child)
|
123
|
+
class_or_module_or_struct_new_call?(child) || allowed_method_name?(child)
|
124
|
+
end
|
125
|
+
|
126
|
+
def allowed_method_name?(node)
|
127
|
+
name = node.method_name
|
128
|
+
|
129
|
+
allowed_method?(name) || matches_allowed_pattern?(name)
|
81
130
|
end
|
82
131
|
|
83
132
|
# @!method eval_call?(node)
|
@@ -7,6 +7,9 @@ module RuboCop
|
|
7
7
|
# Checks the proper ordering of magic comments and whether
|
8
8
|
# a magic comment is not placed before a shebang.
|
9
9
|
#
|
10
|
+
# @safety
|
11
|
+
# This cop's autocorrection is unsafe because file encoding may change.
|
12
|
+
#
|
10
13
|
# @example
|
11
14
|
# # bad
|
12
15
|
#
|
@@ -61,7 +64,7 @@ module RuboCop
|
|
61
64
|
def magic_comment_lines
|
62
65
|
lines = [nil, nil]
|
63
66
|
|
64
|
-
|
67
|
+
leading_magic_comments.each.with_index do |comment, index|
|
65
68
|
if comment.encoding_specified?
|
66
69
|
lines[0] = index
|
67
70
|
elsif comment.frozen_string_literal_specified?
|
@@ -73,10 +76,6 @@ module RuboCop
|
|
73
76
|
|
74
77
|
lines
|
75
78
|
end
|
76
|
-
|
77
|
-
def magic_comments
|
78
|
-
leading_comment_lines.map { |line| MagicComment.parse(line) }
|
79
|
-
end
|
80
79
|
end
|
81
80
|
end
|
82
81
|
end
|
@@ -209,7 +209,12 @@ module RuboCop
|
|
209
209
|
|
210
210
|
add_offense(location, message: message(cop_names)) do |corrector|
|
211
211
|
range = comment_range_with_surrounding_space(location, comment.loc.expression)
|
212
|
-
|
212
|
+
|
213
|
+
if leave_free_comment?(comment, range)
|
214
|
+
corrector.replace(range, ' # ')
|
215
|
+
else
|
216
|
+
corrector.remove(range)
|
217
|
+
end
|
213
218
|
end
|
214
219
|
end
|
215
220
|
|
@@ -227,6 +232,12 @@ module RuboCop
|
|
227
232
|
end
|
228
233
|
end
|
229
234
|
|
235
|
+
def leave_free_comment?(comment, range)
|
236
|
+
free_comment = comment.text.gsub(range.source.strip, '')
|
237
|
+
|
238
|
+
!free_comment.empty? && !free_comment.start_with?('#')
|
239
|
+
end
|
240
|
+
|
230
241
|
def cop_range(comment, cop)
|
231
242
|
cop = remove_department_marker(cop)
|
232
243
|
matching_range(comment.loc.expression, cop) ||
|
@@ -41,6 +41,7 @@ module RuboCop
|
|
41
41
|
return unless (receiver = node.receiver)
|
42
42
|
return unless receiver.receiver&.const_type? && receiver.receiver.short_name == :Dir
|
43
43
|
return unless GLOB_METHODS.include?(receiver.method_name)
|
44
|
+
return if multiple_argument?(receiver)
|
44
45
|
|
45
46
|
selector = node.loc.selector
|
46
47
|
|
@@ -49,6 +50,12 @@ module RuboCop
|
|
49
50
|
corrector.remove(node.loc.dot)
|
50
51
|
end
|
51
52
|
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def multiple_argument?(glob_method)
|
57
|
+
glob_method.arguments.count >= 2 || glob_method.first_argument&.splat_type?
|
58
|
+
end
|
52
59
|
end
|
53
60
|
end
|
54
61
|
end
|
@@ -6,13 +6,22 @@ module RuboCop
|
|
6
6
|
# Checks for unnecessary `require` statement.
|
7
7
|
#
|
8
8
|
# The following features are unnecessary `require` statement because
|
9
|
-
# they are already loaded.
|
9
|
+
# they are already loaded. e.g. Ruby 2.2:
|
10
10
|
#
|
11
11
|
# ruby -ve 'p $LOADED_FEATURES.reject { |feature| %r|/| =~ feature }'
|
12
12
|
# ruby 2.2.8p477 (2017-09-14 revision 59906) [x86_64-darwin13]
|
13
13
|
# ["enumerator.so", "rational.so", "complex.so", "thread.rb"]
|
14
14
|
#
|
15
|
-
#
|
15
|
+
# Below are the features that each `TargetRubyVersion` targets.
|
16
|
+
#
|
17
|
+
# * 2.0+ ... `enumerator`
|
18
|
+
# * 2.1+ ... `thread`
|
19
|
+
# * 2.2+ ... Add `rational` and `complex` above
|
20
|
+
# * 2.5+ ... Add `pp` above
|
21
|
+
# * 2.7+ ... Add `ruby2_keywords` above
|
22
|
+
# * 3.1+ ... Add `fiber` above
|
23
|
+
#
|
24
|
+
# This cop target those features.
|
16
25
|
#
|
17
26
|
# @example
|
18
27
|
# # bad
|
@@ -24,21 +33,19 @@ module RuboCop
|
|
24
33
|
class RedundantRequireStatement < Base
|
25
34
|
include RangeHelp
|
26
35
|
extend AutoCorrector
|
27
|
-
extend TargetRubyVersion
|
28
|
-
|
29
|
-
minimum_target_ruby_version 2.2
|
30
36
|
|
31
37
|
MSG = 'Remove unnecessary `require` statement.'
|
32
38
|
RESTRICT_ON_SEND = %i[require].freeze
|
39
|
+
RUBY_22_LOADED_FEATURES = %w[rational complex].freeze
|
33
40
|
|
34
|
-
# @!method
|
35
|
-
def_node_matcher :
|
41
|
+
# @!method redundant_require_statement?(node)
|
42
|
+
def_node_matcher :redundant_require_statement?, <<~PATTERN
|
36
43
|
(send nil? :require
|
37
|
-
(str
|
44
|
+
(str #redundant_feature?))
|
38
45
|
PATTERN
|
39
46
|
|
40
47
|
def on_send(node)
|
41
|
-
return unless
|
48
|
+
return unless redundant_require_statement?(node)
|
42
49
|
|
43
50
|
add_offense(node) do |corrector|
|
44
51
|
range = range_with_surrounding_space(node.loc.expression, side: :right)
|
@@ -46,6 +53,19 @@ module RuboCop
|
|
46
53
|
corrector.remove(range)
|
47
54
|
end
|
48
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
60
|
+
def redundant_feature?(feature_name)
|
61
|
+
feature_name == 'enumerator' ||
|
62
|
+
(target_ruby_version >= 2.1 && feature_name == 'thread') ||
|
63
|
+
(target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
|
64
|
+
(target_ruby_version >= 2.5 && feature_name == 'pp') ||
|
65
|
+
(target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
|
66
|
+
(target_ruby_version >= 3.1 && feature_name == 'fiber')
|
67
|
+
end
|
68
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
49
69
|
end
|
50
70
|
end
|
51
71
|
end
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
private
|
47
47
|
|
48
48
|
def check_ternary(ternary, node)
|
49
|
-
return
|
49
|
+
return if node.method?(:[]) || !ternary.condition.operator_keyword?
|
50
50
|
|
51
51
|
range = range_between(node.source_range.begin_pos, ternary.condition.source_range.end_pos)
|
52
52
|
|
@@ -31,6 +31,7 @@ module RuboCop
|
|
31
31
|
minimum_target_ruby_version 2.3
|
32
32
|
|
33
33
|
MSG = 'Do not chain ordinary method call after safe navigation operator.'
|
34
|
+
PLUS_MINUS_METHODS = %i[+@ -@].freeze
|
34
35
|
|
35
36
|
# @!method bad_method?(node)
|
36
37
|
def_node_matcher :bad_method?, <<~PATTERN
|
@@ -42,7 +43,7 @@ module RuboCop
|
|
42
43
|
|
43
44
|
def on_send(node)
|
44
45
|
bad_method?(node) do |safe_nav, method|
|
45
|
-
return if nil_methods.include?(method)
|
46
|
+
return if nil_methods.include?(method) || PLUS_MINUS_METHODS.include?(node.method_name)
|
46
47
|
|
47
48
|
method_chain = method_chain(node)
|
48
49
|
location =
|
@@ -71,7 +72,7 @@ module RuboCop
|
|
71
72
|
else
|
72
73
|
offense_range.source.dup
|
73
74
|
end
|
74
|
-
source.prepend('.') unless
|
75
|
+
source.prepend('.') unless source.start_with?('.')
|
75
76
|
source.prepend('&')
|
76
77
|
end
|
77
78
|
|
@@ -155,16 +155,6 @@ module RuboCop
|
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
158
|
-
# @param [RuboCop::AST::Node] rescue_group is a node of array_type
|
159
|
-
def rescued_exceptions(rescue_group)
|
160
|
-
klasses = *rescue_group
|
161
|
-
klasses.map do |klass|
|
162
|
-
next unless klass.const_type?
|
163
|
-
|
164
|
-
klass.source
|
165
|
-
end.compact
|
166
|
-
end
|
167
|
-
|
168
158
|
def find_shadowing_rescue(rescues)
|
169
159
|
rescued_groups = rescued_groups_for(rescues)
|
170
160
|
rescued_groups.zip(rescues).each do |group, res|
|
@@ -12,9 +12,12 @@ module RuboCop
|
|
12
12
|
# because `Ractor` should not access outer variables.
|
13
13
|
# eg. following style is encouraged:
|
14
14
|
#
|
15
|
+
# [source,ruby]
|
16
|
+
# ----
|
15
17
|
# worker_id, pipe = env
|
16
18
|
# Ractor.new(worker_id, pipe) do |worker_id, pipe|
|
17
19
|
# end
|
20
|
+
# ----
|
18
21
|
#
|
19
22
|
# @example
|
20
23
|
#
|
@@ -79,7 +79,7 @@ module RuboCop
|
|
79
79
|
# # bad
|
80
80
|
# 2.times { raise ArgumentError }
|
81
81
|
#
|
82
|
-
# @example AllowedPatterns: [
|
82
|
+
# @example AllowedPatterns: ['(exactly|at_least|at_most)\(\d+\)\.times'] (default)
|
83
83
|
#
|
84
84
|
# # good
|
85
85
|
# exactly(2).times { raise StandardError }
|
@@ -22,6 +22,18 @@ module RuboCop
|
|
22
22
|
processed_source.each_comment_in_lines(start_line...end_line)
|
23
23
|
end
|
24
24
|
|
25
|
+
def comments_contain_disables?(node, cop_name)
|
26
|
+
disabled_ranges = processed_source.disabled_line_ranges[cop_name]
|
27
|
+
|
28
|
+
return unless disabled_ranges
|
29
|
+
|
30
|
+
node_range = node.source_range.line...find_end_line(node)
|
31
|
+
|
32
|
+
disabled_ranges.any? do |disable_range|
|
33
|
+
disable_range.cover?(node_range) || node_range.cover?(disable_range)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
25
37
|
private
|
26
38
|
|
27
39
|
def end_position_for(node)
|
@@ -96,11 +96,14 @@ module RuboCop
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def without_parentheses_call_expr_follows?(ancestor)
|
99
|
+
return false unless ancestor.respond_to?(:parenthesized?) && !ancestor.parenthesized?
|
100
|
+
|
99
101
|
right_sibling = ancestor.right_sibling
|
100
|
-
right_sibling ||= ancestor.each_ancestor.find
|
101
|
-
|
102
|
+
right_sibling ||= ancestor.each_ancestor.find do |node|
|
103
|
+
node.assignment? || node.send_type?
|
104
|
+
end&.right_sibling
|
102
105
|
|
103
|
-
|
106
|
+
!!right_sibling
|
104
107
|
end
|
105
108
|
|
106
109
|
def breakdown_value_types_of_hash(hash_node)
|
@@ -11,7 +11,9 @@ module RuboCop
|
|
11
11
|
private
|
12
12
|
|
13
13
|
def rescue_modifier?(node)
|
14
|
-
|
14
|
+
return false unless node.respond_to?(:resbody_type?)
|
15
|
+
|
16
|
+
node.resbody_type? && @modifier_locations.include?(node.loc.keyword)
|
15
17
|
end
|
16
18
|
|
17
19
|
# @deprecated Use ResbodyNode#exceptions instead
|
@@ -13,7 +13,7 @@ module RuboCop
|
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
def side_space_range(range:, side:)
|
16
|
+
def side_space_range(range:, side:, include_newlines: false)
|
17
17
|
buffer = processed_source.buffer
|
18
18
|
src = buffer.source
|
19
19
|
|
@@ -21,11 +21,11 @@ module RuboCop
|
|
21
21
|
end_pos = range.end_pos
|
22
22
|
if side == :left
|
23
23
|
end_pos = begin_pos
|
24
|
-
begin_pos = reposition(src, begin_pos, -1)
|
24
|
+
begin_pos = reposition(src, begin_pos, -1, include_newlines: include_newlines)
|
25
25
|
end
|
26
26
|
if side == :right
|
27
27
|
begin_pos = end_pos
|
28
|
-
end_pos = reposition(src, end_pos, 1)
|
28
|
+
end_pos = reposition(src, end_pos, 1, include_newlines: include_newlines)
|
29
29
|
end
|
30
30
|
Parser::Source::Range.new(buffer, begin_pos, end_pos)
|
31
31
|
end
|
@@ -75,9 +75,10 @@ module RuboCop
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
def reposition(src, pos, step)
|
78
|
+
def reposition(src, pos, step, include_newlines: false)
|
79
79
|
offset = step == -1 ? -1 : 0
|
80
|
-
pos += step while SINGLE_SPACE_REGEXP.match?(src[pos + offset])
|
80
|
+
pos += step while SINGLE_SPACE_REGEXP.match?(src[pos + offset]) ||
|
81
|
+
(include_newlines && src[pos + offset] == "\n")
|
81
82
|
pos.negative? ? 0 : pos
|
82
83
|
end
|
83
84
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Naming
|
6
|
-
#
|
6
|
+
# Recommends the use of inclusive language instead of problematic terms.
|
7
7
|
# The cop can check the following locations for offenses:
|
8
8
|
# - identifiers
|
9
9
|
# - constants
|
@@ -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)
|
@@ -183,6 +185,7 @@ module RuboCop
|
|
183
185
|
end
|
184
186
|
|
185
187
|
def insert_def(corrector, node, source)
|
188
|
+
source = [*processed_source.ast_with_comments[node].map(&:text), source].join("\n")
|
186
189
|
argument_less_modifier_node = find_argument_less_modifier_node(node)
|
187
190
|
if argument_less_modifier_node
|
188
191
|
corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
|
@@ -201,11 +204,30 @@ module RuboCop
|
|
201
204
|
def remove_node(corrector, node)
|
202
205
|
corrector.remove(
|
203
206
|
range_by_whole_lines(
|
204
|
-
node
|
207
|
+
range_with_comments(node),
|
205
208
|
include_final_newline: true
|
206
209
|
)
|
207
210
|
)
|
208
211
|
end
|
212
|
+
|
213
|
+
def range_with_comments(node)
|
214
|
+
ranges = [
|
215
|
+
node,
|
216
|
+
*processed_source.ast_with_comments[node]
|
217
|
+
].map do |element|
|
218
|
+
element.location.expression
|
219
|
+
end
|
220
|
+
ranges.reduce do |result, range|
|
221
|
+
add_range(result, range)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def add_range(range1, range2)
|
226
|
+
range1.with(
|
227
|
+
begin_pos: [range1.begin_pos, range2.begin_pos].min,
|
228
|
+
end_pos: [range1.end_pos, range2.end_pos].max
|
229
|
+
)
|
230
|
+
end
|
209
231
|
end
|
210
232
|
end
|
211
233
|
end
|
@@ -135,12 +135,16 @@ module RuboCop
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def separate_accessors(node)
|
138
|
-
node.arguments.
|
139
|
-
|
138
|
+
node.arguments.flat_map do |arg|
|
139
|
+
lines = [
|
140
|
+
*processed_source.ast_with_comments[arg].map(&:text),
|
140
141
|
"#{node.method_name} #{arg.source}"
|
142
|
+
]
|
143
|
+
if arg == node.arguments.first
|
144
|
+
lines
|
141
145
|
else
|
142
146
|
indent = ' ' * node.loc.column
|
143
|
-
"#{indent}#{
|
147
|
+
lines.map { |line| "#{indent}#{line}" }
|
144
148
|
end
|
145
149
|
end.join("\n")
|
146
150
|
end
|
@@ -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)
|
@@ -36,8 +36,8 @@ module RuboCop
|
|
36
36
|
extend AutoCorrector
|
37
37
|
|
38
38
|
MSG = 'Use `%<good>s` instead of `%<bad>s`.'
|
39
|
-
|
40
39
|
RESTRICT_ON_SEND = %i[reject reject! select select!].freeze
|
40
|
+
TO_ENUM_METHODS = %i[to_enum lazy].freeze
|
41
41
|
|
42
42
|
# @!method reject_method_with_block_pass?(node)
|
43
43
|
def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
|
@@ -69,6 +69,7 @@ module RuboCop
|
|
69
69
|
|
70
70
|
def on_send(node)
|
71
71
|
return unless (range = offense_range(node))
|
72
|
+
return if target_ruby_version <= 3.0 && to_enum_method?(node)
|
72
73
|
|
73
74
|
good = good_method_name(node)
|
74
75
|
message = format(MSG, good: good, bad: range.source)
|
@@ -94,6 +95,12 @@ module RuboCop
|
|
94
95
|
end
|
95
96
|
end
|
96
97
|
|
98
|
+
def to_enum_method?(node)
|
99
|
+
return false unless node.receiver.send_type?
|
100
|
+
|
101
|
+
TO_ENUM_METHODS.include?(node.receiver.method_name)
|
102
|
+
end
|
103
|
+
|
97
104
|
def good_method_name(node)
|
98
105
|
if node.bang_method?
|
99
106
|
'compact!'
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
52
52
|
MSG_EXPANDED = 'Put the `end` of empty method definitions on the next line.'
|
53
53
|
|
54
54
|
def on_def(node)
|
55
|
-
return if node.body ||
|
55
|
+
return if node.body || processed_source.contains_comment?(node.source_range)
|
56
56
|
return if correct_style?(node)
|
57
57
|
|
58
58
|
add_offense(node) do |corrector|
|