rubocop 1.79.0 → 1.79.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5919779b3b5bcc30656adbfd28f00fc821327d6ecf4abff825eea32150319aef
4
- data.tar.gz: d94231324f779e1f99469dc032b762825a761bc0a3ed85e44f34ae3fdc4ea78a
3
+ metadata.gz: dc8a905ea4a217b5c7a43390a0777107217ce2a1a14b325e5367a4dbafb6cf1d
4
+ data.tar.gz: 01e471a4471ee7ac1151db63ace049693be1a8008955722b1028843034c00e82
5
5
  SHA512:
6
- metadata.gz: fff3036cd812063f449fc41c2e1b536c6735fd1e85742692a5f710769a619b2eab1c5800180744b748ab3ba37fe1f4e6c64dd8edf9d4a9abc2f426bf89b47091
7
- data.tar.gz: d174e5c8d47b012a591bd59292411c2e23927d378c88362bf1f77427b6bf92230f1f95417e7f2ec44454d78bbfe41bf40fd7e7c07add9047beda6655d307e7ed
6
+ metadata.gz: 21c054eb2cb142bbf75ed66598252f114e1b759d4a699f6319f804ed761cdf68b51ad75a96c02475b5bafdf5341198684c3764aadd4ccdf256d0509bf207ea0c
7
+ data.tar.gz: 11c7240440560b7ec024b469634ce3621a0e10363083f5ce2a8bd8d8af9ff5e5c1814a87d320297109534e0c7654c20837f9d4963e9c322e24595d907042f285
data/README.md CHANGED
@@ -6,8 +6,6 @@
6
6
  [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)
7
7
  [![Gem Version](https://badge.fury.io/rb/rubocop.svg)](https://badge.fury.io/rb/rubocop)
8
8
  [![CI](https://github.com/rubocop/rubocop/actions/workflows/rubocop.yml/badge.svg)](https://github.com/rubocop/rubocop/actions/workflows/rubocop.yml)
9
- [![Test Coverage](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/test_coverage)](https://codeclimate.com/github/rubocop/rubocop/test_coverage)
10
- [![Maintainability](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/maintainability)](https://codeclimate.com/github/rubocop/rubocop/maintainability)
11
9
  [![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://discord.gg/wJjWvGRDmm)
12
10
 
13
11
  > Role models are important. <br/>
@@ -39,7 +39,7 @@ module RuboCop
39
39
 
40
40
  def on_send(node)
41
41
  return if node.receiver
42
- return if node.parent&.send_type?
42
+ return if node.parent&.type?(:send, :any_block)
43
43
 
44
44
  return if next_line_empty_or_enable_directive_comment?(node.last_line)
45
45
 
@@ -54,6 +54,18 @@ module RuboCop
54
54
  end
55
55
  end
56
56
 
57
+ def on_or(node)
58
+ return unless node.lhs.falsey_literal?
59
+
60
+ add_offense(node.lhs) do |corrector|
61
+ # Don't autocorrect `'foo' && return` because having `return` as
62
+ # the leftmost node can lead to a void value expression syntax error.
63
+ next if node.rhs.type?(:return, :break, :next)
64
+
65
+ corrector.replace(node, node.rhs.source)
66
+ end
67
+ end
68
+
57
69
  def on_if(node)
58
70
  cond = condition(node)
59
71
 
@@ -53,6 +53,12 @@ module RuboCop
53
53
  # # good
54
54
  # Struct.new(:foo_bar)
55
55
  #
56
+ # # bad
57
+ # alias_method :fooBar, :some_method
58
+ #
59
+ # # good
60
+ # alias_method :foo_bar, :some_method
61
+ #
56
62
  # @example EnforcedStyle: camelCase
57
63
  # # bad
58
64
  # def foo_bar; end
@@ -74,6 +80,12 @@ module RuboCop
74
80
  # # good
75
81
  # Struct.new(:fooBar)
76
82
  #
83
+ # # bad
84
+ # alias_method :foo_bar, :some_method
85
+ #
86
+ # # good
87
+ # alias_method :fooBar, :some_method
88
+ #
77
89
  # @example ForbiddenIdentifiers: ['def', 'super']
78
90
  # # bad
79
91
  # def def; end
@@ -116,6 +128,8 @@ module RuboCop
116
128
  handle_new_struct(node)
117
129
  elsif define_data?(node)
118
130
  handle_define_data(node)
131
+ elsif node.method?(:alias_method)
132
+ handle_alias_method(node)
119
133
  else
120
134
  handle_attr_accessor(node)
121
135
  end
@@ -132,6 +146,10 @@ module RuboCop
132
146
  end
133
147
  alias on_defs on_def
134
148
 
149
+ def on_alias(node)
150
+ handle_method_name(node.new_identifier, node.new_identifier.value)
151
+ end
152
+
135
153
  private
136
154
 
137
155
  def handle_define_method(node)
@@ -153,6 +171,13 @@ module RuboCop
153
171
  end
154
172
  end
155
173
 
174
+ def handle_alias_method(node)
175
+ return unless node.arguments.size == 2
176
+ return unless node.first_argument.type?(:str, :sym)
177
+
178
+ handle_method_name(node.first_argument, node.first_argument.value)
179
+ end
180
+
156
181
  def handle_attr_accessor(node)
157
182
  return unless (attrs = node.attribute_accessor?)
158
183
 
@@ -146,7 +146,6 @@ module RuboCop
146
146
  minimum_target_ruby_version 2.7
147
147
 
148
148
  FORWARDING_LVAR_TYPES = %i[splat kwsplat block_pass].freeze
149
- ADDITIONAL_ARG_TYPES = %i[lvar arg optarg].freeze
150
149
 
151
150
  FORWARDING_MSG = 'Use shorthand syntax `...` for arguments forwarding.'
152
151
  ARGS_MSG = 'Use anonymous positional arguments forwarding (`*`).'
@@ -198,9 +197,9 @@ module RuboCop
198
197
  send_classifications.all? { |_, c, _, _| all_classifications.include?(c) }
199
198
  end
200
199
 
201
- # rubocop:disable Metrics/MethodLength
200
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
202
201
  def add_forward_all_offenses(node, send_classifications, forwardable_args)
203
- _rest_arg, _kwrest_arg, block_arg = *forwardable_args
202
+ rest_arg, kwrest_arg, block_arg = *forwardable_args
204
203
  registered_block_arg_offense = false
205
204
 
206
205
  send_classifications.each do |send_node, c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
@@ -212,16 +211,20 @@ module RuboCop
212
211
  registered_block_arg_offense = true
213
212
  break
214
213
  else
215
- register_forward_all_offense(send_node, send_node, forward_rest)
214
+ first_arg = forward_rest || forward_kwrest || forward_all_first_argument(send_node)
215
+ register_forward_all_offense(send_node, send_node, first_arg)
216
216
  end
217
217
  end
218
218
 
219
219
  return if registered_block_arg_offense
220
220
 
221
- rest_arg, _kwrest_arg, _block_arg = *forwardable_args
222
- register_forward_all_offense(node, node.arguments, rest_arg)
221
+ register_forward_all_offense(node, node.arguments, rest_arg || kwrest_arg)
222
+ end
223
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
224
+
225
+ def forward_all_first_argument(node)
226
+ node.arguments.reverse_each.find(&:forwarded_restarg_type?)
223
227
  end
224
- # rubocop:enable Metrics/MethodLength
225
228
 
226
229
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
227
230
  def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
@@ -361,18 +364,9 @@ module RuboCop
361
364
  end
362
365
  end
363
366
 
364
- # rubocop:disable Metrics/AbcSize
365
367
  def arguments_range(node, first_node)
366
- arguments = node.arguments.reject do |arg|
367
- next true if ADDITIONAL_ARG_TYPES.include?(arg.type) || arg.variable? || arg.call_type?
368
-
369
- arg.literal? && arg.each_descendant(:kwsplat).none?
370
- end
371
-
372
- start_node = first_node || arguments.first
373
- start_node.source_range.begin.join(arguments.last.source_range.end)
368
+ first_node.source_range.begin.join(node.last_argument.source_range.end)
374
369
  end
375
- # rubocop:enable Metrics/AbcSize
376
370
 
377
371
  def allow_only_rest_arguments?
378
372
  cop_config.fetch('AllowOnlyRestArgument', true)
@@ -6,9 +6,11 @@ module RuboCop
6
6
  # In Ruby 3.1, `Array#intersect?` has been added.
7
7
  #
8
8
  # This cop identifies places where:
9
+ #
9
10
  # * `(array1 & array2).any?`
10
11
  # * `(array1.intersection(array2)).any?`
11
12
  # * `array1.any? { |elem| array2.member?(elem) }`
13
+ #
12
14
  # can be replaced with `array1.intersect?(array2)`.
13
15
  #
14
16
  # `array1.intersect?(array2)` is faster and more readable.
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'tsort'
4
-
5
3
  module RuboCop
6
4
  module Cop
7
5
  module Style
@@ -94,15 +92,9 @@ module RuboCop
94
92
  def find_valid_order(left_elements, right_elements)
95
93
  # arrange left_elements in an order such that no corresponding right
96
94
  # element refers to a left element earlier in the sequence
97
- # this can be done using an algorithm called a "topological sort"
98
- # fortunately for us, Ruby's stdlib contains an implementation
99
95
  assignments = left_elements.zip(right_elements)
100
96
 
101
- begin
102
- AssignmentSorter.new(assignments).tsort
103
- rescue TSort::Cyclic
104
- nil
105
- end
97
+ AssignmentSorter.new(assignments).tsort
106
98
  end
107
99
 
108
100
  # Converts (send nil :something) nodes to (send (:self) :something).
@@ -117,10 +109,9 @@ module RuboCop
117
109
  # @!method implicit_self_getter?(node)
118
110
  def_node_matcher :implicit_self_getter?, '(send nil? $_)'
119
111
 
120
- # Helper class necessitated by silly design of TSort prior to Ruby 2.1
121
- # Newer versions have a better API, but that doesn't help us
112
+ # Topologically sorts the assignments with Kahn's algorithm.
113
+ # https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm
122
114
  class AssignmentSorter
123
- include TSort
124
115
  extend RuboCop::NodePattern::Macros
125
116
 
126
117
  # @!method var_name(node)
@@ -136,21 +127,39 @@ module RuboCop
136
127
  @assignments = assignments
137
128
  end
138
129
 
139
- def tsort_each_node(...)
140
- @assignments.each(...)
130
+ def tsort
131
+ dependencies = @assignments.to_h do |assignment|
132
+ [assignment, dependencies_for_assignment(assignment)]
133
+ end
134
+ result = []
135
+
136
+ while (matched_node, = dependencies.find { |_node, edges| edges.empty? })
137
+ dependencies.delete(matched_node)
138
+ result.push(matched_node)
139
+
140
+ dependencies.each do |node, edges|
141
+ dependencies[node].delete(matched_node) if edges.include?(matched_node)
142
+ end
143
+ end
144
+ # Cyclic dependency
145
+ return nil if dependencies.any?
146
+
147
+ result
141
148
  end
142
149
 
143
- def tsort_each_child(assignment)
144
- # yield all the assignments which must come after `assignment`
145
- # (due to dependencies on the previous value of the assigned var)
150
+ # Returns all the assignments which must come after `assignment`
151
+ # (due to dependencies on the previous value of the assigned var)
152
+ def dependencies_for_assignment(assignment)
146
153
  my_lhs, _my_rhs = *assignment
147
154
 
148
- @assignments.each do |other|
149
- _other_lhs, other_rhs = *other
155
+ @assignments.filter_map do |other|
156
+ # Exclude self, there are no dependencies in cases such as `a, b = a, b`.
157
+ next if other == assignment
150
158
 
159
+ _other_lhs, other_rhs = *other
151
160
  next unless dependency?(my_lhs, other_rhs)
152
161
 
153
- yield other
162
+ other
154
163
  end
155
164
  end
156
165
 
@@ -169,7 +169,7 @@ module RuboCop
169
169
  end
170
170
  return 'an interpolated expression' if interpolation?(begin_node)
171
171
  return 'a method argument' if argument_of_parenthesized_method_call?(begin_node, node)
172
- return 'a one-line rescue' if !begin_node.parent&.call_type? && node.rescue_type?
172
+ return 'a one-line rescue' if oneline_rescue_parentheses_required?(begin_node, node)
173
173
 
174
174
  return if begin_node.chained?
175
175
 
@@ -201,6 +201,14 @@ module RuboCop
201
201
  parent.call_type? && parent.parenthesized? && parent.receiver != begin_node
202
202
  end
203
203
 
204
+ def oneline_rescue_parentheses_required?(begin_node, node)
205
+ return false unless node.rescue_type?
206
+ return false unless (parent = begin_node.parent)
207
+ return false if parent.if_type? && parent.ternary?
208
+
209
+ !parent.type?(:call, :array, :pair)
210
+ end
211
+
204
212
  def method_call_parentheses_required?(node)
205
213
  return false unless node.call_type?
206
214
 
@@ -354,9 +354,11 @@ module RuboCop
354
354
  end
355
355
 
356
356
  def reference_assignments(loop_assignments, node)
357
- # If inside a case statement, mark all as referenced.
357
+ # If inside a branching statement, mark all as referenced.
358
358
  # Otherwise, mark only the last assignment as referenced.
359
- if loop_assignments.first.node.each_ancestor(:case, :case_match).any?
359
+ # Note that `rescue` must be considered as branching because of
360
+ # the `retry` keyword.
361
+ if loop_assignments.first.node.each_ancestor(:if, :rescue, :case, :case_match).any?
360
362
  loop_assignments.each { |assignment| assignment.reference!(node) }
361
363
  else
362
364
  loop_assignments.last&.reference!(node)
@@ -194,7 +194,7 @@ module RuboCop
194
194
  return []
195
195
  end
196
196
 
197
- new_text = @server.format(remove_file_protocol_from(file_uri), text, command: command)
197
+ new_text = @server.format(convert_file_uri_to_path(file_uri), text, command: command)
198
198
 
199
199
  return [] if new_text == text
200
200
 
@@ -214,13 +214,13 @@ module RuboCop
214
214
  method: 'textDocument/publishDiagnostics',
215
215
  params: {
216
216
  uri: file_uri,
217
- diagnostics: @server.offenses(remove_file_protocol_from(file_uri), text)
217
+ diagnostics: @server.offenses(convert_file_uri_to_path(file_uri), text)
218
218
  }
219
219
  }
220
220
  end
221
221
 
222
- def remove_file_protocol_from(uri)
223
- uri.delete_prefix('file://')
222
+ def convert_file_uri_to_path(uri)
223
+ URI.decode_www_form_component(uri.delete_prefix('file://'))
224
224
  end
225
225
  end
226
226
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.79.0'
6
+ STRING = '1.79.1'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.79.0
4
+ version: 1.79.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  - Jonas Arvidsson
9
9
  - Yuji Nakayama
10
+ autorequire:
10
11
  bindir: exe
11
12
  cert_chain: []
12
- date: 2025-07-24 00:00:00.000000000 Z
13
+ date: 2025-07-31 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: json
@@ -155,20 +156,6 @@ dependencies:
155
156
  - - "~>"
156
157
  - !ruby/object:Gem::Version
157
158
  version: '1.7'
158
- - !ruby/object:Gem::Dependency
159
- name: tsort
160
- requirement: !ruby/object:Gem::Requirement
161
- requirements:
162
- - - ">="
163
- - !ruby/object:Gem::Version
164
- version: 0.2.0
165
- type: :runtime
166
- prerelease: false
167
- version_requirements: !ruby/object:Gem::Requirement
168
- requirements:
169
- - - ">="
170
- - !ruby/object:Gem::Version
171
- version: 0.2.0
172
159
  - !ruby/object:Gem::Dependency
173
160
  name: unicode-display_width
174
161
  requirement: !ruby/object:Gem::Requirement
@@ -1104,11 +1091,12 @@ licenses:
1104
1091
  - MIT
1105
1092
  metadata:
1106
1093
  homepage_uri: https://rubocop.org/
1107
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.79.0
1094
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.79.1
1108
1095
  source_code_uri: https://github.com/rubocop/rubocop/
1109
1096
  documentation_uri: https://docs.rubocop.org/rubocop/1.79/
1110
1097
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
1111
1098
  rubygems_mfa_required: 'true'
1099
+ post_install_message:
1112
1100
  rdoc_options: []
1113
1101
  require_paths:
1114
1102
  - lib
@@ -1123,7 +1111,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1123
1111
  - !ruby/object:Gem::Version
1124
1112
  version: '0'
1125
1113
  requirements: []
1126
- rubygems_version: 3.6.2
1114
+ rubygems_version: 3.3.7
1115
+ signing_key:
1127
1116
  specification_version: 4
1128
1117
  summary: Automatic Ruby code style checking tool.
1129
1118
  test_files: []