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
@@ -16,10 +16,7 @@ module RuboCop
16
16
  include ConfigurableEnforcedStyle
17
17
 
18
18
  def on_send(node)
19
- _receiver, selector, = *node
20
-
21
- # we care only about `call` methods
22
- return unless selector == :call
19
+ return unless node.receiver && node.method?(:call)
23
20
 
24
21
  if offense?(node)
25
22
  add_offense(node, :expression) { opposite_style_detected }
@@ -31,17 +28,16 @@ module RuboCop
31
28
  private
32
29
 
33
30
  def offense?(node)
34
- # lambda.() does not have a selector
35
- style == :call && node.loc.selector.nil? ||
36
- style == :braces && node.loc.selector
31
+ explicit_style? && node.implicit_call? ||
32
+ implicit_style? && !node.implicit_call?
37
33
  end
38
34
 
39
35
  def autocorrect(node)
40
36
  lambda do |corrector|
41
- if style == :call
42
- receiver_node, = *node
43
- receiver = receiver_node.source
37
+ if explicit_style?
38
+ receiver = node.receiver.source
44
39
  replacement = node.source.sub("#{receiver}.", "#{receiver}.call")
40
+
45
41
  corrector.replace(node.source_range, replacement)
46
42
  else
47
43
  corrector.remove(node.loc.selector)
@@ -50,12 +46,20 @@ module RuboCop
50
46
  end
51
47
 
52
48
  def message(_node)
53
- if style == :call
49
+ if explicit_style?
54
50
  'Prefer the use of `lambda.call(...)` over `lambda.(...)`.'
55
51
  else
56
52
  'Prefer the use of `lambda.(...)` over `lambda.call(...)`.'
57
53
  end
58
54
  end
55
+
56
+ def implicit_style?
57
+ style == :braces
58
+ end
59
+
60
+ def explicit_style?
61
+ style == :call
62
+ end
59
63
  end
60
64
  end
61
65
  end
@@ -22,11 +22,11 @@ module RuboCop
22
22
  class LineEndConcatenation < Cop
23
23
  MSG = 'Use `\\` instead of `+` or `<<` to concatenate ' \
24
24
  'those strings.'.freeze
25
- CONCAT_TOKEN_TYPES = [:tPLUS, :tLSHFT].freeze
25
+ CONCAT_TOKEN_TYPES = %i(tPLUS tLSHFT).freeze
26
26
  SIMPLE_STRING_TOKEN_TYPE = :tSTRING
27
- COMPLEX_STRING_EDGE_TOKEN_TYPES = [:tSTRING_BEG, :tSTRING_END].freeze
28
- HIGH_PRECEDENCE_OP_TOKEN_TYPES = [:tSTAR2, :tPERCENT, :tDOT,
29
- :tLBRACK2].freeze
27
+ COMPLEX_STRING_EDGE_TOKEN_TYPES = %i(tSTRING_BEG tSTRING_END).freeze
28
+ HIGH_PRECEDENCE_OP_TOKEN_TYPES = %i(tSTAR2 tPERCENT tDOT
29
+ tLBRACK2).freeze
30
30
  QUOTE_DELIMITERS = %w(' ").freeze
31
31
 
32
32
  def investigate(processed_source)
@@ -4,29 +4,41 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # This cop checks presence of parentheses in method calls containing
7
- # parameters.
8
- # As in popular Ruby's frameworks a lot of methods should always be
9
- # called without parentheses,
10
- # users can ignore them by passing their names to IgnoredMethods option.
7
+ # parameters. By default, macro methods are ignored. Additional methods
8
+ # can be added to the `IgnoredMethods` list.
11
9
  #
12
10
  # @example
11
+ #
13
12
  # # bad
14
13
  # array.delete e
15
14
  #
16
15
  # # good
17
16
  # array.delete(e)
18
17
  #
19
- # # good if `puts` is listed in IgnoredMethods
18
+ # # okay with `puts` listed in `IgnoredMethods`
20
19
  # puts 'test'
20
+ #
21
+ # # IgnoreMacros: true (default)
22
+ #
23
+ # # good
24
+ # class Foo
25
+ # bar :baz
26
+ # end
27
+ #
28
+ # # IgnoreMacros: false
29
+ #
30
+ # # bad
31
+ # class Foo
32
+ # bar :baz
33
+ # end
21
34
  class MethodCallWithArgsParentheses < Cop
22
35
  MSG = 'Use parentheses for method calls with arguments.'.freeze
23
36
 
24
37
  def on_send(node)
25
- _receiver, method_name, *args = *node
26
- return if ignored_list.include?(method_name)
27
- return if args.empty?
38
+ return if ignored_list.include?(node.method_name)
39
+ return unless node.arguments? && !node.parenthesized?
28
40
  return if operator_call?(node)
29
- return if parentheses?(node)
41
+ return if ignore_macros? && node.macro?
30
42
 
31
43
  add_offense(node, :selector)
32
44
  end
@@ -59,16 +71,16 @@ module RuboCop
59
71
  cop_config['IgnoredMethods'].map(&:to_sym)
60
72
  end
61
73
 
74
+ def ignore_macros?
75
+ cop_config['IgnoreMacros']
76
+ end
77
+
62
78
  def parentheses?(node)
63
79
  node.loc.begin
64
80
  end
65
81
 
66
82
  def operator_call?(node)
67
- node.loc.operator || (reciever?(node) && !node.loc.dot)
68
- end
69
-
70
- def reciever?(node)
71
- !node.children[0].nil?
83
+ node.operator_method?
72
84
  end
73
85
 
74
86
  def args_begin(node)
@@ -15,16 +15,13 @@ module RuboCop
15
15
  MSG = 'Do not use parentheses for method calls with ' \
16
16
  'no arguments.'.freeze
17
17
 
18
- ASGN_NODES = [:lvasgn, :masgn] + SHORTHAND_ASGN_NODES
18
+ ASGN_NODES = %i(lvasgn masgn) + SHORTHAND_ASGN_NODES
19
19
 
20
20
  def on_send(node)
21
- _receiver, method_name, *args = *node
22
-
23
- # methods starting with a capital letter should be skipped
24
- return if method_name =~ /\A[A-Z]/
25
- return unless args.empty? && node.loc.begin
21
+ return if node.camel_case_method?
22
+ return unless !node.arguments? && node.parenthesized?
26
23
  return if same_name_assignment?(node)
27
- return if lambda_call_syntax?(node)
24
+ return if node.implicit_call?
28
25
  return if node.keyword_not?
29
26
 
30
27
  add_offense(node, :begin)
@@ -40,14 +37,12 @@ module RuboCop
40
37
  private
41
38
 
42
39
  def same_name_assignment?(node)
43
- _receiver, method_name, *_args = *node
44
-
45
40
  any_assignment?(node) do |asgn_node|
46
41
  if asgn_node.masgn_type?
47
- next variable_in_mass_assignment?(method_name, asgn_node)
42
+ next variable_in_mass_assignment?(node.method_name, asgn_node)
48
43
  end
49
44
 
50
- asgn_node.loc.name.source == method_name.to_s
45
+ asgn_node.loc.name.source == node.method_name.to_s
51
46
  end
52
47
  end
53
48
 
@@ -74,11 +69,6 @@ module RuboCop
74
69
 
75
70
  var_nodes.map { |n| n.to_a.first }.include?(variable_name)
76
71
  end
77
-
78
- # don't check `lambda.()` syntax; the Style/LambdaCall cop does that
79
- def lambda_call_syntax?(node)
80
- node.method_name == :call && node.loc.selector.nil?
81
- end
82
72
  end
83
73
  end
84
74
  end
@@ -27,12 +27,15 @@ module RuboCop
27
27
 
28
28
  def on_send(node)
29
29
  return if ignored_node?(node)
30
- receiver, _method_name, *_args = *node
30
+
31
+ receiver = node.receiver
32
+
31
33
  return unless receiver && receiver.block_type? &&
32
34
  receiver.loc.end.is?('end')
33
35
 
34
36
  range = range_between(receiver.loc.end.begin_pos,
35
37
  node.source_range.end_pos)
38
+
36
39
  add_offense(nil, range)
37
40
  end
38
41
  end
@@ -75,7 +75,7 @@ module RuboCop
75
75
  end
76
76
 
77
77
  def unless_else_cop_enabled?
78
- unless_else_config['Enabled'] if unless_else_config
78
+ unless_else_config.fetch('Enabled')
79
79
  end
80
80
 
81
81
  def unless_else_config
@@ -83,11 +83,12 @@ module RuboCop
83
83
  end
84
84
 
85
85
  def empty_else_cop_enabled?
86
- empty_else_config['Enabled'] if empty_else_config
86
+ empty_else_config.fetch('Enabled')
87
87
  end
88
88
 
89
89
  def empty_else_style
90
- empty_else_config['EnforcedStyle'].to_sym if empty_else_config
90
+ return unless empty_else_config.key?('EnforcedStyle')
91
+ empty_else_config['EnforcedStyle'].to_sym
91
92
  end
92
93
 
93
94
  def empty_else_config
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for grouping of mixins in `class` and `module` bodies.
7
+ # By default it enforces mixins to be placed in separate declarations,
8
+ # but it can be configured to enforce grouping them in one declaration.
9
+ #
10
+ # @example
11
+ #
12
+ # EnforcedStyle: separated (default)
13
+ #
14
+ # @bad
15
+ # class Foo
16
+ # include Bar, Qox
17
+ # end
18
+ #
19
+ # @good
20
+ # class Foo
21
+ # include Qox
22
+ # include Bar
23
+ # end
24
+ #
25
+ # EnforcedStyle: grouped
26
+ #
27
+ # @bad
28
+ # class Foo
29
+ # extend Bar
30
+ # extend Qox
31
+ # end
32
+ #
33
+ # @good
34
+ # class Foo
35
+ # extend Qox, Bar
36
+ # end
37
+ class MixinGrouping < Cop
38
+ include ConfigurableEnforcedStyle
39
+
40
+ MIXIN_METHODS = %i(extend include prepend).freeze
41
+ MSG = 'Put `%s` mixins in %s.'.freeze
42
+
43
+ def on_send(node)
44
+ return unless MIXIN_METHODS.include?(node.method_name)
45
+
46
+ check(node)
47
+ end
48
+
49
+ private
50
+
51
+ def check(send_node)
52
+ if separated_style?
53
+ check_separated_style(send_node)
54
+ else
55
+ check_grouped_style(send_node)
56
+ end
57
+ end
58
+
59
+ def check_grouped_style(send_node)
60
+ return unless sibling_mixins?(send_node)
61
+
62
+ add_offense(send_node, :expression)
63
+ end
64
+
65
+ def check_separated_style(send_node)
66
+ return if send_node.arguments.one?
67
+
68
+ add_offense(send_node, :expression)
69
+ end
70
+
71
+ def sibling_mixins?(send_node)
72
+ siblings = send_node.parent.each_child_node(:send)
73
+ .reject { |sibling| sibling == send_node }
74
+
75
+ siblings.any? do |sibling_node|
76
+ sibling_node.method_name == send_node.method_name
77
+ end
78
+ end
79
+
80
+ def message(send_node)
81
+ suffix =
82
+ separated_style? ? 'separate statements' : 'a single statement'
83
+
84
+ format(MSG, send_node.method_name, suffix)
85
+ end
86
+
87
+ def grouped_style?
88
+ style == :grouped
89
+ end
90
+
91
+ def separated_style?
92
+ style == :separated
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -3,11 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks that multiline memoizations are wrapped in a `begin`
7
- # and `end` block.
6
+ # This cop checks expressions wrapping styles for multiline memoization.
8
7
  #
9
8
  # @example
10
9
  #
10
+ # # EnforcedStyle: keyword (default)
11
+ #
11
12
  # @bad
12
13
  # foo ||= (
13
14
  # bar
@@ -19,13 +20,31 @@ module RuboCop
19
20
  # bar
20
21
  # baz
21
22
  # end
23
+ #
24
+ # @example
25
+ #
26
+ # # EnforcedStyle: braces
27
+ #
28
+ # @bad
29
+ # foo ||= begin
30
+ # bar
31
+ # baz
32
+ # end
33
+ #
34
+ # @good
35
+ # foo ||= (
36
+ # bar
37
+ # baz
38
+ # )
22
39
  class MultilineMemoization < Cop
40
+ include ConfigurableEnforcedStyle
41
+
23
42
  MSG = 'Wrap multiline memoization blocks in `begin` and `end`.'.freeze
24
43
 
25
44
  def on_or_asgn(node)
26
45
  _lhs, rhs = *node
27
46
 
28
- return unless rhs.multiline? && rhs.begin_type?
47
+ return unless bad_rhs?(rhs)
29
48
 
30
49
  add_offense(rhs, node.source_range, MSG)
31
50
  end
@@ -34,8 +53,22 @@ module RuboCop
34
53
 
35
54
  def autocorrect(node)
36
55
  lambda do |corrector|
37
- corrector.replace(node.loc.begin, 'begin')
38
- corrector.replace(node.loc.end, 'end')
56
+ if style == :keyword
57
+ corrector.replace(node.loc.begin, 'begin')
58
+ corrector.replace(node.loc.end, 'end')
59
+ else
60
+ corrector.replace(node.loc.begin, '(')
61
+ corrector.replace(node.loc.end, ')')
62
+ end
63
+ end
64
+ end
65
+
66
+ def bad_rhs?(rhs)
67
+ return false unless rhs.multiline?
68
+ if style == :keyword
69
+ rhs.begin_type?
70
+ else
71
+ rhs.kwbegin_type?
39
72
  end
40
73
  end
41
74
  end
@@ -79,9 +79,7 @@ module RuboCop
79
79
  private
80
80
 
81
81
  def children(node)
82
- _receiver, _method_name, *args = *node
83
-
84
- args
82
+ node.arguments
85
83
  end
86
84
 
87
85
  def ignored_literal?(node)
@@ -90,6 +88,7 @@ module RuboCop
90
88
 
91
89
  def single_line_ignoring_receiver?(node)
92
90
  return false unless node.loc.begin && node.loc.end
91
+
93
92
  node.loc.begin.line == node.loc.end.line
94
93
  end
95
94
  end
@@ -8,15 +8,15 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  # # bad
11
- # while a
11
+ # while myvariable
12
12
  # .b
13
- # something
13
+ # # do something
14
14
  # end
15
15
  #
16
16
  # # good, EnforcedStyle: aligned
17
- # while a
17
+ # while myvariable
18
18
  # .b
19
- # something
19
+ # # do something
20
20
  # end
21
21
  #
22
22
  # # good, EnforcedStyle: aligned
@@ -24,11 +24,29 @@ module RuboCop
24
24
  # .b
25
25
  # .c
26
26
  #
27
- # # good, EnforcedStyle: indented
28
- # while a
29
- # .b
30
- # something
27
+ # # good, EnforcedStyle: indented,
28
+ # IndentationWidth: 2
29
+ # while myvariable
30
+ # .b
31
+ #
32
+ # # do something
33
+ # end
34
+ #
35
+ # # good, EnforcedStyle: indented_relative_to_receiver,
36
+ # IndentationWidth: 2
37
+ # while myvariable
38
+ # .a
39
+ # .b
40
+ #
41
+ # # do something
31
42
  # end
43
+ #
44
+ # # good, EnforcedStyle: indented_relative_to_receiver,
45
+ # IndentationWidth: 2
46
+ # myvariable = Thing
47
+ # .a
48
+ # .b
49
+ # .c
32
50
  class MultilineMethodCallIndentation < Cop
33
51
  include ConfigurableEnforcedStyle
34
52
  include AutocorrectAlignment
@@ -112,15 +130,15 @@ module RuboCop
112
130
  end
113
131
 
114
132
  def alignment_base(node, rhs, given_style)
115
- return nil if given_style == :indented
116
-
117
- if given_style == :indented_relative_to_receiver
118
- receiver_base = receiver_alignment_base(node)
119
- return receiver_base if receiver_base
133
+ case given_style
134
+ when :aligned
135
+ semantic_alignment_base(node, rhs) ||
136
+ syntactic_alignment_base(node, rhs)
137
+ when :indented
138
+ nil
139
+ when :indented_relative_to_receiver
140
+ receiver_alignment_base(node)
120
141
  end
121
-
122
- semantic_alignment_base(node, rhs) ||
123
- syntactic_alignment_base(node, rhs)
124
142
  end
125
143
 
126
144
  def syntactic_alignment_base(lhs, rhs)
@@ -162,10 +180,11 @@ module RuboCop
162
180
  # .b
163
181
  # .c
164
182
  def receiver_alignment_base(node)
165
- node = semantic_alignment_node(node)
166
- return unless node
183
+ node = node.receiver while node.receiver
184
+ node = node.parent
185
+ node = node.parent until node.loc.dot
167
186
 
168
- node.receiver.source_range
187
+ node.receiver.source_range if node
169
188
  end
170
189
 
171
190
  def semantic_alignment_node(node)