rubocop 0.47.1 → 0.48.0

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.

Potentially problematic release.


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

Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -16
  3. data/config/default.yml +203 -115
  4. data/config/disabled.yml +0 -5
  5. data/config/enabled.yml +92 -8
  6. data/lib/rubocop.rb +24 -1
  7. data/lib/rubocop/ast/builder.rb +7 -2
  8. data/lib/rubocop/ast/node.rb +23 -20
  9. data/lib/rubocop/ast/node/and_node.rb +37 -0
  10. data/lib/rubocop/ast/node/array_node.rb +4 -1
  11. data/lib/rubocop/ast/node/case_node.rb +1 -0
  12. data/lib/rubocop/ast/node/ensure_node.rb +25 -0
  13. data/lib/rubocop/ast/node/hash_node.rb +10 -3
  14. data/lib/rubocop/ast/node/if_node.rb +2 -0
  15. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +23 -0
  16. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +35 -0
  17. data/lib/rubocop/ast/node/or_node.rb +37 -0
  18. data/lib/rubocop/ast/node/resbody_node.rb +25 -0
  19. data/lib/rubocop/ast/node/send_node.rb +190 -0
  20. data/lib/rubocop/ast/node/when_node.rb +1 -1
  21. data/lib/rubocop/ast/traversal.rb +15 -15
  22. data/lib/rubocop/comment_config.rb +1 -1
  23. data/lib/rubocop/config.rb +39 -15
  24. data/lib/rubocop/config_loader.rb +34 -13
  25. data/lib/rubocop/cop/bundler/ordered_gems.rb +23 -4
  26. data/lib/rubocop/cop/commissioner.rb +4 -0
  27. data/lib/rubocop/cop/cop.rb +5 -0
  28. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +53 -0
  29. data/lib/rubocop/cop/lint/debugger.rb +8 -1
  30. data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -1
  31. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -4
  32. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
  33. data/lib/rubocop/cop/lint/each_with_object_argument.rb +3 -1
  34. data/lib/rubocop/cop/lint/empty_ensure.rb +6 -2
  35. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  36. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +20 -18
  37. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -3
  38. data/lib/rubocop/cop/lint/literal_in_condition.rb +1 -1
  39. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  40. data/lib/rubocop/cop/lint/multiple_compare.rb +5 -3
  41. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +26 -18
  42. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +7 -8
  43. data/lib/rubocop/cop/lint/require_parentheses.rb +7 -13
  44. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +7 -3
  45. data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -6
  46. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +7 -8
  47. data/lib/rubocop/cop/lint/unneeded_disable.rb +35 -11
  48. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
  49. data/lib/rubocop/cop/lint/unreachable_code.rb +5 -2
  50. data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -6
  51. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -1
  52. data/lib/rubocop/cop/lint/useless_comparison.rb +5 -4
  53. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  54. data/lib/rubocop/cop/message_annotator.rb +7 -3
  55. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  56. data/lib/rubocop/cop/metrics/block_nesting.rb +4 -4
  57. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -2
  58. data/lib/rubocop/cop/metrics/line_length.rb +2 -9
  59. data/lib/rubocop/cop/metrics/parameter_lists.rb +4 -3
  60. data/lib/rubocop/cop/metrics/perceived_complexity.rb +2 -2
  61. data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
  62. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +2 -2
  63. data/lib/rubocop/cop/mixin/check_assignment.rb +6 -6
  64. data/lib/rubocop/cop/mixin/duplication.rb +1 -1
  65. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  66. data/lib/rubocop/cop/mixin/ignored_pattern.rb +27 -0
  67. data/lib/rubocop/cop/mixin/method_preference.rb +2 -0
  68. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +17 -29
  69. data/lib/rubocop/cop/mixin/on_method_def.rb +3 -3
  70. data/lib/rubocop/cop/mixin/percent_literal.rb +27 -0
  71. data/lib/rubocop/cop/mixin/rescue_node.rb +21 -0
  72. data/lib/rubocop/cop/mixin/safe_mode.rb +1 -1
  73. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  74. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -1
  75. data/lib/rubocop/cop/mixin/target_rails_version.rb +16 -0
  76. data/lib/rubocop/cop/mixin/unused_argument.rb +1 -1
  77. data/lib/rubocop/cop/offense.rb +3 -3
  78. data/lib/rubocop/cop/performance/casecmp.rb +1 -1
  79. data/lib/rubocop/cop/performance/detect.rb +2 -1
  80. data/lib/rubocop/cop/performance/double_start_end_with.rb +35 -1
  81. data/lib/rubocop/cop/performance/end_with.rb +3 -1
  82. data/lib/rubocop/cop/performance/flat_map.rb +6 -6
  83. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -2
  84. data/lib/rubocop/cop/performance/range_include.rb +3 -1
  85. data/lib/rubocop/cop/performance/redundant_match.rb +6 -5
  86. data/lib/rubocop/cop/performance/regexp_match.rb +10 -3
  87. data/lib/rubocop/cop/performance/reverse_each.rb +2 -1
  88. data/lib/rubocop/cop/performance/size.rb +6 -11
  89. data/lib/rubocop/cop/performance/start_with.rb +3 -1
  90. data/lib/rubocop/cop/performance/string_replacement.rb +13 -18
  91. data/lib/rubocop/cop/performance/times_map.rb +4 -4
  92. data/lib/rubocop/cop/rails/action_filter.rb +42 -42
  93. data/lib/rubocop/cop/rails/active_support_aliases.rb +68 -0
  94. data/lib/rubocop/cop/rails/blank.rb +131 -0
  95. data/lib/rubocop/cop/rails/date.rb +25 -28
  96. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +5 -7
  97. data/lib/rubocop/cop/rails/dynamic_find_by.rb +7 -3
  98. data/lib/rubocop/cop/rails/exit.rb +9 -9
  99. data/lib/rubocop/cop/rails/file_path.rb +5 -14
  100. data/lib/rubocop/cop/rails/find_by.rb +8 -10
  101. data/lib/rubocop/cop/rails/find_each.rb +6 -9
  102. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -0
  103. data/lib/rubocop/cop/rails/http_positional_arguments.rb +15 -7
  104. data/lib/rubocop/cop/rails/output.rb +3 -5
  105. data/lib/rubocop/cop/rails/output_safety.rb +4 -8
  106. data/lib/rubocop/cop/rails/pluralization_grammar.rb +25 -24
  107. data/lib/rubocop/cop/rails/present.rb +137 -0
  108. data/lib/rubocop/cop/rails/read_write_attribute.rb +9 -18
  109. data/lib/rubocop/cop/rails/relative_date_constant.rb +53 -0
  110. data/lib/rubocop/cop/rails/request_referer.rb +7 -4
  111. data/lib/rubocop/cop/rails/reversible_migration.rb +1 -2
  112. data/lib/rubocop/cop/rails/safe_navigation.rb +2 -1
  113. data/lib/rubocop/cop/rails/save_bang.rb +10 -10
  114. data/lib/rubocop/cop/rails/skips_model_validations.rb +23 -6
  115. data/lib/rubocop/cop/rails/time_zone.rb +20 -18
  116. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +3 -2
  117. data/lib/rubocop/cop/rails/validation.rb +8 -11
  118. data/lib/rubocop/cop/registry.rb +3 -3
  119. data/lib/rubocop/cop/security/json_load.rb +1 -1
  120. data/lib/rubocop/cop/security/marshal_load.rb +5 -1
  121. data/lib/rubocop/cop/security/yaml_load.rb +3 -3
  122. data/lib/rubocop/cop/severity.rb +1 -1
  123. data/lib/rubocop/cop/style/alias.rb +5 -5
  124. data/lib/rubocop/cop/style/align_hash.rb +1 -1
  125. data/lib/rubocop/cop/style/align_parameters.rb +5 -5
  126. data/lib/rubocop/cop/style/and_or.rb +16 -31
  127. data/lib/rubocop/cop/style/attr.rb +14 -8
  128. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +8 -11
  129. data/lib/rubocop/cop/style/block_delimiters.rb +11 -13
  130. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +19 -23
  131. data/lib/rubocop/cop/style/case_indentation.rb +2 -0
  132. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  133. data/lib/rubocop/cop/style/class_check.rb +5 -7
  134. data/lib/rubocop/cop/style/closing_parenthesis_indentation.rb +5 -4
  135. data/lib/rubocop/cop/style/collection_methods.rb +8 -8
  136. data/lib/rubocop/cop/style/colon_method_call.rb +2 -9
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +38 -45
  138. data/lib/rubocop/cop/style/constant_name.rb +1 -1
  139. data/lib/rubocop/cop/style/documentation_method.rb +1 -0
  140. data/lib/rubocop/cop/style/dot_position.rb +3 -7
  141. data/lib/rubocop/cop/style/double_negation.rb +2 -1
  142. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  143. data/lib/rubocop/cop/style/empty_else.rb +2 -2
  144. data/lib/rubocop/cop/style/empty_line_after_magic_comment.rb +63 -0
  145. data/lib/rubocop/cop/style/empty_line_between_defs.rb +74 -4
  146. data/lib/rubocop/cop/style/empty_lines_around_begin_body.rb +42 -0
  147. data/lib/rubocop/cop/style/empty_lines_around_exception_handling_keywords.rb +127 -0
  148. data/lib/rubocop/cop/style/empty_literal.rb +17 -9
  149. data/lib/rubocop/cop/style/end_of_line.rb +25 -3
  150. data/lib/rubocop/cop/style/file_name.rb +1 -1
  151. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
  152. data/lib/rubocop/cop/style/first_parameter_indentation.rb +17 -19
  153. data/lib/rubocop/cop/style/for.rb +2 -4
  154. data/lib/rubocop/cop/style/format_string.rb +5 -4
  155. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  156. data/lib/rubocop/cop/style/identical_conditional_branches.rb +27 -1
  157. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
  158. data/lib/rubocop/cop/style/indent_assignment.rb +2 -2
  159. data/lib/rubocop/cop/style/indent_hash.rb +2 -1
  160. data/lib/rubocop/cop/style/indent_heredoc.rb +173 -0
  161. data/lib/rubocop/cop/style/indentation_width.rb +61 -29
  162. data/lib/rubocop/cop/style/inverse_methods.rb +130 -0
  163. data/lib/rubocop/cop/style/lambda_call.rb +15 -11
  164. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -4
  165. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +26 -14
  166. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -16
  167. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  168. data/lib/rubocop/cop/style/missing_else.rb +4 -3
  169. data/lib/rubocop/cop/style/mixin_grouping.rb +97 -0
  170. data/lib/rubocop/cop/style/multiline_memoization.rb +38 -5
  171. data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +2 -3
  172. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +38 -19
  173. data/lib/rubocop/cop/style/mutable_constant.rb +5 -1
  174. data/lib/rubocop/cop/style/negated_if.rb +73 -1
  175. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +21 -19
  176. data/lib/rubocop/cop/style/next.rb +5 -5
  177. data/lib/rubocop/cop/style/non_nil_check.rb +7 -10
  178. data/lib/rubocop/cop/style/not.rb +3 -4
  179. data/lib/rubocop/cop/style/numeric_literals.rb +25 -3
  180. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  181. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  182. data/lib/rubocop/cop/style/op_method.rb +2 -2
  183. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -3
  184. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +52 -6
  185. data/lib/rubocop/cop/style/perl_backrefs.rb +1 -1
  186. data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -9
  187. data/lib/rubocop/cop/style/raise_args.rb +28 -24
  188. data/lib/rubocop/cop/style/redundant_freeze.rb +5 -7
  189. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -3
  190. data/lib/rubocop/cop/style/redundant_self.rb +17 -35
  191. data/lib/rubocop/cop/style/rescue_modifier.rb +2 -14
  192. data/lib/rubocop/cop/style/self_assignment.rb +3 -3
  193. data/lib/rubocop/cop/style/send.rb +4 -5
  194. data/lib/rubocop/cop/style/space_after_not.rb +7 -8
  195. data/lib/rubocop/cop/style/space_around_keyword.rb +8 -9
  196. data/lib/rubocop/cop/style/space_around_operators.rb +19 -15
  197. data/lib/rubocop/cop/style/space_before_first_arg.rb +17 -14
  198. data/lib/rubocop/cop/style/space_inside_brackets.rb +1 -1
  199. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +3 -3
  200. data/lib/rubocop/cop/style/space_inside_parens.rb +1 -1
  201. data/lib/rubocop/cop/style/special_global_vars.rb +14 -14
  202. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -1
  203. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  204. data/lib/rubocop/cop/style/string_methods.rb +10 -5
  205. data/lib/rubocop/cop/style/struct_inheritance.rb +4 -15
  206. data/lib/rubocop/cop/style/symbol_array.rb +31 -35
  207. data/lib/rubocop/cop/style/symbol_proc.rb +2 -2
  208. data/lib/rubocop/cop/style/ternary_parentheses.rb +41 -13
  209. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +6 -9
  210. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -1
  211. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  212. data/lib/rubocop/cop/style/unneeded_capital_w.rb +1 -2
  213. data/lib/rubocop/cop/style/unneeded_percent_q.rb +1 -1
  214. data/lib/rubocop/cop/style/word_array.rb +12 -34
  215. data/lib/rubocop/cop/style/zero_length_predicate.rb +11 -4
  216. data/lib/rubocop/cop/team.rb +4 -1
  217. data/lib/rubocop/cop/util.rb +33 -26
  218. data/lib/rubocop/cop/variable_force.rb +13 -13
  219. data/lib/rubocop/cop/variable_force/assignment.rb +1 -8
  220. data/lib/rubocop/cop/variable_force/branch.rb +318 -0
  221. data/lib/rubocop/cop/variable_force/branchable.rb +21 -0
  222. data/lib/rubocop/cop/variable_force/reference.rb +1 -3
  223. data/lib/rubocop/cop/variable_force/scope.rb +36 -20
  224. data/lib/rubocop/cop/variable_force/variable.rb +9 -8
  225. data/lib/rubocop/formatter/colorizable.rb +10 -10
  226. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  227. data/lib/rubocop/formatter/html_formatter.rb +2 -1
  228. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -2
  229. data/lib/rubocop/magic_comment.rb +20 -6
  230. data/lib/rubocop/options.rb +1 -1
  231. data/lib/rubocop/platform.rb +11 -0
  232. data/lib/rubocop/processed_source.rb +1 -1
  233. data/lib/rubocop/remote_config.rb +18 -6
  234. data/lib/rubocop/result_cache.rb +8 -8
  235. data/lib/rubocop/rspec/cop_helper.rb +2 -0
  236. data/lib/rubocop/rspec/shared_contexts.rb +20 -0
  237. data/lib/rubocop/rspec/shared_examples.rb +1 -1
  238. data/lib/rubocop/runner.rb +2 -2
  239. data/lib/rubocop/target_finder.rb +64 -6
  240. data/lib/rubocop/version.rb +2 -4
  241. metadata +27 -4
  242. data/lib/rubocop/cop/variable_force/locatable.rb +0 -200
@@ -14,14 +14,13 @@ module RuboCop
14
14
  def on_send(node)
15
15
  class_check?(node) do |method_name|
16
16
  return if style == method_name
17
+
17
18
  add_offense(node, :selector)
18
19
  end
19
20
  end
20
21
 
21
22
  def message(node)
22
- _receiver, method_name, *_args = *node
23
-
24
- if method_name == :is_a?
23
+ if node.method?(:is_a?)
25
24
  format(MSG, 'kind_of?', 'is_a?')
26
25
  else
27
26
  format(MSG, 'is_a?', 'kind_of?')
@@ -29,11 +28,10 @@ module RuboCop
29
28
  end
30
29
 
31
30
  def autocorrect(node)
32
- _receiver, method_name, *_args = *node
33
-
34
31
  lambda do |corrector|
35
- corrector.replace(node.loc.selector,
36
- method_name == :is_a? ? 'kind_of?' : 'is_a?')
32
+ replacement = node.method?(:is_a?) ? 'kind_of?' : 'is_a?'
33
+
34
+ corrector.replace(node.loc.selector, replacement)
37
35
  end
38
36
  end
39
37
  end
@@ -34,8 +34,7 @@ module RuboCop
34
34
  MSG_ALIGN = 'Align `)` with `(`.'.freeze
35
35
 
36
36
  def on_send(node)
37
- _receiver, _method_name, *args = *node
38
- check(node, args)
37
+ check(node, node.arguments)
39
38
  end
40
39
 
41
40
  def on_begin(node)
@@ -50,15 +49,17 @@ module RuboCop
50
49
 
51
50
  def check(node, elements)
52
51
  right_paren = node.loc.end
53
- return unless right_paren
54
- return unless begins_its_line?(right_paren)
52
+
53
+ return unless right_paren && begins_its_line?(right_paren)
55
54
 
56
55
  correct_column = expected_column(node, elements)
57
56
  @column_delta = correct_column - right_paren.column
57
+
58
58
  return if @column_delta.zero?
59
59
 
60
60
  left_paren = node.loc.begin
61
61
  msg = correct_column == left_paren.column ? MSG_ALIGN : MSG_INDENT
62
+
62
63
  add_offense(right_paren, right_paren, msg)
63
64
  end
64
65
 
@@ -21,8 +21,8 @@ module RuboCop
21
21
  end
22
22
 
23
23
  def on_send(node)
24
- _receiver, _method_name, *args = *node
25
- return unless args.one? && args.first.block_pass_type?
24
+ return unless node.arguments.one? &&
25
+ node.first_argument.block_pass_type?
26
26
 
27
27
  check_method_node(node)
28
28
  end
@@ -36,14 +36,14 @@ module RuboCop
36
36
 
37
37
  private
38
38
 
39
+ def message(node)
40
+ format(MSG, preferred_method(node.method_name), node.method_name)
41
+ end
42
+
39
43
  def check_method_node(node)
40
- _receiver, method_name, *_args = *node
44
+ return unless preferred_methods[node.method_name]
41
45
 
42
- return unless preferred_methods[method_name]
43
- add_offense(node, :selector,
44
- format(MSG,
45
- preferred_method(method_name),
46
- method_name))
46
+ add_offense(node, :selector)
47
47
  end
48
48
  end
49
49
  end
@@ -18,19 +18,12 @@ module RuboCop
18
18
  # ignore Java interop code like Java::int
19
19
  return if java_type_node?(node)
20
20
 
21
- receiver, method_name, *_args = *node
22
-
23
- # discard methods with nil receivers and op methods(like [])
24
- return unless receiver && node.loc.dot && node.loc.dot.is?('::')
25
- return if allowed_name(method_name.to_s)
21
+ return unless node.receiver && node.double_colon?
22
+ return if node.camel_case_method?
26
23
 
27
24
  add_offense(node, :dot)
28
25
  end
29
26
 
30
- def allowed_name(method_name)
31
- method_name.match(/^[A-Z]/)
32
- end
33
-
34
27
  def autocorrect(node)
35
28
  ->(corrector) { corrector.replace(node.loc.dot, '.') }
36
29
  end
@@ -31,16 +31,14 @@ module RuboCop
31
31
  branch.begin_type? ? [*branch].last : branch
32
32
  end
33
33
 
34
- def lhs(node) # rubocop:disable Metrics/MethodLength
34
+ def lhs(node)
35
35
  case node.type
36
36
  when :send
37
37
  lhs_for_send(node)
38
38
  when :op_asgn
39
39
  "#{node.children[0].source} #{node.children[1]}= "
40
- when :and_asgn
41
- "#{node.children[0].source} &&= "
42
- when :or_asgn
43
- "#{node.children[0].source} ||= "
40
+ when :and_asgn, :or_asgn
41
+ "#{node.children[0].source} #{node.loc.operator.source} "
44
42
  when :casgn
45
43
  "#{node.children[1]} = "
46
44
  when *ConditionalAssignment::VARIABLE_ASSIGNMENT_TYPES
@@ -51,15 +49,18 @@ module RuboCop
51
49
  end
52
50
 
53
51
  def indent(cop, source)
54
- if cop.config[END_ALIGNMENT] &&
55
- cop.config[END_ALIGNMENT][ALIGN_WITH] &&
56
- cop.config[END_ALIGNMENT][ALIGN_WITH] == KEYWORD
52
+ conf = cop.config.for_cop(END_ALIGNMENT)
53
+ if conf[ALIGN_WITH] == KEYWORD
57
54
  ' ' * source.length
58
55
  else
59
56
  ''
60
57
  end
61
58
  end
62
59
 
60
+ def end_with_eq?(sym)
61
+ sym.to_s.end_with?(EQUAL)
62
+ end
63
+
63
64
  private
64
65
 
65
66
  def expand_elsif(node, elsif_branches = [])
@@ -75,22 +76,21 @@ module RuboCop
75
76
  end
76
77
 
77
78
  def lhs_for_send(node)
78
- receiver = node.receiver.nil? ? '' : node.receiver.source
79
- method_name = node.method_name
79
+ receiver = node.receiver ? node.receiver.source : ''
80
80
 
81
- if method_name == :[]=
82
- indices = node.children[2...-1].map(&:source).join(', ')
81
+ if node.method?(:[]=)
82
+ indices = node.arguments[0...-1].map(&:source).join(', ')
83
83
  "#{receiver}[#{indices}] = "
84
- elsif setter_method?(method_name)
85
- "#{receiver}.#{method_name[0...-1]} = "
84
+ elsif node.setter_method?
85
+ "#{receiver}.#{node.method_name[0...-1]} = "
86
86
  else
87
- "#{receiver} #{method_name} "
87
+ "#{receiver} #{node.method_name} "
88
88
  end
89
89
  end
90
90
 
91
91
  def setter_method?(method_name)
92
92
  method_name.to_s.end_with?(EQUAL) &&
93
- ![:!=, :==, :===, :>=, :<=].include?(method_name)
93
+ !%i(!= == === >= <=).include?(method_name)
94
94
  end
95
95
 
96
96
  def assignment_rhs_exist?(node)
@@ -205,23 +205,30 @@ module RuboCop
205
205
  ASSIGN_TO_CONDITION_MSG =
206
206
  'Assign variables inside of conditionals'.freeze
207
207
  VARIABLE_ASSIGNMENT_TYPES =
208
- [:casgn, :cvasgn, :gvasgn, :ivasgn, :lvasgn].freeze
208
+ %i(casgn cvasgn gvasgn ivasgn lvasgn).freeze
209
209
  ASSIGNMENT_TYPES = VARIABLE_ASSIGNMENT_TYPES +
210
- [:and_asgn, :or_asgn, :op_asgn, :masgn].freeze
210
+ %i(and_asgn or_asgn op_asgn masgn).freeze
211
211
  LINE_LENGTH = 'Metrics/LineLength'.freeze
212
212
  INDENTATION_WIDTH = 'Style/IndentationWidth'.freeze
213
213
  ENABLED = 'Enabled'.freeze
214
214
  MAX = 'Max'.freeze
215
215
  SINGLE_LINE_CONDITIONS_ONLY = 'SingleLineConditionsOnly'.freeze
216
216
  WIDTH = 'Width'.freeze
217
- METHODS = [:[]=, :<<, :=~, :!~, :<=>].freeze
218
- CONDITION_TYPES = [:if, :case].freeze
217
+
218
+ def_node_matcher :condition?, '{if case}'
219
+
220
+ # The shovel operator `<<` does not have its own type. It is a `send`
221
+ # type.
222
+ def_node_matcher :assignment_type?, <<-END
223
+ {
224
+ #{ASSIGNMENT_TYPES.join(' ')}
225
+ (send _recv {:[]= :<< :=~ :!~ :<=> #end_with_eq?} ...)
226
+ }
227
+ END
219
228
 
220
229
  ASSIGNMENT_TYPES.each do |type|
221
230
  define_method "on_#{type}" do |node|
222
231
  return if part_of_ignored_node?(node)
223
- return unless style == :assign_inside_condition
224
- return unless assignment_rhs_exist?(node)
225
232
 
226
233
  check_assignment_to_condition(node)
227
234
  end
@@ -229,8 +236,6 @@ module RuboCop
229
236
 
230
237
  def on_send(node)
231
238
  return unless assignment_type?(node)
232
- return unless style == :assign_inside_condition
233
- return unless assignment_rhs_exist?(node)
234
239
 
235
240
  check_assignment_to_condition(node)
236
241
  end
@@ -262,6 +267,8 @@ module RuboCop
262
267
  private
263
268
 
264
269
  def check_assignment_to_condition(node)
270
+ return unless style == :assign_inside_condition
271
+ return unless assignment_rhs_exist?(node)
265
272
  ignore_node(node)
266
273
 
267
274
  assignment = assignment_node(node)
@@ -270,8 +277,7 @@ module RuboCop
270
277
 
271
278
  _condition, *branches, else_branch = *assignment
272
279
  return unless else_branch # empty else
273
- return if single_line_conditions_only? &&
274
- [*branches, else_branch].any?(&:begin_type?)
280
+ return if allowed_single_line?([*branches, else_branch])
275
281
 
276
282
  add_offense(node, :expression, ASSIGN_TO_CONDITION_MSG)
277
283
  end
@@ -280,6 +286,10 @@ module RuboCop
280
286
  assignment.if_type? && assignment.ternary? && !include_ternary?
281
287
  end
282
288
 
289
+ def allowed_single_line?(branches)
290
+ single_line_conditions_only? && branches.any?(&:begin_type?)
291
+ end
292
+
283
293
  def autocorrect(node)
284
294
  if assignment_type?(node)
285
295
  move_assignment_inside_condition(node)
@@ -298,10 +308,6 @@ module RuboCop
298
308
  assignment
299
309
  end
300
310
 
301
- def condition?(node)
302
- CONDITION_TYPES.include?(node.type)
303
- end
304
-
305
311
  def move_assignment_outside_condition(node)
306
312
  if node.case_type?
307
313
  CaseCorrector.correct(self, node)
@@ -341,23 +347,10 @@ module RuboCop
341
347
  nodes.map(&:type).uniq.one?
342
348
  end
343
349
 
344
- # The shovel operator `<<` does not have its own type. It is a `send`
345
- # type.
346
- def assignment_type?(branch)
347
- return true if ASSIGNMENT_TYPES.include?(branch.type)
348
-
349
- if branch.send_type?
350
- return true if METHODS.include?(branch.method_name) ||
351
- branch.method_name.to_s.end_with?(EQUAL)
352
- end
353
-
354
- false
355
- end
356
-
357
350
  def check_node(node, branches)
358
351
  return if allowed_ternary?(node)
359
352
  return unless allowed_statements?(branches)
360
- return if single_line_conditions_only? && branches.any?(&:begin_type?)
353
+ return if allowed_single_line?(branches)
361
354
  return if correction_exceeds_line_limit?(node, branches)
362
355
 
363
356
  add_offense(node, :expression)
@@ -368,7 +361,7 @@ module RuboCop
368
361
 
369
362
  statements = branches.map { |branch| tail(branch) }
370
363
 
371
- lhs_all_match?(statements) && !statements.any?(&:masgn_type?) &&
364
+ lhs_all_match?(statements) && statements.none?(&:masgn_type?) &&
372
365
  assignment_types_match?(*statements)
373
366
  end
374
367
 
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # NewClass = something_that_returns_a_class
20
20
  # It's also ok to assign a class constant another class constant
21
21
  # SomeClass = SomeOtherClass
22
- return if value && [:send, :block, :const].include?(value.type)
22
+ return if value && %i(send block const).include?(value.type)
23
23
 
24
24
  add_offense(node, :name) if const_name !~ SNAKE_CASE
25
25
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module RuboCop
3
4
  module Cop
4
5
  module Style
@@ -8,7 +8,7 @@ module RuboCop
8
8
  include ConfigurableEnforcedStyle
9
9
 
10
10
  def on_send(node)
11
- return unless node.loc.dot
11
+ return unless node.dot?
12
12
 
13
13
  if proper_dot_position?(node)
14
14
  correct_style_detected
@@ -30,9 +30,7 @@ module RuboCop
30
30
  end
31
31
 
32
32
  def proper_dot_position?(node)
33
- receiver, _method_name, *_args = *node
34
-
35
- receiver_line = receiver.source_range.end.line
33
+ receiver_line = node.receiver.source_range.end.line
36
34
  selector_line = selector_range(node).line
37
35
 
38
36
  # receiver and selector are on the same line
@@ -61,15 +59,13 @@ module RuboCop
61
59
  end
62
60
 
63
61
  def autocorrect(node)
64
- receiver, _method_name, *_args = *node
65
-
66
62
  lambda do |corrector|
67
63
  corrector.remove(node.loc.dot)
68
64
  case style
69
65
  when :leading
70
66
  corrector.insert_before(selector_range(node), '.')
71
67
  when :trailing
72
- corrector.insert_after(receiver.source_range, '.')
68
+ corrector.insert_after(node.receiver.source_range, '.')
73
69
  end
74
70
  end
75
71
  end
@@ -25,7 +25,8 @@ module RuboCop
25
25
  def_node_matcher :double_negative?, '(send (send _ :!) :!)'
26
26
 
27
27
  def on_send(node)
28
- return unless double_negative?(node) && node.loc.selector.is?('!')
28
+ return unless double_negative?(node) && node.keyword_bang?
29
+
29
30
  add_offense(node, :selector)
30
31
  end
31
32
  end
@@ -18,7 +18,7 @@ module RuboCop
18
18
  # [1, 2].each_with_object({}) { |e, a| a[e] = e }
19
19
  class EachWithObject < Cop
20
20
  MSG = 'Use `each_with_object` instead of `%s`.'.freeze
21
- METHODS = [:inject, :reduce].freeze
21
+ METHODS = %i(inject reduce).freeze
22
22
 
23
23
  def_node_matcher :each_with_object_candidate?, <<-PATTERN
24
24
  (block $(send _ {:inject :reduce} _) $_ $_)
@@ -129,8 +129,8 @@ module RuboCop
129
129
  end
130
130
 
131
131
  def missing_else_style
132
- missing_config = config.for_cop('Style/MissingElse')
133
- missing_config['Enabled'] ? missing_config['EnforcedStyle'] : nil
132
+ missing_cfg = config.for_cop('Style/MissingElse')
133
+ missing_cfg.fetch('Enabled') ? missing_cfg['EnforcedStyle'] : nil
134
134
  end
135
135
  end
136
136
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for a newline after the final magic comment.
7
+ #
8
+ # @example
9
+ # # good
10
+ # # frozen_string_literal: true
11
+ #
12
+ # # Some documentation for Person
13
+ # class Person
14
+ # # Some code
15
+ # end
16
+ #
17
+ # # bad
18
+ # # frozen_string_literal: true
19
+ # # Some documentation for Person
20
+ # class Person
21
+ # # Some code
22
+ # end
23
+ class EmptyLineAfterMagicComment < Cop
24
+ MSG = 'Add a space after magic comments.'.freeze
25
+ BLANK_LINE = /\A\s*\z/
26
+
27
+ def investigate(source)
28
+ return unless source.ast &&
29
+ (last_magic_comment = last_magic_comment(source))
30
+ return if source[last_magic_comment.loc.line] =~ BLANK_LINE
31
+
32
+ offending_range =
33
+ source_range(source.buffer, last_magic_comment.loc.line + 1, 0)
34
+
35
+ add_offense(offending_range, offending_range)
36
+ end
37
+
38
+ def autocorrect(token)
39
+ lambda do |corrector|
40
+ corrector.insert_before(token, "\n")
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ # Find the last magic comment in the source file.
47
+ #
48
+ # Take all comments that precede the first line of code, select the
49
+ # magic comments, and return the last magic comment in the file.
50
+ #
51
+ # @return [Parser::Source::Comment] if magic comments exist before code
52
+ # @return [nil] otherwise
53
+ def last_magic_comment(source)
54
+ source
55
+ .comments
56
+ .take_while { |comment| comment.loc.line < source.ast.loc.line }
57
+ .select { |comment| MagicComment.parse(comment.text).any? }
58
+ .last
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end