rubocop 1.51.0 → 1.54.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.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +62 -3
  4. data/lib/rubocop/cli/command/lsp.rb +19 -0
  5. data/lib/rubocop/cli.rb +3 -0
  6. data/lib/rubocop/config_loader_resolver.rb +4 -3
  7. data/lib/rubocop/cop/base.rb +1 -1
  8. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  9. data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
  10. data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
  11. data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
  12. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  13. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
  14. data/lib/rubocop/cop/layout/class_structure.rb +7 -0
  15. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  16. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +27 -4
  17. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  18. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  19. data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
  20. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  21. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  22. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  23. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -1
  24. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  25. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -1
  26. data/lib/rubocop/cop/lint/debugger.rb +9 -5
  27. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  28. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
  29. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -2
  30. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
  31. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  32. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +1 -2
  33. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  34. data/lib/rubocop/cop/lint/missing_super.rb +34 -5
  35. data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
  36. data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
  37. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  38. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  39. data/lib/rubocop/cop/lint/redundant_require_statement.rb +8 -3
  40. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  41. data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
  42. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  43. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  44. data/lib/rubocop/cop/lint/useless_assignment.rb +4 -1
  45. data/lib/rubocop/cop/lint/void.rb +12 -18
  46. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  47. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +30 -2
  48. data/lib/rubocop/cop/migration/department_name.rb +2 -2
  49. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  50. data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
  51. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  52. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  53. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  54. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  55. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +3 -3
  56. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  57. data/lib/rubocop/cop/style/accessor_grouping.rb +5 -1
  58. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  59. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  60. data/lib/rubocop/cop/style/block_delimiters.rb +3 -3
  61. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  62. data/lib/rubocop/cop/style/class_equality_comparison.rb +17 -39
  63. data/lib/rubocop/cop/style/collection_compact.rb +6 -0
  64. data/lib/rubocop/cop/style/conditional_assignment.rb +3 -1
  65. data/lib/rubocop/cop/style/dir.rb +1 -1
  66. data/lib/rubocop/cop/style/dir_empty.rb +8 -14
  67. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  68. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  69. data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -2
  70. data/lib/rubocop/cop/style/file_read.rb +2 -2
  71. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -22
  72. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  73. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  74. data/lib/rubocop/cop/style/identical_conditional_branches.rb +6 -2
  75. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  76. data/lib/rubocop/cop/style/invertible_unless_condition.rb +1 -1
  77. data/lib/rubocop/cop/style/lambda.rb +3 -3
  78. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +3 -4
  79. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  80. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  81. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  82. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  83. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  84. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
  85. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
  86. data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
  87. data/lib/rubocop/cop/style/redundant_line_continuation.rb +2 -2
  88. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
  89. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
  90. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  91. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
  92. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +3 -1
  93. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  94. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -0
  95. data/lib/rubocop/cop/style/require_order.rb +2 -1
  96. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  97. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +81 -0
  98. data/lib/rubocop/cop/style/select_by_regexp.rb +15 -5
  99. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  100. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  101. data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
  102. data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
  103. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  104. data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
  105. data/lib/rubocop/cop/util.rb +1 -1
  106. data/lib/rubocop/cop/utils/regexp_ranges.rb +100 -0
  107. data/lib/rubocop/cop/variable_force/assignment.rb +43 -4
  108. data/lib/rubocop/cop/variable_force.rb +1 -0
  109. data/lib/rubocop/cops_documentation_generator.rb +1 -1
  110. data/lib/rubocop/ext/regexp_parser.rb +4 -1
  111. data/lib/rubocop/lsp/logger.rb +22 -0
  112. data/lib/rubocop/lsp/routes.rb +231 -0
  113. data/lib/rubocop/lsp/runtime.rb +82 -0
  114. data/lib/rubocop/lsp/server.rb +66 -0
  115. data/lib/rubocop/lsp/severity.rb +27 -0
  116. data/lib/rubocop/options.rb +11 -1
  117. data/lib/rubocop/server/client_command/exec.rb +2 -1
  118. data/lib/rubocop/version.rb +8 -4
  119. data/lib/rubocop.rb +12 -0
  120. metadata +36 -5
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks if `return` or `return nil` is used in predicate method definitions.
7
+ #
8
+ # @safety
9
+ # Autocorrection is marked as unsafe because the change of the return value
10
+ # from `nil` to `false` could potentially lead to incompatibility issues.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # def foo?
15
+ # return if condition
16
+ #
17
+ # do_something?
18
+ # end
19
+ #
20
+ # # bad
21
+ # def foo?
22
+ # return nil if condition
23
+ #
24
+ # do_something?
25
+ # end
26
+ #
27
+ # # good
28
+ # def foo?
29
+ # return false if condition
30
+ #
31
+ # do_something?
32
+ # end
33
+ #
34
+ # @example AllowedMethod: ['foo?']
35
+ # # good
36
+ # def foo?
37
+ # return if condition
38
+ #
39
+ # do_something?
40
+ # end
41
+ #
42
+ # @example AllowedPattern: [/foo/]
43
+ # # good
44
+ # def foo?
45
+ # return if condition
46
+ #
47
+ # do_something?
48
+ # end
49
+ #
50
+ class ReturnNilInPredicateMethodDefinition < Base
51
+ extend AutoCorrector
52
+ include AllowedMethods
53
+ include AllowedPattern
54
+
55
+ MSG = 'Use `return false` instead of `%<prefer>s` in the predicate method.'
56
+
57
+ # @!method return_nil?(node)
58
+ def_node_matcher :return_nil?, <<~PATTERN
59
+ {(return) (return (nil))}
60
+ PATTERN
61
+
62
+ def on_def(node)
63
+ return unless node.predicate_method?
64
+ return if allowed_method?(node.method_name) || matches_allowed_pattern?(node.method_name)
65
+ return unless (body = node.body)
66
+
67
+ body.each_descendant(:return) do |return_node|
68
+ next unless return_nil?(return_node)
69
+
70
+ message = format(MSG, prefer: return_node.source)
71
+
72
+ add_offense(return_node, message: message) do |corrector|
73
+ corrector.replace(return_node, 'return false')
74
+ end
75
+ end
76
+ end
77
+ alias on_defs on_def
78
+ end
79
+ end
80
+ end
81
+ end
@@ -84,6 +84,7 @@ module RuboCop
84
84
  }
85
85
  PATTERN
86
86
 
87
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
87
88
  def on_send(node)
88
89
  return unless (block_node = node.block_node)
89
90
  return if block_node.body&.begin_type?
@@ -91,11 +92,14 @@ module RuboCop
91
92
  return unless (regexp_method_send_node = extract_send_node(block_node))
92
93
  return if match_predicate_without_receiver?(regexp_method_send_node)
93
94
 
94
- opposite = opposite?(regexp_method_send_node)
95
+ replacement = replacement(regexp_method_send_node, node)
96
+ return if target_ruby_version <= 2.2 && replacement == 'grep_v'
97
+
95
98
  regexp = find_regexp(regexp_method_send_node, block_node)
96
99
 
97
- register_offense(node, block_node, regexp, opposite)
100
+ register_offense(node, block_node, regexp, replacement)
98
101
  end
102
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
99
103
 
100
104
  private
101
105
 
@@ -105,9 +109,15 @@ module RuboCop
105
109
  node.hash_type? || creates_hash?(node) || env_const?(node)
106
110
  end
107
111
 
108
- def register_offense(node, block_node, regexp, opposite)
109
- method_name = node.method_name.to_sym
110
- replacement = opposite ? OPPOSITE_REPLACEMENTS[method_name] : REPLACEMENTS[method_name]
112
+ def replacement(regexp_method_send_node, node)
113
+ opposite = opposite?(regexp_method_send_node)
114
+
115
+ method_name = node.method_name
116
+
117
+ opposite ? OPPOSITE_REPLACEMENTS[method_name] : REPLACEMENTS[method_name]
118
+ end
119
+
120
+ def register_offense(node, block_node, regexp, replacement)
111
121
  message = format(MSG, replacement: replacement, original_method: node.method_name)
112
122
 
113
123
  add_offense(block_node, message: message) do |corrector|
@@ -198,7 +198,7 @@ module RuboCop
198
198
  end
199
199
 
200
200
  def command_or_kernel_call?(name, node)
201
- return unless node.method?(name)
201
+ return false unless node.method?(name)
202
202
 
203
203
  node.command?(name) || kernel_call?(node, name)
204
204
  end
@@ -135,7 +135,7 @@ module RuboCop
135
135
 
136
136
  def disallow_endless_method_style?
137
137
  endless_method_config = config.for_cop('Style/EndlessMethod')
138
- return false unless endless_method_config['Enabled']
138
+ return true unless endless_method_config['Enabled']
139
139
 
140
140
  endless_method_config['EnforcedStyle'] == 'disallow'
141
141
  end
@@ -186,7 +186,9 @@ module RuboCop
186
186
  begin_pos = condition.first_argument.source_range.begin_pos
187
187
  return if end_pos > begin_pos
188
188
 
189
- corrector.replace(range_between(end_pos, begin_pos), '(')
189
+ range = range_between(end_pos, begin_pos)
190
+ corrector.remove(range)
191
+ corrector.insert_after(range, '(')
190
192
  corrector.insert_after(condition.last_argument, ')')
191
193
  end
192
194
 
@@ -3,8 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- #
7
- # This cop looks for uses of Perl-style global variables.
6
+ # Looks for uses of Perl-style global variables.
8
7
  # Correcting to global variables in the 'English' library
9
8
  # will add a require statement to the top of the file if
10
9
  # enabled by RequireEnglish config.
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for the use of `YAML.load`, `YAML.safe_load`, and `YAML.parse` with
7
+ # `File.read` argument.
8
+ #
9
+ # NOTE: `YAML.safe_load_file` was introduced in Ruby 3.0.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ # YAML.load(File.read(path))
15
+ # YAML.parse(File.read(path))
16
+ #
17
+ # # good
18
+ # YAML.load_file(path)
19
+ # YAML.parse_file(path)
20
+ #
21
+ # # bad
22
+ # YAML.safe_load(File.read(path)) # Ruby 3.0 and newer
23
+ #
24
+ # # good
25
+ # YAML.safe_load_file(path) # Ruby 3.0 and newer
26
+ #
27
+ class YAMLFileRead < Base
28
+ extend AutoCorrector
29
+
30
+ MSG = 'Use `%<prefer>s` instead.'
31
+ RESTRICT_ON_SEND = %i[load safe_load parse].freeze
32
+
33
+ # @!method yaml_file_read?(node)
34
+ def_node_matcher :yaml_file_read?, <<~PATTERN
35
+ (send
36
+ (const {cbase nil?} :YAML) _
37
+ (send
38
+ (const {cbase nil?} :File) :read $_) $...)
39
+ PATTERN
40
+
41
+ def on_send(node)
42
+ return if node.method?(:safe_load) && target_ruby_version <= 2.7
43
+ return unless (file_path, rest_arguments = yaml_file_read?(node))
44
+
45
+ range = offense_range(node)
46
+ rest_arguments = if rest_arguments.empty?
47
+ ''
48
+ else
49
+ ", #{rest_arguments.map(&:source).join(', ')}"
50
+ end
51
+ prefer = "#{node.method_name}_file(#{file_path.source}#{rest_arguments})"
52
+
53
+ add_offense(range, message: format(MSG, prefer: prefer)) do |corrector|
54
+ corrector.replace(range, prefer)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def offense_range(node)
61
+ node.loc.selector.join(node.source_range.end)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -118,16 +118,18 @@ module RuboCop
118
118
  node.comparison_method? && !noncommutative_operator?(node)
119
119
  end
120
120
 
121
+ # rubocop:disable Metrics/CyclomaticComplexity
121
122
  def valid_yoda?(node)
122
- lhs = node.receiver
123
- rhs = node.first_argument
123
+ return true unless (rhs = node.first_argument)
124
124
 
125
+ lhs = node.receiver
125
126
  return true if (constant_portion?(lhs) && constant_portion?(rhs)) ||
126
127
  (!constant_portion?(lhs) && !constant_portion?(rhs)) ||
127
128
  interpolation?(lhs)
128
129
 
129
130
  enforce_yoda? ? constant_portion?(lhs) : constant_portion?(rhs)
130
131
  end
132
+ # rubocop:enable Metrics/CyclomaticComplexity
131
133
 
132
134
  def message(node)
133
135
  format(MSG, source: node.source)
@@ -142,7 +142,7 @@ module RuboCop
142
142
  end
143
143
 
144
144
  def escape_string(string)
145
- string.inspect[1..-2].tap { |s| s.gsub!(/\\"/, '"') }
145
+ string.inspect[1..-2].tap { |s| s.gsub!('\\"', '"') }
146
146
  end
147
147
 
148
148
  def to_string_literal(string)
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Utils
6
+ # Helper to abstract complexity of building range pairs
7
+ # with octal escape reconstruction (needed for regexp_parser < 2.7).
8
+ class RegexpRanges
9
+ attr_reader :compound_token, :root
10
+
11
+ def initialize(root)
12
+ @root = root
13
+ @compound_token = []
14
+ end
15
+
16
+ def pairs
17
+ unless @pairs
18
+ @pairs = []
19
+ populate(root)
20
+ end
21
+
22
+ # If either bound is a compound the first one is an escape
23
+ # and that's all we need to work with.
24
+ # If there are any cops that wanted to operate on the compound
25
+ # expression we could wrap it with a facade class.
26
+ @pairs.map { |pair| pair.map(&:first) }
27
+ end
28
+
29
+ private
30
+
31
+ def populate(expr)
32
+ expressions = expr.expressions.to_a
33
+
34
+ until expressions.empty?
35
+ current = expressions.shift
36
+
37
+ if escaped_octal?(current)
38
+ compound_token << current
39
+ compound_token.concat(pop_octal_digits(expressions))
40
+ # If we have all the digits we can discard.
41
+ end
42
+
43
+ next unless current.type == :set
44
+
45
+ process_set(expressions, current)
46
+ compound_token.clear
47
+ end
48
+ end
49
+
50
+ def process_set(expressions, current)
51
+ case current.token
52
+ when :range
53
+ @pairs << compose_range(expressions, current)
54
+ when :character
55
+ # Child expressions may include the range we are looking for.
56
+ populate(current)
57
+ when :intersection
58
+ # Each child expression could have child expressions that lead to ranges.
59
+ current.expressions.each do |intersected|
60
+ populate(intersected)
61
+ end
62
+ end
63
+ end
64
+
65
+ def compose_range(expressions, current)
66
+ 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
69
+ else
70
+ [range_start]
71
+ end
72
+ range_end = [range_end]
73
+ range_end.concat(pop_octal_digits(expressions)) if escaped_octal?(range_end.first)
74
+ [range_start, range_end]
75
+ end
76
+
77
+ def escaped_octal?(expr)
78
+ expr.text =~ /^\\[0-7]$/
79
+ end
80
+
81
+ def octal_digit?(char)
82
+ ('0'..'7').cover?(char)
83
+ end
84
+
85
+ def pop_octal_digits(expressions)
86
+ digits = []
87
+
88
+ 2.times do
89
+ next unless (next_child = expressions.first)
90
+ next unless next_child.type == :literal && next_child.text =~ /^[0-7]$/
91
+
92
+ digits << expressions.shift
93
+ end
94
+
95
+ digits
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -63,6 +63,18 @@ module RuboCop
63
63
  meta_assignment_node.type == MULTIPLE_ASSIGNMENT_TYPE
64
64
  end
65
65
 
66
+ def rest_assignment?
67
+ return false unless meta_assignment_node
68
+
69
+ meta_assignment_node.type == REST_ASSIGNMENT_TYPE
70
+ end
71
+
72
+ def for_assignment?
73
+ return false unless meta_assignment_node
74
+
75
+ meta_assignment_node.for_type?
76
+ end
77
+
66
78
  def operator
67
79
  assignment_node = meta_assignment_node || @node
68
80
  assignment_node.loc.operator.source
@@ -70,7 +82,10 @@ module RuboCop
70
82
 
71
83
  def meta_assignment_node
72
84
  unless instance_variable_defined?(:@meta_assignment_node)
73
- @meta_assignment_node = operator_assignment_node || multiple_assignment_node
85
+ @meta_assignment_node = operator_assignment_node ||
86
+ multiple_assignment_node ||
87
+ rest_assignment_node ||
88
+ for_assignment_node
74
89
  end
75
90
 
76
91
  @meta_assignment_node
@@ -87,13 +102,37 @@ module RuboCop
87
102
  end
88
103
 
89
104
  def multiple_assignment_node
90
- grandparent_node = node.parent&.parent
91
- return nil unless grandparent_node
105
+ return nil unless (grandparent_node = node.parent&.parent)
106
+ if (node = find_multiple_assignment_node(grandparent_node))
107
+ return node
108
+ end
92
109
  return nil unless grandparent_node.type == MULTIPLE_ASSIGNMENT_TYPE
93
- return nil unless node.parent.type == MULTIPLE_LEFT_HAND_SIDE_TYPE
94
110
 
95
111
  grandparent_node
96
112
  end
113
+
114
+ def rest_assignment_node
115
+ return nil unless node.parent
116
+ return nil unless node.parent.type == REST_ASSIGNMENT_TYPE
117
+
118
+ node.parent
119
+ end
120
+
121
+ def for_assignment_node
122
+ return nil unless node.parent&.for_type?
123
+
124
+ node.parent
125
+ end
126
+
127
+ def find_multiple_assignment_node(grandparent_node)
128
+ return unless grandparent_node.type == MULTIPLE_LEFT_HAND_SIDE_TYPE
129
+ return if grandparent_node.children.any?(&:splat_type?)
130
+
131
+ parent = grandparent_node.parent
132
+ return parent if parent.type == MULTIPLE_ASSIGNMENT_TYPE
133
+
134
+ find_multiple_assignment_node(parent)
135
+ end
97
136
  end
98
137
  end
99
138
  end
@@ -40,6 +40,7 @@ module RuboCop
40
40
  OPERATOR_ASSIGNMENT_TYPES = (LOGICAL_OPERATOR_ASSIGNMENT_TYPES + [:op_asgn]).freeze
41
41
 
42
42
  MULTIPLE_ASSIGNMENT_TYPE = :masgn
43
+ REST_ASSIGNMENT_TYPE = :splat
43
44
 
44
45
  VARIABLE_REFERENCE_TYPE = :lvar
45
46
 
@@ -198,7 +198,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
198
198
  table = ['|===', "| #{header.join(' | ')}\n\n"].join("\n")
199
199
  marked_contents = content.map do |plain_content|
200
200
  # Escape `|` with backslash to prevent the regexp `|` is not used as a table separator.
201
- plain_content.map { |c| "| #{c.gsub(/\|/, '\|')}" }.join("\n")
201
+ plain_content.map { |c| "| #{c.gsub('|', '\|')}" }.join("\n")
202
202
  end
203
203
  table << marked_contents.join("\n\n")
204
204
  table << "\n|===\n"
@@ -68,7 +68,9 @@ module RuboCop
68
68
  return { body: expression } unless (q = quantifier)
69
69
 
70
70
  body = expression.adjust(end_pos: -q.text.length)
71
- q_loc = expression.with(begin_pos: body.end_pos)
71
+ q.origin = origin
72
+ q.source = source if q.respond_to?(:source=) # for regexp_parser 1.8
73
+ q_loc = q.expression
72
74
  { body: body, quantifier: q_loc }
73
75
  end
74
76
  end
@@ -86,6 +88,7 @@ module RuboCop
86
88
  end
87
89
  end
88
90
  ::Regexp::Expression::Base.include Expression::Base
91
+ ::Regexp::Expression::Quantifier.include Expression::Base
89
92
  ::Regexp::Expression::CharacterSet.include Expression::CharacterSet
90
93
  end
91
94
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # This code is based on https://github.com/standardrb/standard.
5
+ #
6
+ # Copyright (c) 2023 Test Double, Inc.
7
+ #
8
+ # The MIT License (MIT)
9
+ #
10
+ # https://github.com/standardrb/standard/blob/main/LICENSE.txt
11
+ #
12
+ module RuboCop
13
+ module Lsp
14
+ # Log for Language Server Protocol of RuboCop.
15
+ # @api private
16
+ class Logger
17
+ def self.log(message)
18
+ warn("[server] #{message}")
19
+ end
20
+ end
21
+ end
22
+ end