rubocop 0.42.0 → 0.43.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/assets/output.html.erb +21 -10
  4. data/config/default.yml +32 -2
  5. data/config/disabled.yml +8 -1
  6. data/config/enabled.yml +40 -12
  7. data/lib/rubocop.rb +14 -2
  8. data/lib/rubocop/ast_node.rb +2 -0
  9. data/lib/rubocop/cached_data.rb +13 -11
  10. data/lib/rubocop/cli.rb +5 -5
  11. data/lib/rubocop/config.rb +68 -24
  12. data/lib/rubocop/config_loader.rb +13 -11
  13. data/lib/rubocop/config_loader_resolver.rb +4 -2
  14. data/lib/rubocop/cop/cop.rb +16 -5
  15. data/lib/rubocop/cop/lint/assignment_in_condition.rb +21 -20
  16. data/lib/rubocop/cop/lint/block_alignment.rb +3 -4
  17. data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -3
  18. data/lib/rubocop/cop/lint/duplicate_methods.rb +16 -6
  19. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  20. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  21. data/lib/rubocop/cop/lint/end_alignment.rb +4 -6
  22. data/lib/rubocop/cop/lint/eval.rb +1 -1
  23. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  24. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +8 -8
  25. data/lib/rubocop/cop/lint/inherit_exception.rb +22 -7
  26. data/lib/rubocop/cop/lint/literal_in_condition.rb +5 -5
  27. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +3 -5
  28. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  29. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +9 -8
  30. data/lib/rubocop/cop/lint/percent_string_array.rb +17 -6
  31. data/lib/rubocop/cop/lint/percent_symbol_array.rb +4 -4
  32. data/lib/rubocop/cop/lint/rand_one.rb +3 -3
  33. data/lib/rubocop/cop/lint/require_parentheses.rb +1 -3
  34. data/lib/rubocop/cop/lint/shadowed_exception.rb +39 -44
  35. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +2 -2
  36. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +1 -2
  37. data/lib/rubocop/cop/lint/unified_integer.rb +38 -0
  38. data/lib/rubocop/cop/lint/unneeded_disable.rb +51 -38
  39. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +114 -0
  40. data/lib/rubocop/cop/lint/useless_assignment.rb +25 -12
  41. data/lib/rubocop/cop/lint/useless_setter_call.rb +27 -28
  42. data/lib/rubocop/cop/lint/void.rb +2 -4
  43. data/lib/rubocop/cop/mixin/access_modifier_node.rb +5 -5
  44. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +19 -17
  45. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +3 -5
  46. data/lib/rubocop/cop/mixin/configurable_naming.rb +4 -5
  47. data/lib/rubocop/cop/mixin/configurable_numbering.rb +52 -0
  48. data/lib/rubocop/cop/mixin/def_node.rb +28 -0
  49. data/lib/rubocop/cop/mixin/documentation_comment.rb +41 -0
  50. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +18 -13
  51. data/lib/rubocop/cop/mixin/if_node.rb +6 -0
  52. data/lib/rubocop/cop/mixin/match_range.rb +2 -5
  53. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -2
  54. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +40 -28
  55. data/lib/rubocop/cop/mixin/negative_conditional.rb +6 -6
  56. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -5
  57. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +14 -4
  58. data/lib/rubocop/cop/mixin/safe_mode.rb +23 -0
  59. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +2 -4
  60. data/lib/rubocop/cop/mixin/space_inside.rb +1 -3
  61. data/lib/rubocop/cop/mixin/statement_modifier.rb +30 -20
  62. data/lib/rubocop/cop/mixin/trailing_comma.rb +19 -17
  63. data/lib/rubocop/cop/performance/case_when_splat.rb +16 -41
  64. data/lib/rubocop/cop/performance/casecmp.rb +28 -16
  65. data/lib/rubocop/cop/performance/count.rb +58 -34
  66. data/lib/rubocop/cop/performance/detect.rb +3 -7
  67. data/lib/rubocop/cop/performance/double_start_end_with.rb +17 -13
  68. data/lib/rubocop/cop/performance/fixed_size.rb +19 -14
  69. data/lib/rubocop/cop/performance/flat_map.rb +16 -9
  70. data/lib/rubocop/cop/performance/hash_each.rb +2 -3
  71. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +4 -6
  72. data/lib/rubocop/cop/performance/redundant_match.rb +4 -1
  73. data/lib/rubocop/cop/performance/redundant_merge.rb +63 -32
  74. data/lib/rubocop/cop/performance/redundant_sort_by.rb +8 -7
  75. data/lib/rubocop/cop/performance/reverse_each.rb +1 -4
  76. data/lib/rubocop/cop/performance/size.rb +21 -8
  77. data/lib/rubocop/cop/performance/sort_with_block.rb +54 -0
  78. data/lib/rubocop/cop/performance/string_replacement.rb +3 -7
  79. data/lib/rubocop/cop/rails/delegate.rb +2 -3
  80. data/lib/rubocop/cop/rails/find_by.rb +4 -8
  81. data/lib/rubocop/cop/rails/not_null_column.rb +45 -0
  82. data/lib/rubocop/cop/rails/request_referer.rb +3 -3
  83. data/lib/rubocop/cop/rails/safe_navigation.rb +89 -0
  84. data/lib/rubocop/cop/rails/save_bang.rb +78 -9
  85. data/lib/rubocop/cop/rails/scope_args.rb +3 -1
  86. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +2 -3
  87. data/lib/rubocop/cop/rails/validation.rb +1 -1
  88. data/lib/rubocop/cop/security/json_load.rb +36 -0
  89. data/lib/rubocop/cop/style/alias.rb +1 -1
  90. data/lib/rubocop/cop/style/align_hash.rb +25 -14
  91. data/lib/rubocop/cop/style/and_or.rb +13 -3
  92. data/lib/rubocop/cop/style/array_join.rb +3 -3
  93. data/lib/rubocop/cop/style/ascii_comments.rb +1 -2
  94. data/lib/rubocop/cop/style/ascii_identifiers.rb +1 -2
  95. data/lib/rubocop/cop/style/attr.rb +1 -3
  96. data/lib/rubocop/cop/style/block_comments.rb +2 -6
  97. data/lib/rubocop/cop/style/block_delimiters.rb +35 -21
  98. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +4 -4
  99. data/lib/rubocop/cop/style/case_indentation.rb +1 -3
  100. data/lib/rubocop/cop/style/class_methods.rb +3 -4
  101. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  102. data/lib/rubocop/cop/style/command_literal.rb +15 -8
  103. data/lib/rubocop/cop/style/comment_annotation.rb +1 -2
  104. data/lib/rubocop/cop/style/conditional_assignment.rb +68 -36
  105. data/lib/rubocop/cop/style/copyright.rb +1 -5
  106. data/lib/rubocop/cop/style/def_with_parentheses.rb +3 -5
  107. data/lib/rubocop/cop/style/documentation.rb +28 -56
  108. data/lib/rubocop/cop/style/documentation_method.rb +80 -0
  109. data/lib/rubocop/cop/style/each_for_simple_loop.rb +6 -5
  110. data/lib/rubocop/cop/style/each_with_object.rb +2 -2
  111. data/lib/rubocop/cop/style/else_alignment.rb +10 -9
  112. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -4
  113. data/lib/rubocop/cop/style/empty_else.rb +1 -4
  114. data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -3
  115. data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +2 -5
  116. data/lib/rubocop/cop/style/encoding.rb +28 -14
  117. data/lib/rubocop/cop/style/even_odd.rb +28 -17
  118. data/lib/rubocop/cop/style/extra_spacing.rb +36 -25
  119. data/lib/rubocop/cop/style/file_name.rb +19 -10
  120. data/lib/rubocop/cop/style/first_parameter_indentation.rb +2 -3
  121. data/lib/rubocop/cop/style/for.rb +12 -8
  122. data/lib/rubocop/cop/style/format_string.rb +1 -1
  123. data/lib/rubocop/cop/style/guard_clause.rb +22 -56
  124. data/lib/rubocop/cop/style/hash_syntax.rb +72 -7
  125. data/lib/rubocop/cop/style/if_unless_modifier.rb +23 -19
  126. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -3
  127. data/lib/rubocop/cop/style/indentation_width.rb +30 -16
  128. data/lib/rubocop/cop/style/infinite_loop.rb +16 -13
  129. data/lib/rubocop/cop/style/initial_indentation.rb +23 -18
  130. data/lib/rubocop/cop/style/inline_comment.rb +16 -3
  131. data/lib/rubocop/cop/style/lambda.rb +22 -10
  132. data/lib/rubocop/cop/style/leading_comment_space.rb +12 -1
  133. data/lib/rubocop/cop/style/line_end_concatenation.rb +24 -6
  134. data/lib/rubocop/cop/style/method_call_parentheses.rb +18 -9
  135. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  136. data/lib/rubocop/cop/style/method_def_parentheses.rb +3 -4
  137. data/lib/rubocop/cop/style/method_missing.rb +10 -2
  138. data/lib/rubocop/cop/style/module_function.rb +14 -6
  139. data/lib/rubocop/cop/style/multiline_assignment_layout.rb +2 -5
  140. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -5
  141. data/lib/rubocop/cop/style/multiline_block_layout.rb +22 -15
  142. data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +9 -0
  143. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +41 -20
  144. data/lib/rubocop/cop/style/multiline_operation_indentation.rb +6 -6
  145. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +3 -5
  146. data/lib/rubocop/cop/style/mutable_constant.rb +21 -13
  147. data/lib/rubocop/cop/style/negated_if.rb +1 -1
  148. data/lib/rubocop/cop/style/negated_while.rb +3 -3
  149. data/lib/rubocop/cop/style/nested_modifier.rb +2 -4
  150. data/lib/rubocop/cop/style/next.rb +4 -4
  151. data/lib/rubocop/cop/style/non_nil_check.rb +18 -10
  152. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +8 -0
  153. data/lib/rubocop/cop/style/numeric_predicate.rb +9 -9
  154. data/lib/rubocop/cop/style/one_line_conditional.rb +11 -1
  155. data/lib/rubocop/cop/style/op_method.rb +1 -1
  156. data/lib/rubocop/cop/style/option_hash.rb +8 -8
  157. data/lib/rubocop/cop/style/optional_arguments.rb +21 -8
  158. data/lib/rubocop/cop/style/parallel_assignment.rb +51 -35
  159. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  160. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  161. data/lib/rubocop/cop/style/raise_args.rb +2 -2
  162. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  163. data/lib/rubocop/cop/style/redundant_parentheses.rb +26 -15
  164. data/lib/rubocop/cop/style/redundant_return.rb +5 -5
  165. data/lib/rubocop/cop/style/redundant_self.rb +20 -11
  166. data/lib/rubocop/cop/style/regexp_literal.rb +16 -10
  167. data/lib/rubocop/cop/style/rescue_ensure_alignment.rb +8 -6
  168. data/lib/rubocop/cop/style/safe_navigation.rb +125 -0
  169. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  170. data/lib/rubocop/cop/style/semicolon.rb +9 -10
  171. data/lib/rubocop/cop/style/signal_exception.rb +2 -4
  172. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  173. data/lib/rubocop/cop/style/single_line_methods.rb +18 -11
  174. data/lib/rubocop/cop/style/space_after_method_name.rb +2 -3
  175. data/lib/rubocop/cop/style/space_after_not.rb +4 -6
  176. data/lib/rubocop/cop/style/space_around_block_parameters.rb +1 -2
  177. data/lib/rubocop/cop/style/space_around_equals_in_parameter_default.rb +1 -3
  178. data/lib/rubocop/cop/style/space_around_operators.rb +21 -16
  179. data/lib/rubocop/cop/style/space_before_block_braces.rb +2 -12
  180. data/lib/rubocop/cop/style/space_before_first_arg.rb +1 -3
  181. data/lib/rubocop/cop/style/space_inside_array_percent_literal.rb +1 -1
  182. data/lib/rubocop/cop/style/space_inside_block_braces.rb +33 -40
  183. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +38 -23
  184. data/lib/rubocop/cop/style/space_inside_percent_literal_delimiters.rb +1 -1
  185. data/lib/rubocop/cop/style/space_inside_string_interpolation.rb +26 -12
  186. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -4
  187. data/lib/rubocop/cop/style/symbol_array.rb +10 -10
  188. data/lib/rubocop/cop/style/symbol_proc.rb +28 -13
  189. data/lib/rubocop/cop/style/ternary_parentheses.rb +35 -5
  190. data/lib/rubocop/cop/style/trailing_blank_lines.rb +2 -4
  191. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +29 -17
  192. data/lib/rubocop/cop/style/trivial_accessors.rb +6 -6
  193. data/lib/rubocop/cop/style/unless_else.rb +2 -6
  194. data/lib/rubocop/cop/style/unneeded_capital_w.rb +8 -4
  195. data/lib/rubocop/cop/style/unneeded_interpolation.rb +4 -5
  196. data/lib/rubocop/cop/style/unneeded_percent_q.rb +13 -7
  197. data/lib/rubocop/cop/style/variable_number.rb +79 -0
  198. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  199. data/lib/rubocop/cop/style/word_array.rb +25 -15
  200. data/lib/rubocop/cop/style/zero_length_predicate.rb +2 -0
  201. data/lib/rubocop/cop/util.rb +23 -4
  202. data/lib/rubocop/cop/variable_force.rb +59 -25
  203. data/lib/rubocop/cop/variable_force/locatable.rb +8 -6
  204. data/lib/rubocop/cop/variable_force/variable.rb +2 -2
  205. data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
  206. data/lib/rubocop/formatter/disabled_config_formatter.rb +16 -11
  207. data/lib/rubocop/formatter/formatter_set.rb +12 -10
  208. data/lib/rubocop/formatter/worst_offenders_formatter.rb +4 -4
  209. data/lib/rubocop/node_pattern.rb +79 -35
  210. data/lib/rubocop/options.rb +4 -4
  211. data/lib/rubocop/processed_source.rb +9 -5
  212. data/lib/rubocop/remote_config.rb +14 -10
  213. data/lib/rubocop/result_cache.rb +14 -6
  214. data/lib/rubocop/runner.rb +55 -34
  215. data/lib/rubocop/string_util.rb +9 -5
  216. data/lib/rubocop/target_finder.rb +1 -1
  217. data/lib/rubocop/token.rb +1 -1
  218. data/lib/rubocop/version.rb +1 -1
  219. metadata +15 -4
  220. data/lib/rubocop/cop/lint/useless_array_splat.rb +0 -56
  221. data/lib/rubocop/cop/performance/push_splat.rb +0 -47
@@ -28,7 +28,7 @@ module RuboCop
28
28
 
29
29
  def check(node)
30
30
  return unless node.loc.end
31
- return unless fit_within_line_as_modifier_form?(node)
31
+ return unless single_line_as_modifier?(node)
32
32
  add_offense(node, :keyword, message(node.loc.keyword.source))
33
33
  end
34
34
 
@@ -25,19 +25,10 @@ module RuboCop
25
25
  end
26
26
 
27
27
  def autocorrect(node)
28
- words = node.children
29
28
  if style == :percent
30
- escape = words.any? { |w| needs_escaping?(w.children[0]) }
31
- char = escape ? 'W' : 'w'
32
- contents = autocorrect_words(words, escape, node.loc.line)
33
- lambda do |corrector|
34
- corrector.replace(node.source_range, "%#{char}(#{contents})")
35
- end
29
+ correct_percent(node)
36
30
  else
37
- words = words.map { |w| to_string_literal(w.children[0]) }
38
- lambda do |corrector|
39
- corrector.replace(node.source_range, "[#{words.join(', ')}]")
40
- end
31
+ correct_bracketed(node)
41
32
  end
42
33
  end
43
34
 
@@ -50,9 +41,9 @@ module RuboCop
50
41
  comments_in_array?(node)
51
42
  style_detected(:brackets, array_elems.size)
52
43
 
53
- if style == :percent && array_elems.size >= min_size
54
- add_offense(node, :expression, PERCENT_MSG)
55
- end
44
+ return unless style == :percent && array_elems.size >= min_size
45
+
46
+ add_offense(node, :expression, PERCENT_MSG)
56
47
  end
57
48
 
58
49
  def check_percent(node)
@@ -94,13 +85,32 @@ module RuboCop
94
85
  cop_config['WordRegex']
95
86
  end
96
87
 
88
+ def correct_percent(node)
89
+ words = node.children
90
+ escape = words.any? { |w| needs_escaping?(w.children[0]) }
91
+ char = escape ? 'W' : 'w'
92
+ contents = autocorrect_words(words, escape, node.loc.line)
93
+
94
+ lambda do |corrector|
95
+ corrector.replace(node.source_range, "%#{char}(#{contents})")
96
+ end
97
+ end
98
+
99
+ def correct_bracketed(node)
100
+ words = node.children.map { |w| to_string_literal(w.children[0]) }
101
+
102
+ lambda do |corrector|
103
+ corrector.replace(node.source_range, "[#{words.join(', ')}]")
104
+ end
105
+ end
106
+
97
107
  def autocorrect_words(word_nodes, escape, base_line_number)
98
108
  previous_node_line_number = base_line_number
99
109
  word_nodes.map do |node|
100
110
  number_of_line_breaks = node.loc.line - previous_node_line_number
101
111
  line_breaks = "\n" * number_of_line_breaks
102
112
  previous_node_line_number = node.loc.line
103
- content = node.children[0]
113
+ content = node.children.first
104
114
  content = escape ? escape_string(content) : content
105
115
  content.gsub!(/\)/, '\\)')
106
116
  line_breaks + content
@@ -34,10 +34,12 @@ module RuboCop
34
34
 
35
35
  nonzero_length_predicate = nonzero_length_predicate(node)
36
36
 
37
+ # rubocop:disable Style/GuardClause
37
38
  if nonzero_length_predicate
38
39
  add_offense(node, :expression,
39
40
  format(NONZERO_MSG, *nonzero_length_predicate))
40
41
  end
42
+ # rubocop:enable Style/GuardClause
41
43
  end
42
44
 
43
45
  def_node_matcher :zero_length_predicate, <<-END
@@ -81,10 +81,7 @@ module RuboCop
81
81
  yield sexp if Array(syms).include?(sexp.type)
82
82
  return if Array(excludes).include?(sexp.type)
83
83
 
84
- sexp.children.each do |elem|
85
- next unless elem.is_a?(Parser::AST::Node)
86
- on_node(syms, elem, excludes, &block)
87
- end
84
+ sexp.each_child_node { |elem| on_node(syms, elem, excludes, &block) }
88
85
  end
89
86
 
90
87
  def source_range(source_buffer, line_number, column, length = 1)
@@ -119,6 +116,10 @@ module RuboCop
119
116
  end
120
117
  end
121
118
 
119
+ def range_between(start_pos, end_pos)
120
+ Parser::Source::Range.new(processed_source.buffer, start_pos, end_pos)
121
+ end
122
+
122
123
  def range_with_surrounding_comma(range, side = :both)
123
124
  buffer = @processed_source.buffer
124
125
  src = buffer.source
@@ -247,6 +248,24 @@ module RuboCop
247
248
  def interpret_string_escapes(string)
248
249
  StringInterpreter.interpret(string)
249
250
  end
251
+
252
+ def same_line?(n1, n2)
253
+ n1.respond_to?(:loc) &&
254
+ n2.respond_to?(:loc) &&
255
+ n1.loc.line == n2.loc.line
256
+ end
257
+
258
+ def line_distance(n1, n2)
259
+ n2.loc.line - n1.loc.line
260
+ end
261
+
262
+ def preceed?(n1, n2)
263
+ line_distance(n1, n2) == 1
264
+ end
265
+
266
+ def stripped_source_upto(line)
267
+ processed_source[0..line].map(&:strip)
268
+ end
250
269
  end
251
270
  end
252
271
  end
@@ -56,6 +56,18 @@ module RuboCop
56
56
 
57
57
  SEND_TYPE = :send
58
58
 
59
+ VariableReference = Struct.new(:name) do
60
+ def assignment?
61
+ false
62
+ end
63
+ end
64
+
65
+ AssignmentReference = Struct.new(:node) do
66
+ def assignment?
67
+ true
68
+ end
69
+ end
70
+
59
71
  def variable_table
60
72
  @variable_table ||= VariableTable.new(self)
61
73
  end
@@ -70,6 +82,15 @@ module RuboCop
70
82
  variable_table.pop_scope
71
83
  end
72
84
 
85
+ def process_node(node)
86
+ catch(:skip_children) do
87
+ dispatch_node(node)
88
+ process_children(node)
89
+ end
90
+ end
91
+
92
+ private
93
+
73
94
  # This is called for each scope recursively.
74
95
  def inspect_variables_in_scope(scope_node)
75
96
  variable_table.push_scope(scope_node)
@@ -84,13 +105,6 @@ module RuboCop
84
105
  end
85
106
  end
86
107
 
87
- def process_node(node)
88
- catch(:skip_children) do
89
- dispatch_node(node)
90
- process_children(node)
91
- end
92
- end
93
-
94
108
  def skip_children!
95
109
  throw :skip_children
96
110
  end
@@ -158,10 +172,7 @@ module RuboCop
158
172
 
159
173
  def process_regexp_named_captures(node)
160
174
  regexp_node, rhs_node = *node
161
-
162
- regexp_string = regexp_node.children[0].children[0]
163
- regexp = Regexp.new(regexp_string)
164
- variable_names = regexp.named_captures.keys
175
+ variable_names = regexp_captured_names(regexp_node)
165
176
 
166
177
  variable_names.each do |name|
167
178
  next if variable_table.variable_exist?(name)
@@ -178,6 +189,13 @@ module RuboCop
178
189
  skip_children!
179
190
  end
180
191
 
192
+ def regexp_captured_names(node)
193
+ regexp_string = node.children[0].children[0] || ''
194
+ regexp = Regexp.new(regexp_string)
195
+
196
+ regexp.named_captures.keys
197
+ end
198
+
181
199
  def process_variable_operator_assignment(node)
182
200
  if LOGICAL_OPERATOR_ASSIGNMENT_TYPES.include?(node.type)
183
201
  asgn_node, rhs_node = *node
@@ -185,7 +203,7 @@ module RuboCop
185
203
  asgn_node, _operator, rhs_node = *node
186
204
  end
187
205
 
188
- return unless asgn_node.type == :lvasgn
206
+ return unless asgn_node.lvasgn_type?
189
207
 
190
208
  name = asgn_node.children.first
191
209
 
@@ -264,7 +282,7 @@ module RuboCop
264
282
  if TWISTED_SCOPE_TYPES.include?(node.type)
265
283
  # See the comment at the end of file for this behavior.
266
284
  twisted_nodes = [node.children[0]]
267
- twisted_nodes << node.children[1] if node.type == :class
285
+ twisted_nodes << node.children[1] if node.class_type?
268
286
  twisted_nodes.compact!
269
287
 
270
288
  twisted_nodes.each do |twisted_node|
@@ -312,23 +330,39 @@ module RuboCop
312
330
  referenced_variable_names_in_loop = []
313
331
  assignment_nodes_in_loop = []
314
332
 
333
+ each_descendant_reference(loop_node) do |reference|
334
+ if reference.assignment?
335
+ assignment_nodes_in_loop << reference.node
336
+ else
337
+ referenced_variable_names_in_loop << reference.name
338
+ end
339
+ end
340
+
341
+ [referenced_variable_names_in_loop, assignment_nodes_in_loop]
342
+ end
343
+
344
+ def each_descendant_reference(loop_node)
315
345
  # #each_descendant does not consider scope,
316
346
  # but we don't need to care about it here.
317
347
  loop_node.each_descendant do |node|
318
- case node.type
319
- when :lvar
320
- referenced_variable_names_in_loop << node.children.first
321
- when :lvasgn
322
- assignment_nodes_in_loop << node
323
- when *OPERATOR_ASSIGNMENT_TYPES
324
- asgn_node = node.children.first
325
- if asgn_node.type == :lvasgn
326
- referenced_variable_names_in_loop << asgn_node.children.first
327
- end
328
- end
348
+ reference = descendant_reference(node)
349
+
350
+ yield reference if reference
329
351
  end
352
+ end
330
353
 
331
- [referenced_variable_names_in_loop, assignment_nodes_in_loop]
354
+ def descendant_reference(node)
355
+ case node.type
356
+ when :lvar
357
+ VariableReference.new(node.children.first)
358
+ when :lvasgn
359
+ AssignmentReference.new(node)
360
+ when *OPERATOR_ASSIGNMENT_TYPES
361
+ asgn_node = node.children.first
362
+ if asgn_node.lvasgn_type?
363
+ VariableReference.new(asgn_node.children.first)
364
+ end
365
+ end
332
366
  end
333
367
 
334
368
  # Use Node#equal? for accurate check.
@@ -45,7 +45,7 @@ module RuboCop
45
45
  # rescue
46
46
  # # resbody
47
47
  # end
48
- if branch_point_node.type == :rescue &&
48
+ if branch_point_node.rescue_type? &&
49
49
  (branch_body_name == 'main' || other.branch_body_name == 'main')
50
50
  return false
51
51
  end
@@ -83,6 +83,7 @@ module RuboCop
83
83
  @branch_body_node
84
84
  end
85
85
 
86
+ # TODO: Replace case statement with function mapping
86
87
  def branch_body_name
87
88
  case branch_point_node.type
88
89
  when :if then if_body_name
@@ -91,11 +92,10 @@ module RuboCop
91
92
  when ENSURE_TYPE then ensure_body_name
92
93
  when *LOGICAL_OPERATOR_TYPES then logical_operator_body_name
93
94
  when *LOOP_TYPES then loop_body_name
94
- else raise InvalidBranchBodyError
95
+ else
96
+ raise InvalidBranchBodyError, "Invalid body index #{body_index} " \
97
+ "of #{branch_point_node.type}"
95
98
  end
96
- rescue InvalidBranchBodyError
97
- raise InvalidBranchBodyError,
98
- "Invalid body index #{body_index} of #{branch_point_node.type}"
99
99
  end
100
100
 
101
101
  private
@@ -109,7 +109,7 @@ module RuboCop
109
109
  end
110
110
 
111
111
  def case_body_name
112
- if branch_body_node.type == :when
112
+ if branch_body_node.when_type?
113
113
  "when#{body_index - 1}"
114
114
  else
115
115
  'else'
@@ -169,6 +169,7 @@ module RuboCop
169
169
  end
170
170
  end
171
171
 
172
+ # rubocop:disable Metrics/MethodLength
172
173
  def branch?(parent_node, child_node)
173
174
  child_index = parent_node.children.index(child_node)
174
175
 
@@ -189,6 +190,7 @@ module RuboCop
189
190
  false
190
191
  end
191
192
  end
193
+ # rubocop:enable Metrics/MethodLength
192
194
 
193
195
  class InvalidBranchBodyError < StandardError; end
194
196
  end
@@ -87,7 +87,7 @@ module RuboCop
87
87
  end
88
88
 
89
89
  def block_argument?
90
- argument? && @scope.node.type == :block
90
+ argument? && @scope.node.block_type?
91
91
  end
92
92
 
93
93
  def keyword_argument?
@@ -95,7 +95,7 @@ module RuboCop
95
95
  end
96
96
 
97
97
  def explicit_block_local_variable?
98
- @declaration_node.type == :shadowarg
98
+ @declaration_node.shadowarg_type?
99
99
  end
100
100
  end
101
101
  end
@@ -99,7 +99,7 @@ module RuboCop
99
99
  variable = scope.variables[name]
100
100
  return variable if variable
101
101
  # Only block scope allows referencing outer scope variables.
102
- return nil unless scope.node.type == :block
102
+ return nil unless scope.node.block_type?
103
103
  end
104
104
 
105
105
  nil
@@ -112,14 +112,14 @@ module RuboCop
112
112
  def accessible_variables
113
113
  scope_stack.reverse_each.each_with_object([]) do |scope, variables|
114
114
  variables.concat(scope.variables.values)
115
- break variables unless scope.node.type == :block
115
+ break variables unless scope.node.block_type?
116
116
  end
117
117
  end
118
118
 
119
119
  private
120
120
 
121
121
  def mark_variable_as_captured_by_block_if_so(variable)
122
- return unless current_scope.node.type == :block
122
+ return unless current_scope.node.block_type?
123
123
  return if variable.scope == current_scope
124
124
  variable.capture_with_block!
125
125
  end
@@ -151,6 +151,13 @@ module RuboCop
151
151
  require 'pathname'
152
152
  parent = Pathname.new(Dir.pwd)
153
153
 
154
+ output.puts ' Exclude:'
155
+ excludes(offending_files, cop_name, parent).each do |file|
156
+ output_exclude_path(output, file, parent)
157
+ end
158
+ end
159
+
160
+ def excludes(offending_files, cop_name, parent)
154
161
  # Exclude properties in .rubocop_todo.yml override default ones, as well
155
162
  # as any custom excludes in .rubocop.yml, so in order to retain those
156
163
  # excludes we must copy them.
@@ -158,18 +165,16 @@ module RuboCop
158
165
  # just look at the current working directory
159
166
  config = ConfigStore.new.for(parent)
160
167
  cfg = config[cop_name] || {}
161
- excludes = ((cfg['Exclude'] || []) + offending_files).uniq
162
168
 
163
- output.puts ' Exclude:'
164
- excludes.each do |file|
165
- file_path = Pathname.new(file)
166
- begin
167
- relative = file_path.relative_path_from(parent)
168
- output.puts " - '#{relative}'"
169
- rescue ArgumentError
170
- output.puts " - '#{file}'"
171
- end
172
- end
169
+ ((cfg['Exclude'] || []) + offending_files).uniq
170
+ end
171
+
172
+ def output_exclude_path(output, file, parent)
173
+ file_path = Pathname.new(file)
174
+ relative = file_path.relative_path_from(parent)
175
+ output.puts " - '#{relative}'"
176
+ rescue ArgumentError
177
+ output.puts " - '#{file}'"
173
178
  end
174
179
  end
175
180
  end
@@ -47,15 +47,6 @@ module RuboCop
47
47
  end
48
48
 
49
49
  def add_formatter(formatter_type, output_path = nil)
50
- formatter_class = case formatter_type
51
- when Class
52
- formatter_type
53
- when /\A[A-Z]/
54
- custom_formatter_class(formatter_type)
55
- else
56
- builtin_formatter_class(formatter_type)
57
- end
58
-
59
50
  if output_path
60
51
  dir_path = File.dirname(output_path)
61
52
  FileUtils.mkdir_p(dir_path) unless File.exist?(dir_path)
@@ -64,7 +55,7 @@ module RuboCop
64
55
  output = $stdout
65
56
  end
66
57
 
67
- self << formatter_class.new(output, @options)
58
+ self << formatter_class(formatter_type).new(output, @options)
68
59
  end
69
60
 
70
61
  def close_output_files
@@ -75,6 +66,17 @@ module RuboCop
75
66
 
76
67
  private
77
68
 
69
+ def formatter_class(formatter_type)
70
+ case formatter_type
71
+ when Class
72
+ formatter_type
73
+ when /\A[A-Z]/
74
+ custom_formatter_class(formatter_type)
75
+ else
76
+ builtin_formatter_class(formatter_type)
77
+ end
78
+ end
79
+
78
80
  def builtin_formatter_class(specified_key)
79
81
  matching_keys = BUILTIN_FORMATTERS_FOR_KEYS.keys.select do |key|
80
82
  key.start_with?(specified_key)