rubocop 1.69.1 → 1.69.2

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: 8ab30572529c057731f5ebd7548808a1aa9f588f75a45ec0d41ecec2dbbc8015
4
- data.tar.gz: 9beff10b3b9361a9ffc58c0da4920c9c7c7d1caa09e813ea96c46cd7f01683a4
3
+ metadata.gz: 45af4a986637b8c3dacb16d942870c2138501ae834e79c0875b81bbf09644b54
4
+ data.tar.gz: 65961fc4cb25730ad9528201e22a82427def59f6ad5f048cd01a0ca89a437c3c
5
5
  SHA512:
6
- metadata.gz: a1fdca8813de85e849ba3ff5266c589b74986984192247fc53c541c81475ae672788a663444070fc5428cbfd1024de7cccc9ac7924fe0dab8e138069b3f6b8f7
7
- data.tar.gz: 7896834ccaa34e897da918b457b7ab2c738e21b474536144ddbaf71af2d5ae1e829fdeb699701323f6c67d85cb7b2fb1adcc21f3fde1683cb6273387cd390ba2
6
+ metadata.gz: aa6eb7a2cbf39d99cbda0faff3dfe690a61e9665847c21669bc9a005f9ac316e9404a8babc8cadf7f033bf82afcf317c8c503ede2306e8b3a8c211abaa878cb9
7
+ data.tar.gz: 126f20d27ebf2e0098d0a1039230fea4178d2a196693db8c75326a7f3fdc797b1f030af3d116f2d74f69bb70cc033372ede6836962b2c47632a9ecf4f524dd56
@@ -49,17 +49,31 @@ module RuboCop
49
49
  private
50
50
 
51
51
  def disable_offense(offense_range)
52
- range = surrounding_heredoc(offense_range) ||
53
- surrounding_percent_array(offense_range) ||
54
- string_continuation(offense_range)
52
+ unbreakable_range = multiline_ranges(offense_range)&.find do |range|
53
+ range_overlaps_offense?(offense_range, range)
54
+ end
55
55
 
56
- if range
57
- disable_offense_before_and_after(range_by_lines(range))
56
+ if unbreakable_range
57
+ disable_offense_before_and_after(range_by_lines(unbreakable_range))
58
58
  else
59
59
  disable_offense_with_eol_or_surround_comment(offense_range)
60
60
  end
61
61
  end
62
62
 
63
+ def multiline_ranges(offense_range)
64
+ return if offense_range.empty?
65
+
66
+ processed_source.ast.each_node.filter_map do |node|
67
+ if surrounding_heredoc?(node)
68
+ heredoc_range(node)
69
+ elsif string_continuation?(node)
70
+ range_by_lines(node.source_range)
71
+ elsif surrounding_percent_array?(node) || multiline_string?(node)
72
+ node.source_range
73
+ end
74
+ end
75
+ end
76
+
63
77
  def disable_offense_with_eol_or_surround_comment(range)
64
78
  eol_comment = " # rubocop:todo #{cop_name}"
65
79
  needed_line_length = (range.source_line + eol_comment).length
@@ -71,47 +85,30 @@ module RuboCop
71
85
  end
72
86
  end
73
87
 
74
- def surrounding_heredoc(offense_range)
75
- # The empty offense range is an edge case that can be reached from the Lint/Syntax cop.
76
- return nil if offense_range.empty?
77
-
78
- heredoc_nodes = processed_source.ast.each_descendant.select do |node|
79
- node.respond_to?(:heredoc?) && node.heredoc?
80
- end
81
- heredoc_nodes.map { |node| node.source_range.join(node.loc.heredoc_end) }
82
- .find { |range| range.contains?(offense_range) }
88
+ def range_overlaps_offense?(offense_range, range)
89
+ offense_range.begin_pos > range.begin_pos && range.overlaps?(offense_range)
83
90
  end
84
91
 
85
- def surrounding_percent_array(offense_range)
86
- return nil if offense_range.empty?
87
-
88
- percent_array = processed_source.ast.each_descendant.select do |node|
89
- node.array_type? && node.percent_literal?
90
- end
91
-
92
- percent_array.map(&:source_range).find do |range|
93
- range_overlaps_offense?(offense_range, range)
94
- end
92
+ def surrounding_heredoc?(node)
93
+ node.type?(:str, :dstr, :xstr) && node.heredoc?
95
94
  end
96
95
 
97
- def string_continuation(offense_range)
98
- return nil if offense_range.empty?
99
-
100
- string_continuation_nodes = processed_source.ast.each_descendant.filter_map do |node|
101
- range_by_lines(node.source_range) if string_continuation?(node)
102
- end
103
-
104
- string_continuation_nodes.find { |range| range_overlaps_offense?(offense_range, range) }
96
+ def heredoc_range(node)
97
+ node.source_range.join(node.loc.heredoc_end)
105
98
  end
106
99
 
107
- def range_overlaps_offense?(offense_range, range)
108
- offense_range.begin_pos > range.begin_pos && range.overlaps?(offense_range)
100
+ def surrounding_percent_array?(node)
101
+ node.array_type? && node.percent_literal?
109
102
  end
110
103
 
111
104
  def string_continuation?(node)
112
105
  (node.str_type? || node.dstr_type? || node.xstr_type?) && node.source.match?(/\\\s*$/)
113
106
  end
114
107
 
108
+ def multiline_string?(node)
109
+ node.dstr_type? && node.multiline?
110
+ end
111
+
115
112
  def range_of_first_line(range)
116
113
  begin_of_first_line = range.begin_pos - range.column
117
114
  end_of_first_line = begin_of_first_line + range.source_line.length
@@ -73,7 +73,7 @@ module RuboCop
73
73
  end
74
74
 
75
75
  def within_conditional?(node, conditional_node)
76
- conditional_node.branches.any? do |branch|
76
+ conditional_node.branches.compact.any? do |branch|
77
77
  branch == node || branch.child_nodes.include?(node)
78
78
  end
79
79
  end
@@ -17,6 +17,7 @@ module RuboCop
17
17
  extend AutoCorrector
18
18
 
19
19
  MSG = 'Use `%<prefer>s`.'
20
+ PREFERRED_METHOD = 'operator_keyword?'
20
21
 
21
22
  # @!method and_or_type(node)
22
23
  def_node_matcher :and_or_type, <<~PATTERN
@@ -33,8 +34,9 @@ module RuboCop
33
34
  def on_or(node)
34
35
  return unless (lhs, rhs = and_or_type(node))
35
36
 
36
- offense = lhs.receiver.source_range.join(rhs.source_range.end)
37
- prefer = "#{lhs.receiver.source}.operator_keyword?"
37
+ begin_range = lhs.receiver&.source_range || lhs.loc.selector
38
+ offense = begin_range.join(rhs.source_range.end)
39
+ prefer = lhs.receiver ? "#{lhs.receiver.source}.#{PREFERRED_METHOD}" : PREFERRED_METHOD
38
40
 
39
41
  add_offense(offense, message: format(MSG, prefer: prefer)) do |corrector|
40
42
  corrector.replace(offense, prefer)
@@ -8,19 +8,18 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  #
11
- # # good
12
- #
11
+ # # bad
13
12
  # begin
13
+ #
14
14
  # # ...
15
- # end
16
15
  #
17
- # # bad
16
+ # end
18
17
  #
18
+ # # good
19
19
  # begin
20
- #
21
20
  # # ...
22
- #
23
21
  # end
22
+ #
24
23
  class EmptyLinesAroundBeginBody < Base
25
24
  include EmptyLinesAroundBody
26
25
  extend AutoCorrector
@@ -51,6 +51,15 @@ module RuboCop
51
51
  private_constant :LINE_1_ENDING, :LINE_2_BEGINNING,
52
52
  :LEADING_STYLE_OFFENSE, :TRAILING_STYLE_OFFENSE
53
53
 
54
+ # When both cops are activated and run in the same iteration of the correction loop,
55
+ # `Style/StringLiterals` undoes the moving of spaces that
56
+ # `Layout/LineContinuationLeadingSpace` performs. This is because `Style/StringLiterals`
57
+ # takes the original string content and transforms it, rather than just modifying the
58
+ # delimiters, in order to handle escaping for quotes within the string.
59
+ def self.autocorrect_incompatible_with
60
+ [Style::StringLiterals]
61
+ end
62
+
54
63
  def on_dstr(node)
55
64
  # Quick check if we possibly have line continuations.
56
65
  return unless node.source.include?('\\')
@@ -129,9 +138,9 @@ module RuboCop
129
138
 
130
139
  def message(_range)
131
140
  if enforced_style_leading?
132
- 'Move trailing spaces to the start of next line.'
141
+ 'Move trailing spaces to the start of the next line.'
133
142
  else
134
- 'Move leading spaces to the end of previous line.'
143
+ 'Move leading spaces to the end of the previous line.'
135
144
  end
136
145
  end
137
146
 
@@ -78,6 +78,7 @@ module RuboCop
78
78
  PATTERN
79
79
 
80
80
  def on_send(node)
81
+ return unless node.receiver
81
82
  return unless if_node_child?(node)
82
83
  return if explicit_not_force?(node)
83
84
  return unless (exist_node = send_exist_node(node.parent).first)
@@ -58,7 +58,7 @@ module RuboCop
58
58
  Regexp::Parser.parse(text.value)&.each_expression do |expr|
59
59
  detect_offenses(text, expr)
60
60
  end
61
- rescue Regexp::Parser::ParserError
61
+ rescue Regexp::Parser::Error
62
62
  # Upon encountering an invalid regular expression,
63
63
  # we aim to proceed and identify any remaining potential offenses.
64
64
  end
@@ -51,15 +51,7 @@ module RuboCop
51
51
  end
52
52
 
53
53
  def on_casgn(node)
54
- parent = node.parent
55
-
56
- block_node = if parent&.assignment?
57
- parent.expression
58
- elsif parent&.parent&.masgn_type?
59
- parent.parent.expression
60
- else
61
- node.expression
62
- end
54
+ block_node = node.expression || find_expression_within_parent(node.parent)
63
55
 
64
56
  return unless block_node.respond_to?(:class_definition?) && block_node.class_definition?
65
57
 
@@ -71,6 +63,14 @@ module RuboCop
71
63
  def message(length, max_length)
72
64
  format('Class has too many lines. [%<length>d/%<max>d]', length: length, max: max_length)
73
65
  end
66
+
67
+ def find_expression_within_parent(parent)
68
+ if parent&.assignment?
69
+ parent.expression
70
+ elsif parent&.parent&.masgn_type?
71
+ parent.parent.expression
72
+ end
73
+ end
74
74
  end
75
75
  end
76
76
  end
@@ -16,6 +16,8 @@ module RuboCop
16
16
  end
17
17
 
18
18
  def comments_in_range(node)
19
+ return [] unless node.source_range
20
+
19
21
  start_line = node.source_range.line
20
22
  end_line = find_end_line(node)
21
23
 
@@ -74,7 +76,8 @@ module RuboCop
74
76
  end
75
77
  elsif node.block_type? || node.numblock_type?
76
78
  node.loc.end.line
77
- elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node)
79
+ elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node) &&
80
+ next_sibling.source_range
78
81
  next_sibling.loc.line
79
82
  elsif (parent = node.parent)
80
83
  if parent.loc.respond_to?(:end) && parent.loc.end
@@ -37,12 +37,13 @@ module RuboCop
37
37
  last_uri_match = match_uris(line).last
38
38
  return nil unless last_uri_match
39
39
 
40
- begin_position, end_position = last_uri_match.offset(0).map do |pos|
41
- pos + indentation_difference(line)
42
- end
43
-
40
+ begin_position, end_position = last_uri_match.offset(0)
44
41
  end_position = extend_uri_end_position(line, end_position)
45
42
 
43
+ line_indentation_difference = indentation_difference(line)
44
+ begin_position += line_indentation_difference
45
+ end_position += line_indentation_difference
46
+
46
47
  return nil if begin_position < max_line_length && end_position < max_line_length
47
48
 
48
49
  begin_position...end_position
@@ -62,7 +62,7 @@ module RuboCop
62
62
  next unless index
63
63
  next if indent && indent != index
64
64
 
65
- return yield(range, line)
65
+ return yield(range, line, lineno + 1)
66
66
  end
67
67
  false
68
68
  end
@@ -74,12 +74,12 @@ module RuboCop
74
74
  end.map(&:line)
75
75
  end
76
76
 
77
- def aligned_token?(range, line)
78
- aligned_words?(range, line) || aligned_assignment?(range, line)
77
+ def aligned_token?(range, line, lineno)
78
+ aligned_words?(range, line) || aligned_assignment?(range, lineno)
79
79
  end
80
80
 
81
- def aligned_operator?(range, line)
82
- aligned_identical?(range, line) || aligned_assignment?(range, line)
81
+ def aligned_operator?(range, line, lineno)
82
+ aligned_identical?(range, line) || aligned_assignment?(range, lineno)
83
83
  end
84
84
 
85
85
  def aligned_words?(range, line)
@@ -90,16 +90,33 @@ module RuboCop
90
90
  token == line[left_edge, token.length]
91
91
  end
92
92
 
93
- def aligned_assignment?(range, line)
94
- (range.source[-1] == '=' && line[range.last_column - 1] == '=') ||
95
- aligned_with_append_operator?(range, line)
93
+ def aligned_assignment?(range, lineno)
94
+ # Check that assignment is aligned with a previous assignment operator
95
+ # ie. an equals sign, an operator assignment, or an append operator (`<<`)
96
+ line_range = processed_source.buffer.line_range(lineno)
97
+ return false unless line_range
98
+
99
+ # Find the specific token to avoid matching up to operators inside strings
100
+ assignment_token = processed_source.tokens_within(line_range).detect do |token|
101
+ token.equal_sign? || token.type == :tLSHFT
102
+ end
103
+
104
+ aligned_with_preceding_assignment?(range, assignment_token) ||
105
+ aligned_with_append_operator?(range, assignment_token)
106
+ end
107
+
108
+ def aligned_with_preceding_assignment?(range, token)
109
+ return false unless token
110
+
111
+ range.source[-1] == '=' && range.last_column == token.pos.last_column
96
112
  end
97
113
 
98
- def aligned_with_append_operator?(range, line)
99
- last_column = range.last_column
114
+ def aligned_with_append_operator?(range, token)
115
+ return false unless token
100
116
 
101
- (range.source == '<<' && line[last_column - 1] == '=') ||
102
- (range.source[-1] == '=' && line[(last_column - 2)..(last_column - 1)] == '<<')
117
+ ((range.source == '<<' && token.equal_sign?) ||
118
+ (range.source[-1] == '=' && token.type == :tLSHFT)) &&
119
+ token && range.last_column == token.pos.last_column
103
120
  end
104
121
 
105
122
  def aligned_identical?(range, line)
@@ -116,12 +133,9 @@ module RuboCop
116
133
  relevant_indent = processed_source.line_indentation(relevant_line_number)
117
134
 
118
135
  return :none if relevant_indent < token_line_indent
136
+ return :none unless processed_source.lines[relevant_line_number - 1]
119
137
 
120
- assignment_line = processed_source.lines[relevant_line_number - 1]
121
-
122
- return :none unless assignment_line
123
-
124
- aligned_assignment?(token.pos, assignment_line) ? :yes : :no
138
+ aligned_assignment?(token.pos, relevant_line_number) ? :yes : :no
125
139
  end
126
140
 
127
141
  def assignment_lines
@@ -154,7 +154,7 @@ module RuboCop
154
154
  end
155
155
 
156
156
  def variable_name(node)
157
- node.exception_variable&.name
157
+ node.exception_variable.name if node.exception_variable.respond_to?(:name)
158
158
  end
159
159
 
160
160
  def message(node)
@@ -183,7 +183,8 @@ module RuboCop
183
183
  def on_send(node)
184
184
  return unless node.arguments?
185
185
  return if node.parenthesized?
186
- return if node.operator_method? || node.assignment_method?
186
+ return if node.assignment_method?
187
+ return if single_argument_operator_method?(node)
187
188
 
188
189
  node.arguments.each do |arg|
189
190
  get_blocks(arg) do |block|
@@ -501,6 +502,12 @@ module RuboCop
501
502
  # `begin`...`end` when changing `do-end` to `{}`.
502
503
  block_node.each_child_node(:rescue, :ensure).any? && !block_node.single_line?
503
504
  end
505
+
506
+ def single_argument_operator_method?(node)
507
+ return false unless node.operator_method?
508
+
509
+ node.arguments.one? && node.first_argument.block_type?
510
+ end
504
511
  end
505
512
  end
506
513
  end
@@ -41,8 +41,14 @@ module RuboCop
41
41
  return unless (receiver = node.receiver)
42
42
  return unless (regexp = exact_regexp_match(node))
43
43
 
44
- parsed_regexp = Regexp::Parser.parse(regexp)
45
- return unless exact_match_pattern?(parsed_regexp)
44
+ parsed_regexp = begin
45
+ Regexp::Parser.parse(regexp)
46
+ rescue Regexp::Parser::Error
47
+ # Upon encountering an invalid regular expression,
48
+ # we aim to proceed and identify any remaining potential offenses.
49
+ end
50
+
51
+ return unless parsed_regexp && exact_match_pattern?(parsed_regexp)
46
52
 
47
53
  prefer = "#{receiver.source} #{new_method(node)} '#{parsed_regexp[1].text}'"
48
54
 
@@ -8,6 +8,12 @@ module RuboCop
8
8
  # Only looks for full string matches, substrings within a longer string are not
9
9
  # considered.
10
10
  #
11
+ # However, only files that use the string `'/dev/null'` are targeted for detection.
12
+ # This is because the string `'NUL'` is not limited to the null device.
13
+ # This behavior results in false negatives when the `'/dev/null'` string is not used,
14
+ # but it is a trade-off to avoid false positives. `NULL:`
15
+ # Unlike `'NUL'`, `'NUL:'` is regarded as something like `C:` and is always detected.
16
+ #
11
17
  # NOTE: Uses inside arrays and hashes are ignored.
12
18
  #
13
19
  # @safety
@@ -42,11 +48,21 @@ module RuboCop
42
48
  REGEXP = %r{\A(/dev/null|NUL:?)\z}i.freeze
43
49
  MSG = 'Use `File::NULL` instead of `%<source>s`.'
44
50
 
51
+ def on_new_investigation
52
+ return unless (ast = processed_source.ast)
53
+
54
+ @contain_dev_null_string_in_file = ast.each_descendant(:str).any? do |str|
55
+ content = str.str_content
56
+
57
+ valid_string?(content) && content.downcase == '/dev/null' # rubocop:disable Style/FileNull
58
+ end
59
+ end
60
+
45
61
  def on_str(node)
46
62
  value = node.value
47
-
48
- return if invalid_string?(value)
63
+ return unless valid_string?(value)
49
64
  return if acceptable?(node)
65
+ return if value.downcase == 'nul' && !@contain_dev_null_string_in_file # rubocop:disable Style/FileNull
50
66
  return unless REGEXP.match?(value)
51
67
 
52
68
  add_offense(node, message: format(MSG, source: value)) do |corrector|
@@ -56,8 +72,8 @@ module RuboCop
56
72
 
57
73
  private
58
74
 
59
- def invalid_string?(value)
60
- value.empty? || !value.valid_encoding?
75
+ def valid_string?(value)
76
+ !value.empty? && value.valid_encoding?
61
77
  end
62
78
 
63
79
  def acceptable?(node)
@@ -43,7 +43,7 @@ module RuboCop
43
43
  template = if require_newline?(node)
44
44
  MSG_NEWLINE
45
45
  elsif node.else_branch&.if_type? || node.else_branch&.begin_type? ||
46
- use_block_in_branches?(node)
46
+ use_masgn_or_block_in_branches?(node)
47
47
  MSG_IF_ELSE
48
48
  else
49
49
  MSG_TERNARY
@@ -53,7 +53,7 @@ module RuboCop
53
53
  end
54
54
 
55
55
  def autocorrect(corrector, node)
56
- if require_newline?(node) || use_block_in_branches?(node)
56
+ if require_newline?(node) || use_masgn_or_block_in_branches?(node)
57
57
  corrector.replace(node.loc.begin, "\n")
58
58
  else
59
59
  corrector.replace(node, replacement(node))
@@ -64,8 +64,10 @@ module RuboCop
64
64
  node.branches.compact.any?(&:begin_type?) || use_return_with_argument?(node)
65
65
  end
66
66
 
67
- def use_block_in_branches?(node)
68
- node.branches.compact.any? { |branch| branch.block_type? || branch.numblock_type? }
67
+ def use_masgn_or_block_in_branches?(node)
68
+ node.branches.compact.any? do |branch|
69
+ branch.masgn_type? || branch.block_type? || branch.numblock_type?
70
+ end
69
71
  end
70
72
 
71
73
  def use_return_with_argument?(node)
@@ -107,7 +107,7 @@ module RuboCop
107
107
  end
108
108
 
109
109
  def variable_in_mass_assignment?(variable_name, node)
110
- node.assignments.any? { |n| n.name == variable_name }
110
+ node.assignments.reject(&:send_type?).any? { |n| n.name == variable_name }
111
111
  end
112
112
 
113
113
  def offense_range(node)
@@ -63,11 +63,13 @@ module RuboCop
63
63
  return unless (variable, values = find_offending_var(node))
64
64
  return if values.size < comparisons_threshold
65
65
 
66
- add_offense(node) do |corrector|
66
+ range = offense_range(values)
67
+
68
+ add_offense(range) do |corrector|
67
69
  elements = values.map(&:source).join(', ')
68
70
  prefer_method = "[#{elements}].include?(#{variable_name(variable)})"
69
71
 
70
- corrector.replace(node, prefer_method)
72
+ corrector.replace(range, prefer_method)
71
73
  end
72
74
  end
73
75
 
@@ -106,6 +108,10 @@ module RuboCop
106
108
  end
107
109
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
108
110
 
111
+ def offense_range(values)
112
+ values.first.parent.source_range.begin.join(values.last.parent.source_range.end)
113
+ end
114
+
109
115
  def variable_name(node)
110
116
  node.children[0]
111
117
  end
@@ -73,7 +73,7 @@ module RuboCop
73
73
  LINE_CONTINUATION_PATTERN = /(\\\n)/.freeze
74
74
  ALLOWED_STRING_TOKENS = %i[tSTRING tSTRING_CONTENT].freeze
75
75
  ARGUMENT_TYPES = %i[
76
- kFALSE kNIL kSELF kTRUE tCONSTANT tCVAR tFLOAT tGVAR tIDENTIFIER tINTEGER tIVAR
76
+ kDEF kFALSE kNIL kSELF kTRUE tCONSTANT tCVAR tFLOAT tGVAR tIDENTIFIER tINTEGER tIVAR
77
77
  tLBRACK tLCURLY tLPAREN_ARG tSTRING tSTRING_BEG tSYMBOL tXSTRING_BEG
78
78
  ].freeze
79
79
  ARGUMENT_TAKING_FLOW_TOKEN_TYPES = %i[tIDENTIFIER kRETURN kBREAK kNEXT kYIELD].freeze
@@ -129,11 +129,10 @@ module RuboCop
129
129
  return true unless (node = find_node_for_line(range.last_line))
130
130
  return false if argument_newline?(node)
131
131
 
132
- source = node.source
133
- while (node = node.parent)
134
- source = node.source
135
- end
136
- parse(source.gsub("\\\n", "\n")).valid_syntax?
132
+ # Check if source is still valid without the continuation
133
+ source = processed_source.raw_source.dup
134
+ source[range.begin_pos, range.length] = "\n"
135
+ parse(source).valid_syntax?
137
136
  end
138
137
 
139
138
  def inspect_end_of_ruby_code_line_continuation
@@ -80,13 +80,13 @@ module RuboCop
80
80
 
81
81
  # Expose the `frozen_string_literal` value coerced to a boolean if possible.
82
82
  #
83
- # @return [Boolean] if value is `true` or `false`
83
+ # @return [Boolean] if value is `true` or `false` in any case
84
84
  # @return [nil] if frozen_string_literal comment isn't found
85
85
  # @return [String] if comment is found but isn't true or false
86
86
  def frozen_string_literal
87
87
  return unless (setting = extract_frozen_string_literal)
88
88
 
89
- case setting
89
+ case setting.downcase
90
90
  when 'true' then true
91
91
  when 'false' then false
92
92
  else
@@ -283,7 +283,7 @@ module RuboCop
283
283
  # is the only text in the comment.
284
284
  #
285
285
  # Case-insensitive and dashes/underscores are acceptable.
286
- # @see https://github.com/ruby/ruby/blob/78b95b4/parse.y#L7134-L7138
286
+ # @see https://github.com/ruby/ruby/blob/78b95b49f8/parse.y#L7134-L7138
287
287
  def extract_frozen_string_literal
288
288
  extract(/\A\s*#\s*#{KEYWORDS[:frozen_string_literal]}:\s*#{TOKEN}\s*\z/io)
289
289
  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.69.1'
6
+ STRING = '1.69.2'
7
7
 
8
8
  MSG = '%<version>s (using %<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.69.1
4
+ version: 1.69.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: 2024-12-03 00:00:00.000000000 Z
13
+ date: 2024-12-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -1035,12 +1035,12 @@ licenses:
1035
1035
  - MIT
1036
1036
  metadata:
1037
1037
  homepage_uri: https://rubocop.org/
1038
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.69.1
1038
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.69.2
1039
1039
  source_code_uri: https://github.com/rubocop/rubocop/
1040
1040
  documentation_uri: https://docs.rubocop.org/rubocop/1.69/
1041
1041
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
1042
1042
  rubygems_mfa_required: 'true'
1043
- post_install_message:
1043
+ post_install_message:
1044
1044
  rdoc_options: []
1045
1045
  require_paths:
1046
1046
  - lib
@@ -1055,8 +1055,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1055
1055
  - !ruby/object:Gem::Version
1056
1056
  version: '0'
1057
1057
  requirements: []
1058
- rubygems_version: 3.3.7
1059
- signing_key:
1058
+ rubygems_version: 3.4.22
1059
+ signing_key:
1060
1060
  specification_version: 4
1061
1061
  summary: Automatic Ruby code style checking tool.
1062
1062
  test_files: []