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
@@ -101,13 +101,11 @@ module RuboCop
101
101
  end
102
102
 
103
103
  def args?(node)
104
- args = node_args(node)
105
- args.children.count > 0
104
+ !node_args(node).children.empty?
106
105
  end
107
106
 
108
107
  def parentheses?(node)
109
- args = node_args(node)
110
- args.loc.begin
108
+ node_args(node).loc.begin
111
109
  end
112
110
  end
113
111
  end
@@ -26,16 +26,16 @@ module RuboCop
26
26
  end
27
27
 
28
28
  def validate_config
29
- if style == :percent && target_ruby_version < 2.0
30
- raise ValidationError, 'The default `percent` style for the ' \
31
- '`Style/SymbolArray` cop is only compatible' \
32
- ' with Ruby 2.0 and up, but the target Ruby' \
33
- " version for your project is 1.9.\nPlease " \
34
- 'either disable this cop, configure it to ' \
35
- 'use `array` style, or adjust the ' \
36
- '`TargetRubyVersion` parameter in your ' \
37
- 'configuration.'
38
- end
29
+ return unless style == :percent && target_ruby_version < 2.0
30
+
31
+ raise ValidationError, 'The default `percent` style for the ' \
32
+ '`Style/SymbolArray` cop is only compatible' \
33
+ ' with Ruby 2.0 and up, but the target Ruby' \
34
+ " version for your project is 1.9.\nPlease " \
35
+ 'either disable this cop, configure it to ' \
36
+ 'use `array` style, or adjust the ' \
37
+ '`TargetRubyVersion` parameter in your ' \
38
+ 'configuration.'
39
39
  end
40
40
 
41
41
  private
@@ -57,10 +57,9 @@ module RuboCop
57
57
  end
58
58
 
59
59
  def offense(node, method_name, block_method_name)
60
- sb = node.source_range.source_buffer
61
60
  block_start = node.loc.begin.begin_pos
62
61
  block_end = node.loc.end.end_pos
63
- range = Parser::Source::Range.new(sb, block_start, block_end)
62
+ range = range_between(block_start, block_end)
64
63
 
65
64
  add_offense(node,
66
65
  range,
@@ -91,9 +90,7 @@ module RuboCop
91
90
  end
92
91
 
93
92
  def block_range_with_space(node)
94
- block_range =
95
- Parser::Source::Range.new(node.source_range.source_buffer,
96
- begin_pos_for_replacement(node),
93
+ block_range = range_between(begin_pos_for_replacement(node),
97
94
  node.loc.end.end_pos)
98
95
  range_with_surrounding_space(block_range, :left)
99
96
  end
@@ -118,16 +115,15 @@ module RuboCop
118
115
  end
119
116
 
120
117
  def can_shorten?(block_args, block_body)
121
- # something { |x, y| ... }
122
- return false unless block_args.children.size == 1
123
- return false if non_shortenable_args?(block_args)
124
- return false unless block_body && block_body.type == :send
118
+ return false unless shortenable_args?(block_args) &&
119
+ shortenable_body?(block_body)
125
120
 
126
- receiver, _method_name, args = *block_body
121
+ argument_matches_receiver?(block_args, block_body)
122
+ end
127
123
 
128
- # method in block must be invoked on a lvar without args
129
- return false if args
130
- return false unless receiver && receiver.type == :lvar
124
+ # TODO: This might be clearer as a node matcher with unification
125
+ def argument_matches_receiver?(block_args, block_body)
126
+ receiver, = *block_body
131
127
 
132
128
  block_arg_name, = *block_args.children.first
133
129
  receiver_name, = *receiver
@@ -135,6 +131,25 @@ module RuboCop
135
131
  block_arg_name == receiver_name
136
132
  end
137
133
 
134
+ # The block body must have a single send without arguments to an
135
+ # lvar type.
136
+ # E.g.: `foo { |bar| bar.baz }`
137
+ def shortenable_body?(block_body)
138
+ return false unless block_body && block_body.send_type?
139
+
140
+ receiver, _, args = *block_body
141
+
142
+ return false if args
143
+
144
+ receiver && receiver.lvar_type?
145
+ end
146
+
147
+ # The block must have a single, shortenable argument.
148
+ # E.g.: `foo { |bar| ... }`
149
+ def shortenable_args?(block_args)
150
+ block_args.children.one? && !non_shortenable_args?(block_args)
151
+ end
152
+
138
153
  def super?(node)
139
154
  [:super, :zsuper].include?(node.type)
140
155
  end
@@ -4,13 +4,13 @@
4
4
  module RuboCop
5
5
  module Cop
6
6
  module Style
7
- # This cop checks for the presence of arentheses around ternary
7
+ # This cop checks for the presence of parentheses around ternary
8
8
  # conditions. It is configurable to enforce inclusion or omission of
9
9
  # parentheses using `EnforcedStyle`.
10
10
  #
11
11
  # @example
12
12
  #
13
- # EnforcedStyle: require_no_parentheses (deafault)
13
+ # EnforcedStyle: require_no_parentheses (default)
14
14
  #
15
15
  # @bad
16
16
  # foo = (bar?) ? a : b
@@ -55,7 +55,8 @@ module RuboCop
55
55
 
56
56
  (require_parentheses? && !parenthesized?(condition) ||
57
57
  !require_parentheses? && parenthesized?(condition)) &&
58
- !(safe_assignment?(condition) && safe_assignment_allowed?)
58
+ !(safe_assignment?(condition) && safe_assignment_allowed?) &&
59
+ !infinite_loop?
59
60
  end
60
61
 
61
62
  def autocorrect(node)
@@ -66,8 +67,8 @@ module RuboCop
66
67
  corrector.insert_before(condition.source_range, '(')
67
68
  corrector.insert_after(condition.source_range, ')')
68
69
  else
69
- # Don't correct if it's a safe assignment
70
- unless safe_assignment?(condition)
70
+ unless safe_assignment?(condition) ||
71
+ unsafe_autocorrect?(condition)
71
72
  corrector.remove(condition.loc.begin)
72
73
  corrector.remove(condition.loc.end)
73
74
  end
@@ -85,9 +86,38 @@ module RuboCop
85
86
  style == :require_parentheses
86
87
  end
87
88
 
89
+ def redundant_parentheses_enabled?
90
+ @config.for_cop('RedundantParentheses')['Enabled']
91
+ end
92
+
88
93
  def parenthesized?(node)
89
94
  node.source =~ /^\(.*\)$/
90
95
  end
96
+
97
+ # When this cop is configured to enforce parentheses and the
98
+ # `RedundantParentheses` cop is enabled, it will cause an infinite loop
99
+ # as they compete to add and remove the parentheses respectively.
100
+ def infinite_loop?
101
+ require_parentheses? &&
102
+ redundant_parentheses_enabled?
103
+ end
104
+
105
+ def unsafe_autocorrect?(condition)
106
+ condition.children.any? do |child|
107
+ unparenthesized_method_call?(child)
108
+ end
109
+ end
110
+
111
+ def unparenthesized_method_call?(child)
112
+ argument = method_call_argument(child)
113
+
114
+ argument && argument !~ /^\(/
115
+ end
116
+
117
+ def_node_matcher :method_call_argument, <<-PATTERN
118
+ {(:defined? $...)
119
+ (send {(send ...) nil} _ $(send nil _)...)}
120
+ PATTERN
91
121
  end
92
122
  end
93
123
  end
@@ -34,11 +34,9 @@ module RuboCop
34
34
  def offense_detected(sb, wanted_blank_lines, blank_lines,
35
35
  whitespace_at_end)
36
36
  begin_pos = sb.source.length - whitespace_at_end.length
37
- autocorrect_range = Parser::Source::Range.new(sb, begin_pos,
38
- sb.source.length)
37
+ autocorrect_range = range_between(begin_pos, sb.source.length)
39
38
  begin_pos += 1 unless whitespace_at_end.empty?
40
- report_range = Parser::Source::Range.new(sb, begin_pos,
41
- sb.source.length)
39
+ report_range = range_between(begin_pos, sb.source.length)
42
40
  add_offense(autocorrect_range, report_range,
43
41
  message(wanted_blank_lines, blank_lines))
44
42
  end
@@ -26,7 +26,9 @@ module RuboCop
26
26
  UNDERSCORE = '_'.freeze
27
27
 
28
28
  def on_masgn(node)
29
- return unless (range = unneeded_range(node))
29
+ range = unneeded_range(node)
30
+
31
+ return unless range
30
32
 
31
33
  good_code = node.source
32
34
  offset = range.begin_pos - node.source_range.begin_pos
@@ -36,8 +38,9 @@ module RuboCop
36
38
  end
37
39
 
38
40
  def autocorrect(node)
41
+ range = unneeded_range(node)
42
+
39
43
  lambda do |corrector|
40
- range = unneeded_range(node)
41
44
  corrector.remove(range) if range
42
45
  end
43
46
  end
@@ -45,27 +48,38 @@ module RuboCop
45
48
  private
46
49
 
47
50
  def find_first_offense(variables)
48
- first_offense = nil
51
+ first_offense = find_first_possible_offense(variables.reverse)
52
+
53
+ return unless first_offense
54
+ return if splat_variable_before?(first_offense, variables)
55
+
56
+ first_offense
57
+ end
49
58
 
50
- variables.reverse_each do |variable|
59
+ def find_first_possible_offense(variables)
60
+ variables.reduce(nil) do |offense, variable|
51
61
  var, = *variable
52
62
  var, = *var
53
63
  if allow_named_underscore_variables
54
- break unless var == :_
64
+ break offense unless var == :_
55
65
  else
56
- break unless var.to_s.start_with?(UNDERSCORE)
66
+ break offense unless var.to_s.start_with?(UNDERSCORE)
57
67
  end
58
- first_offense = variable
68
+
69
+ variable
59
70
  end
71
+ end
60
72
 
61
- return nil if first_offense.nil?
73
+ def splat_variable_before?(first_offense, variables)
74
+ # Account for cases like `_, *rest, _`, where we would otherwise get
75
+ # the index of the first underscore.
76
+ first_offense_index = reverse_index(variables, first_offense)
62
77
 
63
- first_offense_index = variables.index(first_offense)
64
- 0.upto(first_offense_index - 1).each do |index|
65
- return nil if variables[index].splat_type?
66
- end
78
+ variables[0...first_offense_index].any?(&:splat_type?)
79
+ end
67
80
 
68
- first_offense
81
+ def reverse_index(collection, item)
82
+ collection.size - 1 - collection.reverse.index(item)
69
83
  end
70
84
 
71
85
  def allow_named_underscore_variables
@@ -87,10 +101,8 @@ module RuboCop
87
101
  node.loc.operator.begin_pos
88
102
  end
89
103
 
90
- range =
91
- Parser::Source::Range.new(node.source_range.source_buffer,
92
- first_offense.source_range.begin_pos,
93
- end_position)
104
+ range = range_between(first_offense.source_range.begin_pos,
105
+ end_position)
94
106
  range_with_surrounding_space(range, :right)
95
107
  end
96
108
  end
@@ -85,7 +85,7 @@ module RuboCop
85
85
  end
86
86
 
87
87
  def looks_like_trivial_reader?(args, body)
88
- args.children.empty? && body && body.type == :ivar
88
+ args.children.empty? && body && body.ivar_type?
89
89
  end
90
90
 
91
91
  def trivial_writer?(method_name, args, body)
@@ -95,10 +95,10 @@ module RuboCop
95
95
  end
96
96
 
97
97
  def looks_like_trivial_writer?(args, body)
98
- args.children.size == 1 &&
98
+ args.children.one? &&
99
99
  ![:restarg, :blockarg].include?(args.children[0].type) &&
100
- body && body.type == :ivasgn &&
101
- body.children[1] && body.children[1].type == :lvar
100
+ body && body.ivasgn_type? &&
101
+ body.children[1] && body.children[1].lvar_type?
102
102
  end
103
103
 
104
104
  def allowed_method?(method_name, body)
@@ -134,9 +134,9 @@ module RuboCop
134
134
  end
135
135
 
136
136
  def autocorrect(node)
137
- if node.type == :def
137
+ if node.def_type?
138
138
  autocorrect_instance(node)
139
- elsif node.type == :defs && node.children.first.type == :self
139
+ elsif node.defs_type? && node.children.first.self_type?
140
140
  autocorrect_class(node)
141
141
  end
142
142
  end
@@ -32,15 +32,11 @@ module RuboCop
32
32
  end
33
33
 
34
34
  def range_between_condition_and_else(node, condition)
35
- Parser::Source::Range.new(node.source_range.source_buffer,
36
- condition.source_range.end_pos,
37
- node.loc.else.begin_pos)
35
+ range_between(condition.source_range.end_pos, node.loc.else.begin_pos)
38
36
  end
39
37
 
40
38
  def range_between_else_and_end(node)
41
- Parser::Source::Range.new(node.source_range.source_buffer,
42
- node.loc.else.end_pos,
43
- node.loc.end.begin_pos)
39
+ range_between(node.loc.else.end_pos, node.loc.end.begin_pos)
44
40
  end
45
41
  end
46
42
  end
@@ -18,11 +18,15 @@ module RuboCop
18
18
  private
19
19
 
20
20
  def on_percent_literal(node)
21
- requires_interpolation = node.children.any? do |string|
22
- string.type == :dstr ||
23
- double_quotes_acceptable?(string.str_content)
21
+ return if requires_interpolation?(node)
22
+
23
+ add_offense(node, :expression)
24
+ end
25
+
26
+ def requires_interpolation?(node)
27
+ node.child_nodes.any? do |string|
28
+ string.dstr_type? || double_quotes_acceptable?(string.str_content)
24
29
  end
25
- add_offense(node, :expression) unless requires_interpolation
26
30
  end
27
31
 
28
32
  def autocorrect(node)
@@ -39,11 +39,11 @@ module RuboCop
39
39
  end
40
40
 
41
41
  def single_child?(node)
42
- node.children.size == 1
42
+ node.children.one?
43
43
  end
44
44
 
45
45
  def interpolation?(node)
46
- variable_interpolation?(node) || node.type == :begin
46
+ variable_interpolation?(node) || node.begin_type?
47
47
  end
48
48
 
49
49
  def variable_interpolation?(node)
@@ -51,12 +51,11 @@ module RuboCop
51
51
  end
52
52
 
53
53
  def implicit_concatenation?(node)
54
- node.parent && node.parent.type == :dstr
54
+ node.parent && node.parent.dstr_type?
55
55
  end
56
56
 
57
57
  def embedded_in_percent_array?(node)
58
- node.parent &&
59
- node.parent.type == :array &&
58
+ node.parent && node.parent.array_type? &&
60
59
  percent_literal?(node.parent)
61
60
  end
62
61
 
@@ -33,16 +33,22 @@ module RuboCop
33
33
  private
34
34
 
35
35
  def check(node)
36
- src = node.source
37
- return unless start_with_percent_q_variant?(src)
38
- return if src.include?(SINGLE_QUOTE) && src.include?(QUOTE)
39
- return if src.start_with?(PERCENT_Q) && acceptable_q?(node)
40
- return if src.start_with?(PERCENT_CAPITAL_Q) &&
41
- acceptable_capital_q?(node)
36
+ return unless start_with_percent_q_variant?(node)
37
+ return if interpolated_quotes?(node) || allowed_percent_q?(node)
42
38
 
43
39
  add_offense(node, :expression)
44
40
  end
45
41
 
42
+ def interpolated_quotes?(node)
43
+ node.source.include?(SINGLE_QUOTE) && node.source.include?(QUOTE)
44
+ end
45
+
46
+ def allowed_percent_q?(node)
47
+ node.source.start_with?(PERCENT_Q) && acceptable_q?(node) ||
48
+ node.source.start_with?(PERCENT_CAPITAL_Q) &&
49
+ acceptable_capital_q?(node)
50
+ end
51
+
46
52
  def message(node)
47
53
  src = node.source
48
54
  extra = if src.start_with?(PERCENT_CAPITAL_Q)
@@ -68,7 +74,7 @@ module RuboCop
68
74
  end
69
75
 
70
76
  def start_with_percent_q_variant?(string)
71
- string.start_with?(PERCENT_Q, PERCENT_CAPITAL_Q)
77
+ string.source.start_with?(PERCENT_Q, PERCENT_CAPITAL_Q)
72
78
  end
73
79
 
74
80
  def acceptable_q?(node)
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Style
7
+ # This cop makes sure that all numbered variables use the
8
+ # configured style, snake_case, normalcase or non_integer,
9
+ # for their numbering.
10
+ #
11
+ # @example
12
+ # "EnforcedStyle => 'snake_case'"
13
+ #
14
+ # # bad
15
+ #
16
+ # variable1 = 1
17
+ #
18
+ # # good
19
+ #
20
+ # variable_1 = 1
21
+ #
22
+ # @example
23
+ # "EnforcedStyle => 'normalcase'"
24
+ #
25
+ # # bad
26
+ #
27
+ # variable_1 = 1
28
+ #
29
+ # # good
30
+ #
31
+ # variable1 = 1
32
+ #
33
+ # @example
34
+ # "EnforcedStyle => 'non_integer'"
35
+ #
36
+ # #bad
37
+ #
38
+ # variable1 = 1
39
+ #
40
+ # variable_1 = 1
41
+ #
42
+ # #good
43
+ #
44
+ # variableone = 1
45
+ #
46
+ # variable_one = 1
47
+ #
48
+ class VariableNumber < Cop
49
+ include ConfigurableNumbering
50
+
51
+ def on_lvasgn(node)
52
+ name, = *node
53
+ check_name(node, name, node.loc.name)
54
+ end
55
+
56
+ def on_ivasgn(node)
57
+ name, = *node
58
+ check_name(node, name, node.loc.name)
59
+ end
60
+
61
+ def on_cvasgn(node)
62
+ name, = *node
63
+ check_name(node, name, node.loc.name)
64
+ end
65
+
66
+ def on_arg(node)
67
+ name, = *node
68
+ check_name(node, name, node.loc.name)
69
+ end
70
+
71
+ private
72
+
73
+ def message(style)
74
+ format('Use %s for variable numbers.', style)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end