rubocop 1.56.0 → 1.56.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76532b5c0c7ccf0baff454ad37e17c405e4f827a0c8323ce1a5aab0ee9e78c19
4
- data.tar.gz: fe2f7d727d5addd930a762ebe7fb34a38845164fed801744a6802ab91e6ba779
3
+ metadata.gz: 33c4c853e4bf651034a9ac3faa2f221baa77104521504824e2b4e88b349f01e0
4
+ data.tar.gz: d49422193353fc79c86b1c8cdfc3465f4abebf56bc01cd95d2c0e150c3f9747a
5
5
  SHA512:
6
- metadata.gz: ff206ac0d02084dd7014818da655f5f8d718ac1bb4bfc2f781d3c007839096a142236ded54d30084fa7b3e1689205ff7a8bc7ad7eee3ffea2d809e4610d6a1ae
7
- data.tar.gz: aaa03f29b7669ffcf6fdcb16b7da4c38a6bc62187eb91d6347e3ada22f396370b6564177eb3a040fd5ddd3eeea9cf8b3ff51943e79c3d0ad410508a75bb3177b
6
+ metadata.gz: 3bd1f56046aba375e89f62b8c954802636023539111238848c25b37a70ed95a41835198b2dd17ded64223b1f50e98f7e20f0c82aafed0381cad30f0be526b4fc
7
+ data.tar.gz: e02897c89f4869054ffea56efac2d9983f65bdce40c9254d5806effbda70561bf9c7c4161fa9a7d3269dc229d6d09b3e7c990eef10835f7ec5f2b3c55b32f6cf
@@ -5,6 +5,24 @@ module RuboCop
5
5
  module Bundler
6
6
  # A Gem group, or a set of groups, should be listed only once in a Gemfile.
7
7
  #
8
+ # For example, if the values of `source`, `git`, `platforms`, or `path`
9
+ # surrounding `group` are different, no offense will be registered:
10
+ #
11
+ # [source,ruby]
12
+ # -----
13
+ # platforms :ruby do
14
+ # group :default do
15
+ # gem 'openssl'
16
+ # end
17
+ # end
18
+ #
19
+ # platforms :jruby do
20
+ # group :default do
21
+ # gem 'jruby-openssl'
22
+ # end
23
+ # end
24
+ # -----
25
+ #
8
26
  # @example
9
27
  # # bad
10
28
  # group :development do
@@ -42,27 +60,35 @@ module RuboCop
42
60
 
43
61
  MSG = 'Gem group `%<group_name>s` already defined on line ' \
44
62
  '%<line_of_first_occurrence>d of the Gemfile.'
63
+ SOURCE_BLOCK_NAMES = %i[source git platforms path].freeze
64
+
65
+ # @!method group_declarations(node)
66
+ def_node_search :group_declarations, '(send nil? :group ...)'
45
67
 
46
68
  def on_new_investigation
47
69
  return if processed_source.blank?
48
70
 
49
71
  duplicated_group_nodes.each do |nodes|
50
72
  nodes[1..].each do |node|
51
- register_offense(node, node.arguments.map(&:value).join(', '), nodes.first.first_line)
73
+ group_name = node.arguments.map(&:source).join(', ')
74
+
75
+ register_offense(node, group_name, nodes.first.first_line)
52
76
  end
53
77
  end
54
78
  end
55
79
 
56
80
  private
57
81
 
58
- # @!method group_declarations(node)
59
- def_node_search :group_declarations, '(send nil? :group ...)'
60
-
61
82
  def duplicated_group_nodes
62
- group_declarations(processed_source.ast)
63
- .group_by { |node| node.arguments.map(&:value).map(&:to_s).sort }
64
- .values
65
- .select { |nodes| nodes.size > 1 }
83
+ group_declarations = group_declarations(processed_source.ast)
84
+ group_keys = group_declarations.group_by do |node|
85
+ source_key = find_source_key(node)
86
+ group_attributes = group_attributes(node).sort.join
87
+
88
+ "#{source_key}#{group_attributes}"
89
+ end
90
+
91
+ group_keys.values.select { |nodes| nodes.size > 1 }
66
92
  end
67
93
 
68
94
  def register_offense(node, group_name, line_of_first_occurrence)
@@ -75,6 +101,26 @@ module RuboCop
75
101
  )
76
102
  add_offense(offense_location, message: message)
77
103
  end
104
+
105
+ def find_source_key(node)
106
+ source_block = node.each_ancestor(:block).find do |block_node|
107
+ SOURCE_BLOCK_NAMES.include?(block_node.method_name)
108
+ end
109
+
110
+ return unless source_block
111
+
112
+ "#{source_block.method_name}#{source_block.send_node.first_argument&.source}"
113
+ end
114
+
115
+ def group_attributes(node)
116
+ node.arguments.map do |argument|
117
+ if argument.hash_type?
118
+ argument.pairs.map(&:source).sort.join(', ')
119
+ else
120
+ argument.value.to_s
121
+ end
122
+ end
123
+ end
78
124
  end
79
125
  end
80
126
  end
@@ -14,12 +14,15 @@ module RuboCop
14
14
  # Check for unparenthesized args' preceding and trailing whitespaces.
15
15
  remove_unparenthesized_whitespace(corrector)
16
16
 
17
- # Avoid correcting to `lambdado` by inserting whitespace
18
- # if none exists before or after the lambda arguments.
19
- insert_separating_space(corrector)
17
+ if block_node.block_type?
18
+ # Avoid correcting to `lambdado` by inserting whitespace
19
+ # if none exists before or after the lambda arguments.
20
+ insert_separating_space(corrector)
21
+
22
+ remove_arguments(corrector)
23
+ end
20
24
 
21
25
  replace_selector(corrector)
22
- remove_arguments(corrector)
23
26
 
24
27
  replace_delimiters(corrector)
25
28
 
@@ -57,7 +57,7 @@ module RuboCop
57
57
 
58
58
  def on_new_investigation
59
59
  processed_source.comments.each do |comment|
60
- next unless /\A#+[^#\s=+-]/.match?(comment.text)
60
+ next unless /\A(?!#\+\+|#--)(#+[^#\s=])/.match?(comment.text)
61
61
  next if comment.loc.line == 1 && allowed_on_first_line?(comment)
62
62
  next if doxygen_comment_style?(comment)
63
63
  next if gemfile_ruby_comment?(comment)
@@ -109,7 +109,7 @@ module RuboCop
109
109
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
110
110
 
111
111
  def comment_ranges(comments)
112
- comments.map(&:loc).map(&:expression)
112
+ comments.map(&:source_range)
113
113
  end
114
114
 
115
115
  def last_line(processed_source)
@@ -118,7 +118,9 @@ module RuboCop
118
118
  end
119
119
 
120
120
  def comment_within?(node)
121
- processed_source.comments.map(&:loc).map(&:line).any? do |comment_line_number|
121
+ comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
122
+
123
+ comment_line_numbers.any? do |comment_line_number|
122
124
  comment_line_number >= node.first_line && comment_line_number <= node.last_line
123
125
  end
124
126
  end
@@ -57,12 +57,12 @@ module RuboCop
57
57
  REMOVE_FORCE_METHODS).freeze
58
58
 
59
59
  # @!method send_exist_node(node)
60
- def_node_search :send_exist_node, <<-PATTERN
60
+ def_node_search :send_exist_node, <<~PATTERN
61
61
  $(send (const nil? {:FileTest :File :Dir :Shell}) {:exist? :exists?} ...)
62
62
  PATTERN
63
63
 
64
64
  # @!method receiver_and_method_name(node)
65
- def_node_matcher :receiver_and_method_name, <<-PATTERN
65
+ def_node_matcher :receiver_and_method_name, <<~PATTERN
66
66
  (send (const nil? $_) $_ ...)
67
67
  PATTERN
68
68
 
@@ -96,8 +96,7 @@ module RuboCop
96
96
  return_value_node = return_value_node_of_scope(scope)
97
97
  return unless assignment.meta_assignment_node.equal?(return_value_node)
98
98
 
99
- " Use `#{assignment.operator.sub(/=$/, '')}` " \
100
- "instead of `#{assignment.operator}`."
99
+ " Use `#{assignment.operator.delete_suffix('=')}` instead of `#{assignment.operator}`."
101
100
  end
102
101
 
103
102
  def similar_name_message(variable)
@@ -136,7 +136,7 @@ module RuboCop
136
136
  end
137
137
 
138
138
  def filename_good?(basename)
139
- basename = basename.sub(/^\./, '')
139
+ basename = basename.delete_prefix('.')
140
140
  basename = basename.sub(/\.[^.]+$/, '')
141
141
  # special handling for Action Pack Variants file names like
142
142
  # some_file.xlsx+mobile.axlsx
@@ -80,6 +80,7 @@ module RuboCop
80
80
  minimum_target_ruby_version 2.7
81
81
 
82
82
  FORWARDING_LVAR_TYPES = %i[splat kwsplat block_pass].freeze
83
+ ADDITIONAL_ARG_TYPES = %i[lvar arg].freeze
83
84
 
84
85
  FORWARDING_MSG = 'Use shorthand syntax `...` for arguments forwarding.'
85
86
  ARGS_MSG = 'Use anonymous positional arguments forwarding (`*`).'
@@ -212,7 +213,7 @@ module RuboCop
212
213
  end
213
214
 
214
215
  def arguments_range(node, first_node)
215
- arguments = node.arguments
216
+ arguments = node.arguments.reject { |arg| ADDITIONAL_ARG_TYPES.include?(arg.type) }
216
217
 
217
218
  start_node = first_node || arguments.first
218
219
 
@@ -279,7 +280,7 @@ module RuboCop
279
280
 
280
281
  if can_forward_all?
281
282
  :all
282
- elsif target_ruby_version >= 3.2
283
+ else
283
284
  :rest_or_kwrest
284
285
  end
285
286
  end
@@ -332,9 +333,9 @@ module RuboCop
332
333
  end
333
334
 
334
335
  def no_post_splat_args?
335
- splat_index = arguments.index(forwarded_rest_arg)
336
- arg_after_splat = arguments[splat_index + 1]
336
+ return true unless (splat_index = arguments.index(forwarded_rest_arg))
337
337
 
338
+ arg_after_splat = arguments[splat_index + 1]
338
339
  [nil, :hash, :block_pass].include?(arg_after_splat&.type)
339
340
  end
340
341
 
@@ -74,7 +74,7 @@ module RuboCop
74
74
  new_arguments =
75
75
  node.arguments.map do |arg|
76
76
  if arg.percent_literal?
77
- arg.children.map(&:value).map(&:inspect)
77
+ arg.children.map { |child| child.value.inspect }
78
78
  else
79
79
  arg.children.map(&:source)
80
80
  end
@@ -146,7 +146,9 @@ module RuboCop
146
146
  end
147
147
 
148
148
  def call_in_match_pattern?(node)
149
- node.parent&.match_pattern_type?
149
+ return false unless (parent = node.parent)
150
+
151
+ parent.match_pattern_type? || parent.match_pattern_p_type?
150
152
  end
151
153
 
152
154
  def hash_literal_in_arguments?(node)
@@ -45,7 +45,7 @@ module RuboCop
45
45
  MSG = 'Avoid using `OpenStruct`; use `Struct`, `Hash`, a class or test doubles instead.'
46
46
 
47
47
  # @!method uses_open_struct?(node)
48
- def_node_matcher :uses_open_struct?, <<-PATTERN
48
+ def_node_matcher :uses_open_struct?, <<~PATTERN
49
49
  (const {nil? (cbase)} :OpenStruct)
50
50
  PATTERN
51
51
 
@@ -98,7 +98,9 @@ module RuboCop
98
98
  end
99
99
 
100
100
  def like_method_argument_parentheses?(node)
101
- node.send_type? && node.arguments.one? && !node.parenthesized? &&
101
+ return false if !node.send_type? && !node.super_type? && !node.yield_type?
102
+
103
+ node.arguments.one? && !node.parenthesized? &&
102
104
  !node.arithmetic_operation? && node.first_argument.begin_type?
103
105
  end
104
106
 
@@ -75,6 +75,11 @@ module RuboCop
75
75
  add_offense(offense_branch) do |corrector|
76
76
  assignment_value = opposite_branch ? opposite_branch.source : 'nil'
77
77
  replacement = "#{assignment_value} #{keyword} #{if_node.condition.source}"
78
+ if opposite_branch.respond_to?(:heredoc?) && opposite_branch.heredoc?
79
+ replacement += opposite_branch.loc.heredoc_end.with(
80
+ begin_pos: opposite_branch.source_range.end_pos
81
+ ).source
82
+ end
78
83
 
79
84
  corrector.replace(if_node, replacement)
80
85
  end
@@ -69,6 +69,8 @@ module RuboCop
69
69
 
70
70
  def complex_content?(node)
71
71
  node.children.any? do |sym|
72
+ return false if DELIMITERS.include?(sym.source)
73
+
72
74
  content = *sym
73
75
  content = content.map { |c| c.is_a?(AST::Node) ? c.source : c }.join
74
76
  content_without_delimiter_pairs = content.gsub(/(\[[^\s\[\]]*\])|(\([^\s\(\)]*\))/, '')
@@ -6,27 +6,40 @@ module RuboCop
6
6
  # Helper to abstract complexity of building range pairs
7
7
  # with octal escape reconstruction (needed for regexp_parser < 2.7).
8
8
  class RegexpRanges
9
- attr_reader :compound_token, :root
9
+ attr_reader :root
10
10
 
11
11
  def initialize(root)
12
12
  @root = root
13
13
  @compound_token = []
14
+ @pairs = []
15
+ @populated = false
16
+ end
17
+
18
+ def compound_token
19
+ populate_all unless @populated
20
+
21
+ @compound_token
14
22
  end
15
23
 
16
24
  def pairs
17
- unless @pairs
18
- @pairs = []
19
- populate(root)
20
- end
25
+ populate_all unless @populated
26
+
27
+ @pairs
28
+ end
29
+
30
+ private
31
+
32
+ def populate_all
33
+ populate(@root)
21
34
 
22
35
  # If either bound is a compound the first one is an escape
23
36
  # and that's all we need to work with.
24
37
  # If there are any cops that wanted to operate on the compound
25
38
  # expression we could wrap it with a facade class.
26
- @pairs.map { |pair| pair.map(&:first) }
27
- end
39
+ @pairs.map! { |pair| pair.map(&:first) }
28
40
 
29
- private
41
+ @populated = true
42
+ end
30
43
 
31
44
  def populate(expr)
32
45
  expressions = expr.expressions.to_a
@@ -35,15 +48,15 @@ module RuboCop
35
48
  current = expressions.shift
36
49
 
37
50
  if escaped_octal?(current)
38
- compound_token << current
39
- compound_token.concat(pop_octal_digits(expressions))
51
+ @compound_token << current
52
+ @compound_token.concat(pop_octal_digits(expressions))
40
53
  # If we have all the digits we can discard.
41
54
  end
42
55
 
43
56
  next unless current.type == :set
44
57
 
45
58
  process_set(expressions, current)
46
- compound_token.clear
59
+ @compound_token.clear
47
60
  end
48
61
  end
49
62
 
@@ -64,8 +77,8 @@ module RuboCop
64
77
 
65
78
  def compose_range(expressions, current)
66
79
  range_start, range_end = current.expressions
67
- range_start = if compound_token.size.between?(1, 2) && octal_digit?(range_start.text)
68
- compound_token.dup << range_start
80
+ range_start = if @compound_token.size.between?(1, 2) && octal_digit?(range_start.text)
81
+ @compound_token.dup << range_start
69
82
  else
70
83
  [range_start]
71
84
  end
@@ -155,9 +155,11 @@ module RuboCop
155
155
  (send _ :required_ruby_version= $_)
156
156
  PATTERN
157
157
 
158
- # @!method gem_requirement?(node)
159
- def_node_matcher :gem_requirement?, <<~PATTERN
160
- (send (const(const _ :Gem):Requirement) :new $str)
158
+ # @!method gem_requirement_versions(node)
159
+ def_node_matcher :gem_requirement_versions, <<~PATTERN
160
+ (send (const(const _ :Gem):Requirement) :new
161
+ {$str+ | (send $str :freeze)+ | (array $str+) | (array (send $str :freeze)+)}
162
+ )
161
163
  PATTERN
162
164
 
163
165
  def name
@@ -194,10 +196,12 @@ module RuboCop
194
196
  end
195
197
 
196
198
  def version_from_right_hand_side(right_hand_side)
199
+ gem_requirement_versions = gem_requirement_versions(right_hand_side)
200
+
197
201
  if right_hand_side.array_type?
198
202
  version_from_array(right_hand_side)
199
- elsif gem_requirement?(right_hand_side)
200
- right_hand_side.children.last.value
203
+ elsif gem_requirement_versions
204
+ gem_requirement_versions.map(&:value)
201
205
  else
202
206
  right_hand_side.value
203
207
  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.56.0'
6
+ STRING = '1.56.1'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
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.56.0
4
+ version: 1.56.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2023-08-09 00:00:00.000000000 Z
13
+ date: 2023-08-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: base64
@@ -196,9 +196,9 @@ dependencies:
196
196
  - - "<"
197
197
  - !ruby/object:Gem::Version
198
198
  version: '3.0'
199
- description: |2
200
- RuboCop is a Ruby code style checking and code formatting tool.
201
- It aims to enforce the community-driven Ruby Style Guide.
199
+ description: |
200
+ RuboCop is a Ruby code style checking and code formatting tool.
201
+ It aims to enforce the community-driven Ruby Style Guide.
202
202
  email: rubocop@googlegroups.com
203
203
  executables:
204
204
  - rubocop