rubocop 1.74.0 → 1.75.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +32 -6
  4. data/config/obsoletion.yml +3 -1
  5. data/lib/rubocop/cli.rb +1 -1
  6. data/lib/rubocop/config.rb +35 -6
  7. data/lib/rubocop/config_loader.rb +4 -0
  8. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  9. data/lib/rubocop/config_obsoletion.rb +46 -2
  10. data/lib/rubocop/config_validator.rb +1 -0
  11. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +1 -1
  12. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  13. data/lib/rubocop/cop/layout/block_alignment.rb +1 -0
  14. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  15. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  16. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  17. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
  18. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  19. data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
  20. data/lib/rubocop/cop/layout/line_length.rb +5 -1
  21. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  22. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  23. data/lib/rubocop/cop/layout/redundant_line_break.rb +9 -5
  24. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
  25. data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
  26. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  27. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
  28. data/lib/rubocop/cop/lint/debugger.rb +2 -2
  29. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  30. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  31. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  32. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
  33. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  34. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
  35. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  36. data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -0
  37. data/lib/rubocop/cop/lint/void.rb +1 -0
  38. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  39. data/lib/rubocop/cop/metrics/method_length.rb +1 -0
  40. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
  41. data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
  42. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  43. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  44. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -0
  45. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  46. data/lib/rubocop/cop/naming/variable_name.rb +6 -19
  47. data/lib/rubocop/cop/registry.rb +9 -6
  48. data/lib/rubocop/cop/style/array_intersect.rb +39 -28
  49. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  50. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  51. data/lib/rubocop/cop/style/combinable_loops.rb +1 -0
  52. data/lib/rubocop/cop/style/for.rb +1 -0
  53. data/lib/rubocop/cop/style/guard_clause.rb +2 -1
  54. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -2
  55. data/lib/rubocop/cop/style/hash_fetch_chain.rb +105 -0
  56. data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
  57. data/lib/rubocop/cop/style/inverse_methods.rb +1 -0
  58. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  59. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  60. data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
  61. data/lib/rubocop/cop/style/lambda.rb +1 -0
  62. data/lib/rubocop/cop/style/map_into_array.rb +1 -0
  63. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -0
  64. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -0
  65. data/lib/rubocop/cop/style/next.rb +44 -0
  66. data/lib/rubocop/cop/style/object_then.rb +1 -0
  67. data/lib/rubocop/cop/style/proc.rb +1 -0
  68. data/lib/rubocop/cop/style/redundant_begin.rb +1 -0
  69. data/lib/rubocop/cop/style/redundant_format.rb +10 -3
  70. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -1
  71. data/lib/rubocop/cop/style/redundant_self.rb +1 -0
  72. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  73. data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
  74. data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
  75. data/lib/rubocop/cop/style/sole_nested_conditional.rb +41 -100
  76. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  77. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -0
  78. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  79. data/lib/rubocop/cop/variable_force/variable.rb +1 -6
  80. data/lib/rubocop/cop/variable_force.rb +1 -1
  81. data/lib/rubocop/lsp/runtime.rb +4 -4
  82. data/lib/rubocop/lsp/stdin_runner.rb +3 -1
  83. data/lib/rubocop/rspec/cop_helper.rb +4 -1
  84. data/lib/rubocop/rspec/shared_contexts.rb +20 -0
  85. data/lib/rubocop/rspec/support.rb +2 -0
  86. data/lib/rubocop/runner.rb +5 -1
  87. data/lib/rubocop/target_ruby.rb +1 -1
  88. data/lib/rubocop/version.rb +14 -7
  89. data/lib/rubocop.rb +4 -0
  90. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +20 -2
  91. metadata +10 -6
@@ -96,11 +96,7 @@ module RuboCop
96
96
  end
97
97
 
98
98
  def autocorrect(corrector, node, if_branch)
99
- if node.condition.or_type? || node.condition.assignment?
100
- corrector.wrap(node.condition, '(', ')')
101
- end
102
-
103
- if outer_condition_modify_form?(node, if_branch)
99
+ if node.modifier_form?
104
100
  autocorrect_outer_condition_modify_form(corrector, node, if_branch)
105
101
  else
106
102
  autocorrect_outer_condition_basic(corrector, node, if_branch)
@@ -108,74 +104,48 @@ module RuboCop
108
104
  end
109
105
 
110
106
  def autocorrect_outer_condition_basic(corrector, node, if_branch)
111
- correct_from_unless_to_if(corrector, node) if node.unless?
112
-
113
- outer_condition = node.condition
114
- correct_outer_condition(corrector, outer_condition)
107
+ correct_node(corrector, node)
115
108
 
116
- and_operator = if_branch.unless? ? ' && !' : ' && '
117
109
  if if_branch.modifier_form?
118
- correct_for_guard_condition_style(corrector, outer_condition, if_branch, and_operator)
110
+ correct_for_guard_condition_style(corrector, node, if_branch)
119
111
  else
120
- correct_for_basic_condition_style(corrector, node, if_branch, and_operator)
112
+ correct_for_basic_condition_style(corrector, node, if_branch)
121
113
  correct_for_comment(corrector, node, if_branch)
122
114
  end
123
115
  end
124
116
 
125
- def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
126
- correct_from_unless_to_if(corrector, if_branch, is_modify_form: true) if if_branch.unless?
127
- correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
117
+ def correct_node(corrector, node)
118
+ corrector.replace(node.loc.keyword, 'if') if node.unless?
119
+ corrector.replace(node.condition, chainable_condition(node))
128
120
  end
129
121
 
130
- def correct_from_unless_to_if(corrector, node, is_modify_form: false)
131
- corrector.replace(node.loc.keyword, 'if')
132
-
133
- insert_bang(corrector, node, is_modify_form)
134
- end
122
+ def correct_for_guard_condition_style(corrector, node, if_branch)
123
+ corrector.insert_after(node.condition, " && #{chainable_condition(if_branch)}")
135
124
 
136
- def correct_for_guard_condition_style(corrector, outer_condition, if_branch, and_operator)
137
- condition = if_branch.condition
138
- corrector.insert_after(outer_condition, "#{and_operator}#{replace_condition(condition)}")
139
-
140
- range = range_between(if_branch.loc.keyword.begin_pos, condition.source_range.end_pos)
125
+ range = range_between(
126
+ if_branch.loc.keyword.begin_pos, if_branch.condition.source_range.end_pos
127
+ )
141
128
  corrector.remove(range_with_surrounding_space(range, newlines: false))
142
- corrector.remove(if_branch.loc.keyword)
143
129
  end
144
130
 
145
- def correct_for_basic_condition_style(corrector, node, if_branch, and_operator)
131
+ def correct_for_basic_condition_style(corrector, node, if_branch)
146
132
  range = range_between(
147
133
  node.condition.source_range.end_pos, if_branch.condition.source_range.begin_pos
148
134
  )
149
- corrector.replace(range, and_operator)
150
- corrector.remove(range_by_whole_lines(node.loc.end, include_final_newline: true))
151
-
152
- wrap_condition(corrector, if_branch.condition)
153
- end
154
-
155
- def wrap_condition(corrector, condition)
156
- # Handle `send` and `block` nodes that need to be wrapped in parens
157
- # FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
158
- # but wrapping the argument list would be a more ergonomic correction.
159
- node_to_check = condition&.any_block_type? ? condition.send_node : condition
160
- return unless wrap_condition?(node_to_check)
135
+ corrector.replace(range, ' && ')
161
136
 
162
- if condition.call_type?
163
- source = parenthesized_method_arguments(condition)
137
+ corrector.replace(if_branch.condition, chainable_condition(if_branch))
164
138
 
165
- corrector.replace(condition, source)
166
- else
167
- corrector.wrap(condition, '(', ')')
168
- end
139
+ corrector.remove(range_by_whole_lines(node.loc.end, include_final_newline: true))
169
140
  end
170
141
 
171
- def correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
172
- condition = if_branch.condition
173
- corrector.insert_before(condition,
174
- "#{'!' if node.unless?}#{replace_condition(node.condition)} && ")
142
+ def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
143
+ correct_node(corrector, if_branch)
144
+
145
+ corrector.insert_before(if_branch.condition, "#{chainable_condition(node)} && ")
175
146
 
176
- corrector.remove(node.condition)
177
- corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
178
- corrector.replace(if_branch.loc.keyword, 'if')
147
+ range = range_between(node.loc.keyword.begin_pos, node.condition.source_range.end_pos)
148
+ corrector.remove(range_with_surrounding_space(range, newlines: false))
179
149
  end
180
150
 
181
151
  def correct_for_comment(corrector, node, if_branch)
@@ -187,61 +157,36 @@ module RuboCop
187
157
  corrector.insert_before(node.loc.keyword, comment_text) unless comments.empty?
188
158
  end
189
159
 
190
- def correct_outer_condition(corrector, condition)
191
- return unless require_parentheses?(condition)
192
-
193
- end_pos = condition.loc.selector.end_pos
194
- begin_pos = condition.first_argument.source_range.begin_pos
195
- return if end_pos > begin_pos
196
-
197
- range = range_between(end_pos, begin_pos)
198
- corrector.remove(range)
199
- corrector.insert_after(range, '(')
200
- corrector.insert_after(condition.last_argument, ')')
201
- end
160
+ def chainable_condition(node)
161
+ wrapped_condition = add_parentheses_if_needed(node.condition)
202
162
 
203
- def insert_bang(corrector, node, is_modify_form)
204
- condition = node.condition
163
+ return wrapped_condition if node.if?
205
164
 
206
- if (condition.send_type? && condition.comparison_method? && !condition.parenthesized?) ||
207
- (is_modify_form && wrap_condition?(condition))
208
- corrector.wrap(node.condition, '!(', ')')
209
- elsif condition.and_type?
210
- insert_bang_for_and(corrector, node)
211
- else
212
- corrector.insert_before(condition, '!')
213
- end
165
+ node.condition.and_type? ? "!(#{wrapped_condition})" : "!#{wrapped_condition}"
214
166
  end
215
167
 
216
- def insert_bang_for_and(corrector, node)
217
- lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
168
+ def add_parentheses_if_needed(condition)
169
+ # Handle `send` and `block` nodes that need to be wrapped in parens
170
+ # FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
171
+ # but wrapping the argument list would be a more ergonomic correction.
172
+ node_to_check = condition&.any_block_type? ? condition.send_node : condition
173
+ return condition.source unless add_parentheses?(node_to_check)
218
174
 
219
- if lhs.and_type?
220
- insert_bang_for_and(corrector, lhs)
221
- corrector.insert_before(rhs, '!') if rhs
175
+ if parenthesize_method?(condition)
176
+ parenthesized_method_arguments(condition)
222
177
  else
223
- corrector.insert_before(lhs, '!')
224
- corrector.insert_before(rhs, '!')
178
+ "(#{condition.source})"
225
179
  end
226
180
  end
227
181
 
228
- def require_parentheses?(condition)
229
- condition.call_type? && !condition.arguments.empty? && !condition.parenthesized? &&
230
- !condition.comparison_method?
231
- end
232
-
233
- def wrap_condition?(node)
234
- node.operator_keyword? || (node.call_type? && node.arguments.any? && !node.parenthesized?)
182
+ def parenthesize_method?(node)
183
+ node.call_type? && node.arguments.any? && !node.parenthesized? &&
184
+ !node.comparison_method? && !node.operator_method?
235
185
  end
236
186
 
237
- def replace_condition(condition)
238
- return condition.source unless wrap_condition?(condition)
239
-
240
- if condition.call_type? && !condition.comparison_method?
241
- parenthesized_method_arguments(condition)
242
- else
243
- "(#{condition.source})"
244
- end
187
+ def add_parentheses?(node)
188
+ node.assignment? || (node.operator_keyword? && !node.and_type?) ||
189
+ (node.call_type? && node.arguments.any? && !node.parenthesized?)
245
190
  end
246
191
 
247
192
  def parenthesized_method_arguments(node)
@@ -254,10 +199,6 @@ module RuboCop
254
199
  def allow_modifier?
255
200
  cop_config['AllowModifier']
256
201
  end
257
-
258
- def outer_condition_modify_form?(node, if_branch)
259
- node.condition.source_range.begin_pos > if_branch.condition.source_range.begin_pos
260
- end
261
202
  end
262
203
  end
263
204
  end
@@ -159,6 +159,7 @@ module RuboCop
159
159
  {
160
160
  (block $#symbol_proc_receiver? $(args (arg _var)) (send (lvar _var) $_))
161
161
  (numblock $#symbol_proc_receiver? $1 (send (lvar :_1) $_))
162
+ (itblock $#symbol_proc_receiver? $_ (send (lvar :it) $_))
162
163
  }
163
164
  PATTERN
164
165
 
@@ -185,6 +186,7 @@ module RuboCop
185
186
  end
186
187
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
187
188
  alias on_numblock on_block
189
+ alias on_itblock on_block
188
190
 
189
191
  def destructuring_block_argument?(argument_node)
190
192
  argument_node.one? && argument_node.source.include?(',')
@@ -64,6 +64,7 @@ module RuboCop
64
64
  end
65
65
 
66
66
  alias on_numblock on_block
67
+ alias on_itblock on_block
67
68
 
68
69
  private
69
70
 
@@ -46,7 +46,7 @@ module RuboCop
46
46
  else
47
47
  child_index = case node.type
48
48
  when :module, :sclass then 1
49
- when :def, :class, :block, :numblock then 2
49
+ when :def, :class, :block, :numblock, :itblock then 2
50
50
  when :defs then 3
51
51
  end
52
52
 
@@ -6,8 +6,6 @@ module RuboCop
6
6
  # A Variable represents existence of a local variable.
7
7
  # This holds a variable declaration node and some states of the variable.
8
8
  class Variable
9
- extend NodePattern::Macros
10
-
11
9
  VARIABLE_DECLARATION_TYPES = (VARIABLE_ASSIGNMENT_TYPES + ARGUMENT_DECLARATION_TYPES).freeze
12
10
 
13
11
  attr_reader :name, :declaration_node, :scope, :assignments, :references, :captured_by_block
@@ -40,14 +38,11 @@ module RuboCop
40
38
 
41
39
  def mark_last_as_reassigned!(assignment)
42
40
  return if captured_by_block?
43
- return if candidate_condition?(assignment.node.parent)
41
+ return unless assignment.branch == @assignments.last&.branch
44
42
 
45
43
  @assignments.last&.reassigned!
46
44
  end
47
45
 
48
- # @!method candidate_condition?(node)
49
- def_node_matcher :candidate_condition?, '[{if case case_match when}]'
50
-
51
46
  def referenced?
52
47
  !@references.empty?
53
48
  end
@@ -54,7 +54,7 @@ module RuboCop
54
54
 
55
55
  ZERO_ARITY_SUPER_TYPE = :zsuper
56
56
 
57
- TWISTED_SCOPE_TYPES = %i[block numblock class sclass defs module].freeze
57
+ TWISTED_SCOPE_TYPES = %i[block numblock itblock class sclass defs module].freeze
58
58
  SCOPE_TYPES = (TWISTED_SCOPE_TYPES + [:def]).freeze
59
59
 
60
60
  SEND_TYPE = :send
@@ -30,7 +30,7 @@ module RuboCop
30
30
  @layout_mode = false
31
31
  end
32
32
 
33
- def format(path, text, command:)
33
+ def format(path, text, command:, prism_result: nil)
34
34
  safe_autocorrect = if command
35
35
  command == 'rubocop.formatAutocorrects'
36
36
  else
@@ -40,15 +40,15 @@ module RuboCop
40
40
  formatting_options = { autocorrect: true, safe_autocorrect: safe_autocorrect }
41
41
  formatting_options[:only] = config_only_options if @lint_mode || @layout_mode
42
42
 
43
- @runner.run(path, text, formatting_options)
43
+ @runner.run(path, text, formatting_options, prism_result: prism_result)
44
44
  @runner.formatted_source
45
45
  end
46
46
 
47
- def offenses(path, text, document_encoding = nil)
47
+ def offenses(path, text, document_encoding = nil, prism_result: nil)
48
48
  diagnostic_options = {}
49
49
  diagnostic_options[:only] = config_only_options if @lint_mode || @layout_mode
50
50
 
51
- @runner.run(path, text, diagnostic_options)
51
+ @runner.run(path, text, diagnostic_options, prism_result: prism_result)
52
52
  @runner.offenses.map do |offense|
53
53
  Diagnostic.new(
54
54
  document_encoding, offense, path, @cop_registry[offense.cop_name]&.first
@@ -41,10 +41,12 @@ module RuboCop
41
41
  end
42
42
 
43
43
  # rubocop:disable Metrics/MethodLength
44
- def run(path, contents, options)
44
+ def run(path, contents, options, prism_result: nil)
45
45
  @options = options.merge(DEFAULT_RUBOCOP_OPTIONS)
46
46
  @options[:stdin] = contents
47
47
 
48
+ @prism_result = prism_result
49
+
48
50
  @offenses = []
49
51
  @warnings = []
50
52
  @errors = []
@@ -10,7 +10,10 @@ module CopHelper
10
10
  # The minimum version Prism can parse is 3.3.
11
11
  ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : RuboCop::TargetRuby::DEFAULT_VERSION
12
12
  end
13
- let(:parser_engine) { ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym }
13
+ let(:parser_engine) do
14
+ # The maximum version Parser can parse is 3.4.
15
+ ruby_version >= 3.5 ? :parser_prism : ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym
16
+ end
14
17
  let(:rails_version) { false }
15
18
 
16
19
  before(:all) do
@@ -178,6 +178,21 @@ RSpec.shared_context 'mock console output' do
178
178
  end
179
179
  end
180
180
 
181
+ RSpec.shared_context 'mock obsoletion' do
182
+ include_context 'mock console output'
183
+
184
+ let(:obsoletion_configuration_path) { 'obsoletions.yml' }
185
+
186
+ before do
187
+ RuboCop::ConfigObsoletion.reset!
188
+ allow(RuboCop::ConfigObsoletion).to receive(:files).and_return([obsoletion_configuration_path])
189
+ end
190
+
191
+ after do
192
+ RuboCop::ConfigObsoletion.reset!
193
+ end
194
+ end
195
+
181
196
  RSpec.shared_context 'lsp' do
182
197
  before do
183
198
  RuboCop::LSP.enable
@@ -250,3 +265,8 @@ end
250
265
  RSpec.shared_context 'ruby 3.4' do
251
266
  let(:ruby_version) { 3.4 }
252
267
  end
268
+
269
+ RSpec.shared_context 'ruby 3.5' do
270
+ # Parser supports parsing Ruby <= 3.4.
271
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.5 : 3.4 }
272
+ end
@@ -16,6 +16,7 @@ RSpec.configure do |config|
16
16
  config.include_context 'lsp', :lsp
17
17
  config.include_context 'maintain registry', :restore_registry
18
18
  config.include_context 'maintain default configuration', :restore_configuration
19
+ config.include_context 'mock obsoletion', :mock_obsoletion
19
20
  config.include_context 'ruby 2.0', :ruby20
20
21
  config.include_context 'ruby 2.1', :ruby21
21
22
  config.include_context 'ruby 2.2', :ruby22
@@ -29,4 +30,5 @@ RSpec.configure do |config|
29
30
  config.include_context 'ruby 3.2', :ruby32
30
31
  config.include_context 'ruby 3.3', :ruby33
31
32
  config.include_context 'ruby 3.4', :ruby34
33
+ config.include_context 'ruby 3.5', :ruby35
32
34
  end
@@ -489,7 +489,11 @@ module RuboCop
489
489
 
490
490
  processed_source = if @options[:stdin]
491
491
  ProcessedSource.new(
492
- @options[:stdin], ruby_version, file, parser_engine: parser_engine
492
+ @options[:stdin],
493
+ ruby_version,
494
+ file,
495
+ parser_engine: parser_engine,
496
+ prism_result: @prism_result
493
497
  )
494
498
  else
495
499
  begin
@@ -4,7 +4,7 @@ module RuboCop
4
4
  # The kind of Ruby that code inspected by RuboCop is written in.
5
5
  # @api private
6
6
  class TargetRuby
7
- KNOWN_RUBIES = [2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4].freeze
7
+ KNOWN_RUBIES = [2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5].freeze
8
8
  DEFAULT_VERSION = 2.7
9
9
 
10
10
  OBSOLETE_RUBIES = {
@@ -3,13 +3,15 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.74.0'
6
+ STRING = '1.75.0'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
10
10
  'analyzing as Ruby %<target_ruby_version>s, ' \
11
11
  'running on %<ruby_engine>s %<ruby_version>s)%<server_mode>s [%<ruby_platform>s]'
12
12
 
13
+ MINIMUM_PARSABLE_PRISM_VERSION = 3.3
14
+
13
15
  CANONICAL_FEATURE_NAMES = {
14
16
  'Rspec' => 'RSpec', 'Graphql' => 'GraphQL', 'Md' => 'Markdown', 'Factory_bot' => 'FactoryBot',
15
17
  'Thread_safety' => 'ThreadSafety', 'Rspec_rails' => 'RSpecRails'
@@ -20,11 +22,14 @@ module RuboCop
20
22
 
21
23
  # NOTE: Marked as private but used by gems like standard.
22
24
  # @api private
25
+ # rubocop:disable Metrics/MethodLength
23
26
  def self.version(debug: false, env: nil)
24
27
  if debug
25
- verbose_version = format(MSG, version: STRING, parser_version: parser_version,
28
+ target_ruby_version = target_ruby_version(env)
29
+ verbose_version = format(MSG, version: STRING,
30
+ parser_version: parser_version(target_ruby_version),
26
31
  rubocop_ast_version: RuboCop::AST::Version::STRING,
27
- target_ruby_version: target_ruby_version(env),
32
+ target_ruby_version: target_ruby_version,
28
33
  ruby_engine: RUBY_ENGINE, ruby_version: RUBY_VERSION,
29
34
  server_mode: server_mode,
30
35
  ruby_platform: RUBY_PLATFORM)
@@ -41,6 +46,7 @@ module RuboCop
41
46
  STRING
42
47
  end
43
48
  end
49
+ # rubocop:enable Metrics/MethodLength
44
50
 
45
51
  # @api private
46
52
  def self.verbose(env: nil)
@@ -48,15 +54,16 @@ module RuboCop
48
54
  end
49
55
 
50
56
  # @api private
51
- def self.parser_version
57
+ def self.parser_version(target_ruby_version)
52
58
  config_path = ConfigFinder.find_config_path(Dir.pwd)
53
59
  yaml = Util.silence_warnings do
54
60
  ConfigLoader.load_yaml_configuration(config_path)
55
61
  end
62
+ parser_engine = yaml.dig('AllCops', 'ParserEngine')
63
+ parser_engine_text = ", #{parser_engine}" if parser_engine
56
64
 
57
- if yaml.dig('AllCops', 'ParserEngine') == 'parser_prism'
58
- require 'prism'
59
- "Prism #{Prism::VERSION}"
65
+ if target_ruby_version >= MINIMUM_PARSABLE_PRISM_VERSION
66
+ "Parser #{Parser::VERSION}, Prism #{Prism::VERSION}#{parser_engine_text}"
60
67
  else
61
68
  "Parser #{Parser::VERSION}"
62
69
  end
data/lib/rubocop.rb CHANGED
@@ -75,6 +75,8 @@ require_relative 'rubocop/cop/mixin/allowed_identifiers'
75
75
  require_relative 'rubocop/cop/mixin/allowed_methods'
76
76
  require_relative 'rubocop/cop/mixin/allowed_pattern'
77
77
  require_relative 'rubocop/cop/mixin/allowed_receivers'
78
+ require_relative 'rubocop/cop/mixin/forbidden_identifiers'
79
+ require_relative 'rubocop/cop/mixin/forbidden_pattern'
78
80
  require_relative 'rubocop/cop/mixin/auto_corrector' # rubocop:todo Naming/InclusiveLanguage
79
81
  require_relative 'rubocop/cop/mixin/check_assignment'
80
82
  require_relative 'rubocop/cop/mixin/check_line_breakable'
@@ -564,6 +566,7 @@ require_relative 'rubocop/cop/style/hash_as_last_array_item'
564
566
  require_relative 'rubocop/cop/style/hash_conversion'
565
567
  require_relative 'rubocop/cop/style/hash_each_methods'
566
568
  require_relative 'rubocop/cop/style/hash_except'
569
+ require_relative 'rubocop/cop/style/hash_fetch_chain'
567
570
  require_relative 'rubocop/cop/style/hash_like_case'
568
571
  require_relative 'rubocop/cop/style/hash_slice'
569
572
  require_relative 'rubocop/cop/style/hash_syntax'
@@ -583,6 +586,7 @@ require_relative 'rubocop/cop/style/inline_comment'
583
586
  require_relative 'rubocop/cop/style/invertible_unless_condition'
584
587
  require_relative 'rubocop/cop/style/ip_addresses'
585
588
  require_relative 'rubocop/cop/style/it_assignment'
589
+ require_relative 'rubocop/cop/style/it_block_parameter'
586
590
  require_relative 'rubocop/cop/style/keyword_arguments_merging'
587
591
  require_relative 'rubocop/cop/style/keyword_parameters_order'
588
592
  require_relative 'rubocop/cop/style/lambda'
@@ -16,11 +16,21 @@ module RubyLsp
16
16
  end
17
17
 
18
18
  def run_diagnostic(uri, document)
19
- @runtime.offenses(uri_to_path(uri), document.source, document.encoding)
19
+ @runtime.offenses(
20
+ uri_to_path(uri),
21
+ document.source,
22
+ document.encoding,
23
+ prism_result: prism_result(document)
24
+ )
20
25
  end
21
26
 
22
27
  def run_formatting(uri, document)
23
- @runtime.format(uri_to_path(uri), document.source, command: 'rubocop.formatAutocorrects')
28
+ @runtime.format(
29
+ uri_to_path(uri),
30
+ document.source,
31
+ command: 'rubocop.formatAutocorrects',
32
+ prism_result: prism_result(document)
33
+ )
24
34
  end
25
35
 
26
36
  def run_range_formatting(_uri, _partial_source, _base_indentation)
@@ -42,6 +52,14 @@ module RubyLsp
42
52
  uri.to_s.delete_prefix('file://')
43
53
  end
44
54
  end
55
+
56
+ def prism_result(document)
57
+ prism_result = document.parse_result
58
+
59
+ # NOTE: `prism_result` must be `Prism::ParseLexResult` compatible object.
60
+ # This is for compatibility parsed result unsupported.
61
+ prism_result.is_a?(Prism::ParseLexResult) ? prism_result : nil
62
+ end
45
63
  end
46
64
  end
47
65
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.74.0
4
+ version: 1.75.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -9,7 +9,7 @@ authors:
9
9
  - Yuji Nakayama
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2025-03-13 00:00:00.000000000 Z
12
+ date: 2025-03-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -127,7 +127,7 @@ dependencies:
127
127
  requirements:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
- version: 1.38.0
130
+ version: 1.43.0
131
131
  - - "<"
132
132
  - !ruby/object:Gem::Version
133
133
  version: '2.0'
@@ -137,7 +137,7 @@ dependencies:
137
137
  requirements:
138
138
  - - ">="
139
139
  - !ruby/object:Gem::Version
140
- version: 1.38.0
140
+ version: 1.43.0
141
141
  - - "<"
142
142
  - !ruby/object:Gem::Version
143
143
  version: '2.0'
@@ -616,6 +616,8 @@ files:
616
616
  - lib/rubocop/cop/mixin/endless_method_rewriter.rb
617
617
  - lib/rubocop/cop/mixin/enforce_superclass.rb
618
618
  - lib/rubocop/cop/mixin/first_element_line_break.rb
619
+ - lib/rubocop/cop/mixin/forbidden_identifiers.rb
620
+ - lib/rubocop/cop/mixin/forbidden_pattern.rb
619
621
  - lib/rubocop/cop/mixin/frozen_string_literal.rb
620
622
  - lib/rubocop/cop/mixin/gem_declaration.rb
621
623
  - lib/rubocop/cop/mixin/gemspec_help.rb
@@ -784,6 +786,7 @@ files:
784
786
  - lib/rubocop/cop/style/hash_conversion.rb
785
787
  - lib/rubocop/cop/style/hash_each_methods.rb
786
788
  - lib/rubocop/cop/style/hash_except.rb
789
+ - lib/rubocop/cop/style/hash_fetch_chain.rb
787
790
  - lib/rubocop/cop/style/hash_like_case.rb
788
791
  - lib/rubocop/cop/style/hash_slice.rb
789
792
  - lib/rubocop/cop/style/hash_syntax.rb
@@ -803,6 +806,7 @@ files:
803
806
  - lib/rubocop/cop/style/invertible_unless_condition.rb
804
807
  - lib/rubocop/cop/style/ip_addresses.rb
805
808
  - lib/rubocop/cop/style/it_assignment.rb
809
+ - lib/rubocop/cop/style/it_block_parameter.rb
806
810
  - lib/rubocop/cop/style/keyword_arguments_merging.rb
807
811
  - lib/rubocop/cop/style/keyword_parameters_order.rb
808
812
  - lib/rubocop/cop/style/lambda.rb
@@ -1076,9 +1080,9 @@ licenses:
1076
1080
  - MIT
1077
1081
  metadata:
1078
1082
  homepage_uri: https://rubocop.org/
1079
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.74.0
1083
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.75.0
1080
1084
  source_code_uri: https://github.com/rubocop/rubocop/
1081
- documentation_uri: https://docs.rubocop.org/rubocop/1.74/
1085
+ documentation_uri: https://docs.rubocop.org/rubocop/1.75/
1082
1086
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
1083
1087
  rubygems_mfa_required: 'true'
1084
1088
  rdoc_options: []