rubocop 1.22.1 → 1.22.2

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +2 -3
  3. data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
  4. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +30 -23
  5. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +60 -0
  6. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  7. data/lib/rubocop/cop/layout/assignment_indentation.rb +1 -1
  8. data/lib/rubocop/cop/layout/dot_position.rb +5 -7
  9. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  10. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +7 -4
  11. data/lib/rubocop/cop/layout/end_alignment.rb +1 -2
  12. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -1
  13. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -1
  14. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  15. data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
  16. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
  17. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  18. data/lib/rubocop/cop/layout/line_length.rb +1 -1
  19. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  20. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -2
  21. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  22. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
  23. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -1
  24. data/lib/rubocop/cop/layout/space_inside_parens.rb +0 -4
  25. data/lib/rubocop/cop/lint/ambiguous_range.rb +1 -1
  26. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  27. data/lib/rubocop/cop/metrics/parameter_lists.rb +5 -2
  28. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -2
  29. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  30. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
  31. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  32. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  33. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  34. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
  35. data/lib/rubocop/cop/mixin/trailing_body.rb +1 -1
  36. data/lib/rubocop/cop/security/json_load.rb +1 -1
  37. data/lib/rubocop/cop/style/commented_keyword.rb +5 -3
  38. data/lib/rubocop/cop/style/line_end_concatenation.rb +1 -1
  39. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  40. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
  41. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -0
  42. data/lib/rubocop/cop/util.rb +11 -1
  43. data/lib/rubocop/rspec/parallel_formatter.rb +90 -0
  44. data/lib/rubocop/rspec/support.rb +1 -0
  45. data/lib/rubocop/target_finder.rb +1 -1
  46. data/lib/rubocop/version.rb +1 -1
  47. metadata +8 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc48ec8bad4f5af1a464cb2d8d512975a10efd1d9c73e74ce024f798a4b200cc
4
- data.tar.gz: 65ed09a920ce2211ab2d29a26780d1b198c08d29b3af92ef783c46024e056607
3
+ metadata.gz: 55ba084f7d7ade15b0310d7ba6fcaf66b56f06a8123a0e57ddff0defb95316f9
4
+ data.tar.gz: 520b506f7d36904c76d3f9fee9075ba7550e203f06fae95c21c0fc5b54ebb00c
5
5
  SHA512:
6
- metadata.gz: 9fff6f773ae50140975bfac3f671f1657cd7da4c1df10623a7e36096e21032630fa8c41eb5a5d4eb8f07b92a48e7d99fc2b40d20da5811fc4bb0060dfc410e3b
7
- data.tar.gz: 0aa4fa740168feb2643edbeecedc723c3da44c0f2c4843a39b9593c7dda07db21d05552ae52731b1b1ddbeeb2ffe0816d2c5e7d0423caec2dc40888cbd52758f
6
+ metadata.gz: dde07235d238fc9dd8c0f67c710e06d77a9ce3b5efc24de4eda8b1885ff5540f9c1ad4197d1bb09a74e73e2cf12caaaaa684c07f86fef1350ef9731896d4e04e
7
+ data.tar.gz: 68a466978d9621ea6a269bd03ec159844d6cb6b6180085190f781d659048937b3ee9a756ab53399992415fd3128dc0d472d65dcd8f0aab8989ebdcdf369cb04c
data/config/default.yml CHANGED
@@ -262,7 +262,7 @@ Gemspec/RequiredRubyVersion:
262
262
  Description: 'Checks that `required_ruby_version` of gemspec is specified and equal to `TargetRubyVersion` of .rubocop.yml.'
263
263
  Enabled: true
264
264
  VersionAdded: '0.52'
265
- VersionChanged: '0.89'
265
+ VersionChanged: '1.22'
266
266
  Include:
267
267
  - '**/*.gemspec'
268
268
 
@@ -2754,10 +2754,9 @@ Security/JSONLoad:
2754
2754
  Reference: 'https://ruby-doc.org/stdlib-2.7.0/libdoc/json/rdoc/JSON.html#method-i-load'
2755
2755
  Enabled: true
2756
2756
  VersionAdded: '0.43'
2757
- VersionChanged: '0.44'
2757
+ VersionChanged: '1.22'
2758
2758
  # Autocorrect here will change to a method that may cause crashes depending
2759
2759
  # on the value of the argument.
2760
- AutoCorrect: false
2761
2760
  SafeAutoCorrect: false
2762
2761
 
2763
2762
  Security/MarshalLoad:
@@ -88,7 +88,7 @@ module RuboCop
88
88
  CHECKED_OPTIONS_CONFIG = 'OnlyFor'
89
89
  VERSION_SPECIFIERS_OPTION = 'version_specifiers'
90
90
  RESTRICTIVE_VERSION_SPECIFIERS_OPTION = 'restrictive_version_specifiers'
91
- RESTRICTIVE_VERSION_PATTERN = /<|~>/.freeze
91
+ RESTRICTIVE_VERSION_PATTERN = /\A\s*(?:<|~>|\d|=)/.freeze
92
92
  RESTRICT_ON_SEND = %i[gem].freeze
93
93
 
94
94
  def on_send(node)
@@ -152,8 +152,8 @@ module RuboCop
152
152
  def restrictive_version_specified_gem?(node)
153
153
  return unless version_specified_gem?(node)
154
154
 
155
- node.arguments
156
- .any? { |arg| arg&.str_type? && RESTRICTIVE_VERSION_PATTERN.match?(arg.to_s) }
155
+ node.arguments[1..-1]
156
+ .any? { |arg| arg&.str_type? && RESTRICTIVE_VERSION_PATTERN.match?(arg.value) }
157
157
  end
158
158
 
159
159
  def contains_checked_options?(node)
@@ -3,10 +3,11 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Gemspec
6
- # Checks that `required_ruby_version` of gemspec is specified and
7
- # equal to `TargetRubyVersion` of .rubocop.yml.
8
- # Thereby, RuboCop to perform static analysis working on the version
9
- # required by gemspec.
6
+ # Checks that `required_ruby_version` in a gemspec file is set to a valid
7
+ # value (non-blank) and matches `TargetRubyVersion` as set in RuboCop's
8
+ # configuration for the gem.
9
+ #
10
+ # This ensures that RuboCop is using the same Ruby version as the gem.
10
11
  #
11
12
  # @example
12
13
  # # When `TargetRubyVersion` of .rubocop.yml is `2.5`.
@@ -26,6 +27,11 @@ module RuboCop
26
27
  # spec.required_ruby_version = '>= 2.6.0'
27
28
  # end
28
29
  #
30
+ # # bad
31
+ # Gem::Specification.new do |spec|
32
+ # spec.required_ruby_version = ''
33
+ # end
34
+ #
29
35
  # # good
30
36
  # Gem::Specification.new do |spec|
31
37
  # spec.required_ruby_version = '>= 2.5.0'
@@ -49,15 +55,15 @@ module RuboCop
49
55
  class RequiredRubyVersion < Base
50
56
  include RangeHelp
51
57
 
52
- NOT_EQUAL_MSG = '`required_ruby_version` (%<required_ruby_version>s, ' \
53
- 'declared in %<gemspec_filename>s) and `TargetRubyVersion` ' \
58
+ RESTRICT_ON_SEND = %i[required_ruby_version=].freeze
59
+ NOT_EQUAL_MSG = '`required_ruby_version` and `TargetRubyVersion` ' \
54
60
  '(%<target_ruby_version>s, which may be specified in ' \
55
61
  '.rubocop.yml) should be equal.'
56
62
  MISSING_MSG = '`required_ruby_version` should be specified.'
57
63
 
58
- # @!method required_ruby_version(node)
59
- def_node_search :required_ruby_version, <<~PATTERN
60
- (send _ :required_ruby_version= $_)
64
+ # @!method required_ruby_version?(node)
65
+ def_node_search :required_ruby_version?, <<~PATTERN
66
+ (send _ :required_ruby_version= _)
61
67
  PATTERN
62
68
 
63
69
  # @!method defined_ruby_version(node)
@@ -66,27 +72,28 @@ module RuboCop
66
72
  (send (const (const nil? :Gem) :Requirement) :new $(str _))}
67
73
  PATTERN
68
74
 
69
- # rubocop:disable Metrics/AbcSize
70
75
  def on_new_investigation
71
- version_def = required_ruby_version(processed_source.ast).first
76
+ add_global_offense(MISSING_MSG) unless required_ruby_version?(processed_source.ast)
77
+ end
72
78
 
73
- if version_def
74
- ruby_version = extract_ruby_version(defined_ruby_version(version_def))
75
- return if !ruby_version || ruby_version == target_ruby_version.to_s
79
+ def on_send(node)
80
+ version_def = node.first_argument
81
+ return if dynamic_version?(version_def)
76
82
 
77
- add_offense(
78
- version_def.loc.expression,
79
- message: not_equal_message(ruby_version, target_ruby_version)
80
- )
81
- else
82
- range = source_range(processed_source.buffer, 1, 0)
83
- add_offense(range, message: MISSING_MSG)
84
- end
83
+ ruby_version = extract_ruby_version(defined_ruby_version(version_def))
84
+ return if ruby_version == target_ruby_version.to_s
85
+
86
+ add_offense(version_def, message: not_equal_message(ruby_version, target_ruby_version))
85
87
  end
86
- # rubocop:enable Metrics/AbcSize
87
88
 
88
89
  private
89
90
 
91
+ def dynamic_version?(node)
92
+ (node.send_type? && !node.receiver) ||
93
+ node.variable? ||
94
+ node.each_descendant(:send, *RuboCop::AST::Node::VARIABLES).any?
95
+ end
96
+
90
97
  def extract_ruby_version(required_ruby_version)
91
98
  return unless required_ruby_version
92
99
 
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # This cop enforces the use of `same_line?` instead of location line comparison for equality.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # node.loc.line == node.parent.loc.line
11
+ #
12
+ # # bad
13
+ # node.loc.first_line == node.parent.loc.first_line
14
+ #
15
+ # # good
16
+ # same_line?(node, node.parent)
17
+ #
18
+ class LocationLineEqualityComparison < Base
19
+ extend AutoCorrector
20
+
21
+ MSG = 'Use `%<preferred>s`.'
22
+
23
+ # @!method line_send(node)
24
+ def_node_matcher :line_send, <<~PATTERN
25
+ {
26
+ (send (send _ {:loc :source_range}) {:line :first_line})
27
+ (send _ :first_line)
28
+ }
29
+ PATTERN
30
+
31
+ # @!method location_line_equality_comparison?(node)
32
+ def_node_matcher :location_line_equality_comparison?, <<~PATTERN
33
+ (send #line_send :== #line_send)
34
+ PATTERN
35
+
36
+ def on_send(node)
37
+ return unless location_line_equality_comparison?(node)
38
+
39
+ lhs, _op, rhs = *node
40
+
41
+ lhs_receiver = extract_receiver(lhs)
42
+ rhs_receiver = extract_receiver(rhs)
43
+ preferred = "same_line?(#{lhs_receiver}, #{rhs_receiver})"
44
+
45
+ add_offense(node, message: format(MSG, preferred: preferred)) do |corrector|
46
+ corrector.replace(node, preferred)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def extract_receiver(node)
53
+ receiver = node.receiver
54
+ receiver = receiver.receiver if receiver.method?(:loc) || receiver.method?(:source_range)
55
+ receiver.source
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -3,6 +3,7 @@
3
3
  require_relative 'internal_affairs/empty_line_between_expect_offense_and_correction'
4
4
  require_relative 'internal_affairs/example_description'
5
5
  require_relative 'internal_affairs/inherit_deprecated_cop_class'
6
+ require_relative 'internal_affairs/location_line_equality_comparison'
6
7
  require_relative 'internal_affairs/method_name_equal'
7
8
  require_relative 'internal_affairs/node_destructuring'
8
9
  require_relative 'internal_affairs/node_matcher_directive'
@@ -33,7 +33,7 @@ module RuboCop
33
33
  def check_assignment(node, rhs)
34
34
  return unless rhs
35
35
  return unless node.loc.operator
36
- return if node.loc.operator.line == rhs.first_line
36
+ return if same_line?(node.loc.operator, rhs)
37
37
 
38
38
  base = display_column(leftmost_multiple_assignment(node).source_range)
39
39
  check_alignment([rhs], base + configured_indentation_width)
@@ -68,18 +68,14 @@ module RuboCop
68
68
  end
69
69
 
70
70
  def proper_dot_position?(node)
71
- selector_line = selector_range(node).line
71
+ selector_range = selector_range(node)
72
72
 
73
- # If the receiver is a HEREDOC and the selector is on the same line
74
- # then there is nothing to do
75
- return true if heredoc?(node.receiver) && node.receiver.loc.first_line == selector_line
73
+ return true if same_line?(selector_range, selector_range(node.receiver))
76
74
 
75
+ selector_line = selector_range.line
77
76
  receiver_line = receiver_end_line(node.receiver)
78
77
  dot_line = node.loc.dot.line
79
78
 
80
- # receiver and selector are on the same line
81
- return true if selector_line == receiver_line
82
-
83
79
  # don't register an offense if there is a line comment between the
84
80
  # dot and the selector otherwise, we might break the code while
85
81
  # "correcting" it (even if there is just an extra blank line, treat
@@ -124,6 +120,8 @@ module RuboCop
124
120
  end
125
121
 
126
122
  def selector_range(node)
123
+ return node unless node.call_type?
124
+
127
125
  # l.(1) has no selector, so we use the opening parenthesis instead
128
126
  node.loc.selector || node.loc.begin
129
127
  end
@@ -96,7 +96,7 @@ module RuboCop
96
96
 
97
97
  def autocorrect(corrector, node)
98
98
  previous_token = previous_token(node)
99
- range = if previous_token && node.loc.line == previous_token.line
99
+ range = if previous_token && same_line?(node, previous_token)
100
100
  range_with_surrounding_space(range: node.loc.expression, newlines: false)
101
101
  else
102
102
  range_by_whole_lines(node.loc.expression, include_final_newline: true)
@@ -65,21 +65,24 @@ module RuboCop
65
65
  MSG = 'Extra empty line detected %<location>s the `%<keyword>s`.'
66
66
 
67
67
  def on_def(node)
68
- check_body(node.body)
68
+ check_body(node.body, node.loc.line)
69
69
  end
70
70
  alias on_defs on_def
71
71
 
72
72
  def on_kwbegin(node)
73
73
  body, = *node
74
- check_body(body)
74
+ check_body(body, node.loc.line)
75
75
  end
76
76
 
77
77
  private
78
78
 
79
- def check_body(node)
80
- locations = keyword_locations(node)
79
+ def check_body(body, line_of_def_or_kwbegin)
80
+ locations = keyword_locations(body)
81
+
81
82
  locations.each do |loc|
82
83
  line = loc.line
84
+ next if line == line_of_def_or_kwbegin
85
+
83
86
  keyword = loc.source
84
87
  # below the keyword
85
88
  check_line(style, line, message('after', keyword), &:empty?)
@@ -165,8 +165,7 @@ module RuboCop
165
165
  end
166
166
 
167
167
  def alignment_node_for_variable_style(node)
168
- return node.parent if node.case_type? && node.argument? &&
169
- node.loc.line == node.parent.loc.line
168
+ return node.parent if node.case_type? && node.argument? && same_line?(node, node.parent)
170
169
 
171
170
  assignment = assignment_or_operator_method(node)
172
171
 
@@ -115,7 +115,7 @@ module RuboCop
115
115
  left_bracket = array_node.loc.begin
116
116
  first_elem = array_node.values.first
117
117
  if first_elem
118
- return if first_elem.source_range.line == left_bracket.line
118
+ return if same_line?(first_elem, left_bracket)
119
119
 
120
120
  check_first(first_elem, left_bracket, left_parenthesis, 0)
121
121
  end
@@ -116,7 +116,7 @@ module RuboCop
116
116
  first_pair = hash_node.pairs.first
117
117
 
118
118
  if first_pair
119
- return if first_pair.first_line == left_brace.line
119
+ return if same_line?(first_pair, left_brace)
120
120
 
121
121
  if separator_style?(first_pair)
122
122
  check_based_on_longest_key(hash_node, left_brace, left_parenthesis)
@@ -74,7 +74,7 @@ module RuboCop
74
74
  left_parenthesis = def_node.arguments.loc.begin
75
75
  first_elem = def_node.arguments.first
76
76
  return unless first_elem
77
- return if first_elem.source_range.line == left_parenthesis.line
77
+ return if same_line?(first_elem, left_parenthesis)
78
78
 
79
79
  check_first(first_elem, left_parenthesis, nil, 0)
80
80
  end
@@ -224,7 +224,7 @@ module RuboCop
224
224
 
225
225
  parent_loc = node.parent.loc
226
226
  selector = parent_loc.selector || parent_loc.expression
227
- selector.line == node.pairs.first.loc.line
227
+ same_line?(selector, node.pairs.first)
228
228
  end
229
229
 
230
230
  def reset!
@@ -167,7 +167,7 @@ module RuboCop
167
167
 
168
168
  end_of_outer_send = outermost_send.loc.end
169
169
 
170
- end_of_outer_send.line == end_of_last_arg_of_outer_send.line &&
170
+ same_line?(end_of_outer_send, end_of_last_arg_of_outer_send) &&
171
171
  end_of_outer_send.column == end_of_last_arg_of_outer_send.column + 1
172
172
  end
173
173
 
@@ -341,7 +341,7 @@ module RuboCop
341
341
  return true unless body_node
342
342
 
343
343
  # Don't check if expression is on same line as "then" keyword, etc.
344
- return true if body_node.loc.line == base_loc.line
344
+ return true if same_line?(body_node, base_loc)
345
345
 
346
346
  return true if starts_with_access_modifier?(body_node)
347
347
 
@@ -137,7 +137,7 @@ module RuboCop
137
137
  range = semicolon_token.pos
138
138
  end_pos = range.end_pos
139
139
  next_range = range_between(end_pos, end_pos + 1)
140
- return nil unless next_range.line == range.line
140
+ return nil unless same_line?(next_range, range)
141
141
 
142
142
  next_char = next_range.source
143
143
  return nil if /[\r\n]/.match?(next_char)
@@ -88,7 +88,7 @@ module RuboCop
88
88
  end
89
89
 
90
90
  def check_new_line_offense(node, rhs)
91
- return unless node.loc.operator.line == rhs.first_line
91
+ return unless same_line?(node.loc.operator, rhs)
92
92
 
93
93
  add_offense(node, message: NEW_LINE_OFFENSE) do |corrector|
94
94
  corrector.insert_after(node.loc.operator, "\n")
@@ -63,7 +63,7 @@ module RuboCop
63
63
  add_offense_for_expression(node, node.arguments, ARG_MSG)
64
64
  end
65
65
 
66
- return unless node.body && node.loc.begin.line == node.body.first_line
66
+ return unless node.body && same_line?(node.loc.begin, node.body)
67
67
 
68
68
  add_offense_for_expression(node, node.body, MSG)
69
69
  end
@@ -110,7 +110,7 @@ module RuboCop
110
110
 
111
111
  expr_before_body ||= node.loc.begin
112
112
 
113
- return unless expr_before_body.line == node.body.first_line
113
+ return unless same_line?(expr_before_body, node.body)
114
114
 
115
115
  autocorrect_body(corrector, node, node.body)
116
116
  end
@@ -75,7 +75,7 @@ module RuboCop
75
75
  def right_hand_side(send_node)
76
76
  dot = send_node.loc.dot
77
77
  selector = send_node.loc.selector
78
- if send_node.dot? && selector && dot.line == selector.line
78
+ if send_node.dot? && selector && same_line?(dot, selector)
79
79
  dot.join(selector)
80
80
  elsif selector
81
81
  selector
@@ -61,7 +61,7 @@ module RuboCop
61
61
  alignment_loc = alignment_location(alignment_node)
62
62
  kw_loc = node.loc.keyword
63
63
 
64
- return if alignment_loc.column == kw_loc.column || alignment_loc.line == kw_loc.line
64
+ return if alignment_loc.column == kw_loc.column || same_line?(alignment_loc, kw_loc)
65
65
 
66
66
  add_offense(
67
67
  kw_loc, message: format_message(alignment_node, alignment_loc, kw_loc)
@@ -20,7 +20,7 @@ module RuboCop
20
20
  def on_new_investigation
21
21
  processed_source.sorted_tokens.each_cons(2) do |token1, token2|
22
22
  next unless token2.comment?
23
- next unless token1.line == token2.line
23
+ next unless same_line?(token1, token2)
24
24
  next unless token1.pos.end == token2.pos.begin
25
25
 
26
26
  range = token2.pos
@@ -146,10 +146,6 @@ module RuboCop
146
146
  end
147
147
  end
148
148
 
149
- def same_line?(token1, token2)
150
- token1.line == token2.line
151
- end
152
-
153
149
  def parens?(token1, token2)
154
150
  token1.left_parens? || token2.right_parens?
155
151
  end
@@ -82,7 +82,7 @@ module RuboCop
82
82
  def acceptable?(node)
83
83
  node.begin_type? ||
84
84
  node.basic_literal? ||
85
- node.variable? || node.const_type? ||
85
+ node.variable? || node.const_type? || node.self_type? ||
86
86
  (node.call_type? && acceptable_call?(node))
87
87
  end
88
88
 
@@ -72,7 +72,7 @@ module RuboCop
72
72
  first_else = else_branch.begin_type? ? else_branch.children.first : else_branch
73
73
 
74
74
  return unless first_else
75
- return unless first_else.source_range.line == node.loc.else.line
75
+ return unless same_line?(first_else, node.loc.else)
76
76
 
77
77
  add_offense(first_else) { |corrector| autocorrect(corrector, node, first_else) }
78
78
  end
@@ -9,6 +9,9 @@ module RuboCop
9
9
  # Keyword arguments can optionally be excluded from the total count,
10
10
  # as they add less complexity than positional or optional parameters.
11
11
  #
12
+ # NOTE: Explicit block argument `&block` is not counted to prevent
13
+ # erroneous change that is avoided by making block argument implicit.
14
+ #
12
15
  # @example Max: 3
13
16
  # # good
14
17
  # def foo(a, b, c = 1)
@@ -94,9 +97,9 @@ module RuboCop
94
97
 
95
98
  def args_count(node)
96
99
  if count_keyword_args?
97
- node.children.size
100
+ node.children.count { |a| !a.blockarg_type? }
98
101
  else
99
- node.children.count { |a| !NAMED_KEYWORD_TYPES.include?(a.type) }
102
+ node.children.count { |a| !NAMED_KEYWORD_TYPES.include?(a.type) && !a.blockarg_type? }
100
103
  end
101
104
  end
102
105
 
@@ -34,8 +34,7 @@ module RuboCop
34
34
 
35
35
  def matching_ranges(end_loc, align_ranges)
36
36
  align_ranges.select do |_, range|
37
- range.line == end_loc.line ||
38
- column_offset_between(range, end_loc).zero?
37
+ same_line?(range, end_loc) || column_offset_between(range, end_loc).zero?
39
38
  end
40
39
  end
41
40
 
@@ -139,9 +139,9 @@ module RuboCop
139
139
  end
140
140
 
141
141
  def self.from_map_to_h(node, match)
142
- strip_trailing_chars = 0
143
-
144
- unless node.parent&.block_type?
142
+ if node.parent&.block_type? && node.parent.send_node == node
143
+ strip_trailing_chars = 0
144
+ else
145
145
  map_range = node.children.first.source_range
146
146
  node_range = node.source_range
147
147
  strip_trailing_chars = node_range.end_pos - map_range.end_pos
@@ -15,7 +15,7 @@ module RuboCop
15
15
  node.arguments.each do |arg|
16
16
  on_node(type, arg, :send) do |type_node|
17
17
  left_brace = type_node.loc.begin
18
- if left_brace && left_brace.line == left_parenthesis.line
18
+ if left_brace && same_line?(left_brace, left_parenthesis)
19
19
  yield type_node, left_parenthesis
20
20
  ignore_node(type_node)
21
21
  end
@@ -90,7 +90,7 @@ module RuboCop
90
90
  # This method depends on the fact that we have guarded
91
91
  # against implicit and empty literals.
92
92
  def opening_brace_on_same_line?(node)
93
- node.loc.begin.line == children(node).first.first_line
93
+ same_line?(node.loc.begin, children(node).first)
94
94
  end
95
95
 
96
96
  # This method depends on the fact that we have guarded
@@ -28,7 +28,7 @@ module RuboCop
28
28
  end
29
29
 
30
30
  def space_missing?(token1, token2)
31
- token1.line == token2.line && token2.column == token1.column + offset
31
+ same_line?(token1, token2) && token2.column == token1.column + offset
32
32
  end
33
33
 
34
34
  def space_required_before?(token)
@@ -32,7 +32,7 @@ module RuboCop
32
32
  end
33
33
 
34
34
  def space_missing?(token1, token2)
35
- token1.line == token2.line && token2.begin_pos > token1.end_pos
35
+ same_line?(token1, token2) && token2.begin_pos > token1.end_pos
36
36
  end
37
37
 
38
38
  def space_required_after?(token)
@@ -54,7 +54,7 @@ module RuboCop
54
54
  end
55
55
 
56
56
  def first_line_comment(node)
57
- comment = processed_source.find_comment { |c| c.loc.line == node.loc.line }
57
+ comment = processed_source.find_comment { |c| same_line?(c, node) }
58
58
  return unless comment
59
59
 
60
60
  comment_source = comment.loc.expression.source
@@ -10,7 +10,7 @@ module RuboCop
10
10
  end
11
11
 
12
12
  def body_on_first_line?(node, body)
13
- node.source_range.first_line == body.source_range.first_line
13
+ same_line?(node, body)
14
14
  end
15
15
 
16
16
  def first_part_of(body)
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # security issues.
8
8
  #
9
9
  # @safety
10
- # Autocorrect is disabled by default because it's potentially dangerous.
10
+ # This cop's autocorrection is unsafe because it's potentially dangerous.
11
11
  # If using a stream, like `JSON.load(open('file'))`, it will need to call
12
12
  # `#read` manually, like `JSON.parse(open('file').read)`.
13
13
  # If reading single values (rather than proper JSON objects), like
@@ -52,9 +52,11 @@ module RuboCop
52
52
  ALLOWED_COMMENTS = %w[:nodoc: :yields: rubocop:disable rubocop:todo].freeze
53
53
  ALLOWED_COMMENT_REGEXES = ALLOWED_COMMENTS.map { |c| /#\s*#{c}/ }.freeze
54
54
 
55
+ REGEXP = /(?<keyword>\S+).*#/.freeze
56
+
55
57
  def on_new_investigation
56
58
  processed_source.comments.each do |comment|
57
- next unless offensive?(comment) && (match = line(comment).match(/(?<keyword>\S+).*#/))
59
+ next unless offensive?(comment) && (match = source_line(comment).match(REGEXP))
58
60
 
59
61
  register_offense(comment, match[:keyword])
60
62
  end
@@ -76,12 +78,12 @@ module RuboCop
76
78
  end
77
79
 
78
80
  def offensive?(comment)
79
- line = line(comment)
81
+ line = source_line(comment)
80
82
  KEYWORD_REGEXES.any? { |r| r.match?(line) } &&
81
83
  ALLOWED_COMMENT_REGEXES.none? { |r| r.match?(line) }
82
84
  end
83
85
 
84
- def line(comment)
86
+ def source_line(comment)
85
87
  comment.location.expression.source_line
86
88
  end
87
89
  end
@@ -59,7 +59,7 @@ module RuboCop
59
59
 
60
60
  return unless eligible_token_set?(predecessor, operator, successor)
61
61
 
62
- return if operator.line == successor.line
62
+ return if same_line?(operator, successor)
63
63
 
64
64
  next_successor = token_after_last_string(successor, index)
65
65
 
@@ -54,7 +54,7 @@ module RuboCop
54
54
  return true if in_pattern_node.pattern.first_line != in_pattern_node.pattern.last_line
55
55
  return false unless in_pattern_node.body
56
56
 
57
- in_pattern_node.loc.line == in_pattern_node.body.loc.line
57
+ same_line?(in_pattern_node, in_pattern_node.body)
58
58
  end
59
59
  end
60
60
  end
@@ -54,7 +54,7 @@ module RuboCop
54
54
  end
55
55
  return false unless when_node.body
56
56
 
57
- when_node.loc.line == when_node.body.loc.line
57
+ same_line?(when_node, when_node.body)
58
58
  end
59
59
 
60
60
  def accept_node_type?(node)
@@ -83,6 +83,7 @@ module RuboCop
83
83
  return if block_node.body.begin_type?
84
84
  return if receiver_allowed?(block_node.receiver)
85
85
  return unless (regexp_method_send_node = extract_send_node(block_node))
86
+ return if match_predicate_without_receiver?(regexp_method_send_node)
86
87
 
87
88
  regexp = find_regexp(regexp_method_send_node)
88
89
  register_offense(node, block_node, regexp)
@@ -127,6 +128,10 @@ module RuboCop
127
128
  node.receiver
128
129
  end
129
130
  end
131
+
132
+ def match_predicate_without_receiver?(node)
133
+ node.send_type? && node.method?(:match?) && node.receiver.nil?
134
+ end
130
135
  end
131
136
  end
132
137
  end
@@ -126,8 +126,18 @@ module RuboCop
126
126
  StringInterpreter.interpret(string)
127
127
  end
128
128
 
129
+ def line(node_or_range)
130
+ if node_or_range.respond_to?(:line)
131
+ node_or_range.line
132
+ elsif node_or_range.respond_to?(:loc)
133
+ node_or_range.loc.line
134
+ end
135
+ end
136
+
129
137
  def same_line?(node1, node2)
130
- node1.respond_to?(:loc) && node2.respond_to?(:loc) && node1.loc.line == node2.loc.line
138
+ line1 = line(node1)
139
+ line2 = line(node2)
140
+ line1 && line2 && line1 == line2
131
141
  end
132
142
 
133
143
  def indent(node, offset: 0)
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec::Support.require_rspec_core 'formatters/base_text_formatter'
4
+ RSpec::Support.require_rspec_core 'formatters/console_codes'
5
+
6
+ module RuboCop
7
+ module RSpec
8
+ # RSpec formatter for use with running `rake spec` in parallel. This formatter
9
+ # removes much of the noise from RSpec so that only the important information
10
+ # will be surfaced by test-queue.
11
+ # It also adds metadata to the output in order to more easily find the text
12
+ # needed for outputting after the parallel run completes.
13
+ class ParallelFormatter < ::RSpec::Core::Formatters::BaseTextFormatter
14
+ ::RSpec::Core::Formatters.register self, :dump_pending, :dump_failures, :dump_summary
15
+
16
+ # Don't show pending tests
17
+ def dump_pending(*); end
18
+
19
+ # The BEGIN/END comments are used by `spec_runner.rake` to determine what
20
+ # output goes where in the final parallelized output, and should not be
21
+ # removed!
22
+ def dump_failures(notification)
23
+ return if notification.failure_notifications.empty?
24
+
25
+ output.puts '# FAILURES BEGIN'
26
+ notification.failure_notifications.each do |failure|
27
+ output.puts failure.fully_formatted('*', colorizer)
28
+ end
29
+ output.puts
30
+ output.puts '# FAILURES END'
31
+ end
32
+
33
+ def dump_summary(summary)
34
+ output_summary(summary)
35
+ output_rerun_commands(summary)
36
+ end
37
+
38
+ private
39
+
40
+ def colorizer
41
+ @colorizer ||= ::RSpec::Core::Formatters::ConsoleCodes
42
+ end
43
+
44
+ # The BEGIN/END comments are used by `spec_runner.rake` to determine what
45
+ # output goes where in the final parallelized output, and should not be
46
+ # removed!
47
+ def output_summary(summary)
48
+ output.puts '# SUMMARY BEGIN'
49
+ output.puts colorize_summary(summary)
50
+ output.puts '# SUMMARY END'
51
+ end
52
+
53
+ def colorize_summary(summary)
54
+ totals = totals(summary)
55
+
56
+ if summary.failure_count.positive? || summary.errors_outside_of_examples_count.positive?
57
+ colorizer.wrap(totals, ::RSpec.configuration.failure_color)
58
+ else
59
+ colorizer.wrap(totals, ::RSpec.configuration.success_color)
60
+ end
61
+ end
62
+
63
+ # The BEGIN/END comments are used by `spec_runner.rake` to determine what
64
+ # output goes where in the final parallelized output, and should not be
65
+ # removed!
66
+ def output_rerun_commands(summary)
67
+ output.puts '# RERUN BEGIN'
68
+ output.puts summary.colorized_rerun_commands.lines[3..-1].join
69
+ output.puts '# RERUN END'
70
+ end
71
+
72
+ def totals(summary)
73
+ output = pluralize(summary.example_count, 'example')
74
+ output += ", #{summary.pending_count} pending" if summary.pending_count.positive?
75
+ output += ", #{pluralize(summary.failure_count, 'failure')}"
76
+
77
+ if summary.errors_outside_of_examples_count.positive?
78
+ error_count = pluralize(summary.errors_outside_of_examples_count, 'error')
79
+ output += ", #{error_count} occurred outside of examples"
80
+ end
81
+
82
+ output
83
+ end
84
+
85
+ def pluralize(*args)
86
+ ::RSpec::Core::Formatters::Helpers.pluralize(*args)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -6,6 +6,7 @@ require_relative 'cop_helper'
6
6
  require_relative 'host_environment_simulation_helper'
7
7
  require_relative 'shared_contexts'
8
8
  require_relative 'expect_offense'
9
+ require_relative 'parallel_formatter'
9
10
 
10
11
  RSpec.configure do |config|
11
12
  config.include CopHelper
@@ -95,7 +95,7 @@ module RuboCop
95
95
 
96
96
  def wanted_dir_patterns(base_dir, exclude_pattern, flags)
97
97
  base_dir = base_dir.gsub('/{}/', '/\{}/')
98
- dirs = Dir.glob(File.join(base_dir.gsub('/**/', '/\**/'), '*/'), flags)
98
+ dirs = Dir.glob(File.join(base_dir.gsub('/*/', '/\*/').gsub('/**/', '/\**/'), '*/'), flags)
99
99
  .reject do |dir|
100
100
  next true if dir.end_with?('/./', '/../')
101
101
  next true if File.fnmatch?(exclude_pattern, dir, flags)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.22.1'
6
+ STRING = '1.22.2'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, '\
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.22.1
4
+ version: 1.22.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  - Jonas Arvidsson
9
9
  - Yuji Nakayama
10
- autorequire:
10
+ autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-10-04 00:00:00.000000000 Z
13
+ date: 2021-10-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parallel
@@ -260,6 +260,7 @@ files:
260
260
  - lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb
261
261
  - lib/rubocop/cop/internal_affairs/example_description.rb
262
262
  - lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb
263
+ - lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb
263
264
  - lib/rubocop/cop/internal_affairs/method_name_equal.rb
264
265
  - lib/rubocop/cop/internal_affairs/node_destructuring.rb
265
266
  - lib/rubocop/cop/internal_affairs/node_matcher_directive.rb
@@ -880,6 +881,7 @@ files:
880
881
  - lib/rubocop/rspec/cop_helper.rb
881
882
  - lib/rubocop/rspec/expect_offense.rb
882
883
  - lib/rubocop/rspec/host_environment_simulation_helper.rb
884
+ - lib/rubocop/rspec/parallel_formatter.rb
883
885
  - lib/rubocop/rspec/shared_contexts.rb
884
886
  - lib/rubocop/rspec/support.rb
885
887
  - lib/rubocop/runner.rb
@@ -899,7 +901,7 @@ metadata:
899
901
  source_code_uri: https://github.com/rubocop/rubocop/
900
902
  documentation_uri: https://docs.rubocop.org/rubocop/1.22/
901
903
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
902
- post_install_message:
904
+ post_install_message:
903
905
  rdoc_options: []
904
906
  require_paths:
905
907
  - lib
@@ -914,8 +916,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
914
916
  - !ruby/object:Gem::Version
915
917
  version: '0'
916
918
  requirements: []
917
- rubygems_version: 3.2.22
918
- signing_key:
919
+ rubygems_version: 3.1.2
920
+ signing_key:
919
921
  specification_version: 4
920
922
  summary: Automatic Ruby code style checking tool.
921
923
  test_files: []