rubocop 0.73.0 → 0.77.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.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/bin/console +1 -0
  4. data/config/default.yml +332 -295
  5. data/lib/rubocop.rb +46 -30
  6. data/lib/rubocop/ast/builder.rb +1 -0
  7. data/lib/rubocop/ast/node.rb +6 -8
  8. data/lib/rubocop/ast/node/block_node.rb +2 -0
  9. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +1 -12
  10. data/lib/rubocop/ast/node/return_node.rb +24 -0
  11. data/lib/rubocop/cli.rb +11 -227
  12. data/lib/rubocop/cli/command.rb +21 -0
  13. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  14. data/lib/rubocop/cli/command/base.rb +33 -0
  15. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  16. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  17. data/lib/rubocop/cli/command/show_cops.rb +73 -0
  18. data/lib/rubocop/cli/command/version.rb +17 -0
  19. data/lib/rubocop/cli/environment.rb +21 -0
  20. data/lib/rubocop/comment_config.rb +5 -4
  21. data/lib/rubocop/config.rb +28 -537
  22. data/lib/rubocop/config_loader.rb +21 -3
  23. data/lib/rubocop/config_loader_resolver.rb +4 -3
  24. data/lib/rubocop/config_obsoletion.rb +275 -0
  25. data/lib/rubocop/config_validator.rb +246 -0
  26. data/lib/rubocop/cop/autocorrect_logic.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  28. data/lib/rubocop/cop/commissioner.rb +15 -7
  29. data/lib/rubocop/cop/cop.rb +33 -9
  30. data/lib/rubocop/cop/corrector.rb +8 -7
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
  32. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  33. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  34. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
  35. data/lib/rubocop/cop/generator.rb +3 -3
  36. data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
  37. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  38. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  39. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
  40. data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
  41. data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
  42. data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +11 -2
  43. data/lib/rubocop/cop/layout/block_alignment.rb +2 -2
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
  46. data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -7
  48. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -2
  49. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -2
  50. data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
  51. data/lib/rubocop/cop/layout/extra_spacing.rb +15 -60
  52. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +12 -10
  53. data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
  54. data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +4 -4
  55. data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
  56. data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +8 -4
  57. data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +2 -2
  58. data/lib/rubocop/cop/layout/indentation_width.rb +19 -5
  59. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  60. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  61. data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
  62. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  63. data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
  64. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -0
  65. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
  66. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
  67. data/lib/rubocop/cop/layout/space_around_operators.rb +43 -24
  68. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
  69. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +8 -5
  70. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +7 -0
  71. data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
  72. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
  73. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  74. data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
  75. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  76. data/lib/rubocop/cop/lint/debugger.rb +1 -3
  77. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  78. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  79. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  80. data/lib/rubocop/cop/lint/erb_new_arguments.rb +61 -4
  81. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +10 -36
  82. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  83. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  84. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
  85. data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
  86. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  87. data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +24 -24
  88. data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +6 -8
  89. data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +1 -1
  90. data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +12 -7
  91. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +7 -7
  92. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  93. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  94. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -6
  95. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  96. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
  97. data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
  98. data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
  99. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
  100. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  101. data/lib/rubocop/cop/lint/void.rb +7 -26
  102. data/lib/rubocop/cop/message_annotator.rb +16 -7
  103. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  104. data/lib/rubocop/cop/metrics/line_length.rb +48 -42
  105. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  106. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
  107. data/lib/rubocop/cop/migration/department_name.rb +44 -0
  108. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  109. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  110. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  111. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  112. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  113. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  114. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  115. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  116. data/lib/rubocop/cop/mixin/statement_modifier.rb +5 -2
  117. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  118. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -6
  119. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  120. data/lib/rubocop/cop/naming/file_name.rb +12 -5
  121. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
  122. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  123. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +3 -3
  124. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  125. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  126. data/lib/rubocop/cop/offense.rb +18 -7
  127. data/lib/rubocop/cop/registry.rb +22 -1
  128. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  129. data/lib/rubocop/cop/style/alias.rb +1 -1
  130. data/lib/rubocop/cop/style/array_join.rb +1 -1
  131. data/lib/rubocop/cop/style/attr.rb +2 -2
  132. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  133. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +35 -16
  134. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  135. data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
  136. data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +5 -7
  138. data/lib/rubocop/cop/style/constant_visibility.rb +13 -2
  139. data/lib/rubocop/cop/style/copyright.rb +11 -7
  140. data/lib/rubocop/cop/style/documentation_method.rb +44 -0
  141. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +10 -4
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  143. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  144. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  145. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  146. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  147. data/lib/rubocop/cop/style/expand_path_arguments.rb +1 -1
  148. data/lib/rubocop/cop/style/format_string.rb +10 -7
  149. data/lib/rubocop/cop/style/format_string_token.rb +19 -68
  150. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +28 -33
  151. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  152. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  153. data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -15
  154. data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
  155. data/lib/rubocop/cop/style/inverse_methods.rb +19 -13
  156. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  157. data/lib/rubocop/cop/style/lambda.rb +0 -2
  158. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
  159. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -25
  160. data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
  161. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  162. data/lib/rubocop/cop/style/mixin_usage.rb +11 -1
  163. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  164. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
  165. data/lib/rubocop/cop/style/nested_modifier.rb +22 -4
  166. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
  167. data/lib/rubocop/cop/style/next.rb +5 -5
  168. data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
  169. data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
  170. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  171. data/lib/rubocop/cop/style/or_assignment.rb +6 -1
  172. data/lib/rubocop/cop/style/parentheses_around_condition.rb +14 -0
  173. data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
  174. data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
  175. data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
  176. data/lib/rubocop/cop/style/redundant_parentheses.rb +16 -7
  177. data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
  178. data/lib/rubocop/cop/style/redundant_return.rb +39 -29
  179. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  180. data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +5 -5
  181. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  182. data/lib/rubocop/cop/style/safe_navigation.rb +23 -3
  183. data/lib/rubocop/cop/style/semicolon.rb +13 -2
  184. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  185. data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
  186. data/lib/rubocop/cop/style/ternary_parentheses.rb +19 -0
  187. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  188. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  189. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  190. data/lib/rubocop/cop/team.rb +5 -0
  191. data/lib/rubocop/cop/util.rb +1 -1
  192. data/lib/rubocop/cop/utils/format_string.rb +120 -0
  193. data/lib/rubocop/cop/variable_force.rb +7 -5
  194. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  195. data/lib/rubocop/core_ext/string.rb +0 -24
  196. data/lib/rubocop/formatter/clang_style_formatter.rb +9 -6
  197. data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
  198. data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
  199. data/lib/rubocop/formatter/formatter_set.rb +16 -15
  200. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  201. data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
  202. data/lib/rubocop/formatter/tap_formatter.rb +18 -7
  203. data/lib/rubocop/magic_comment.rb +4 -0
  204. data/lib/rubocop/node_pattern.rb +3 -1
  205. data/lib/rubocop/options.rb +17 -22
  206. data/lib/rubocop/path_util.rb +1 -1
  207. data/lib/rubocop/processed_source.rb +5 -1
  208. data/lib/rubocop/rake_task.rb +1 -0
  209. data/lib/rubocop/result_cache.rb +22 -8
  210. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  211. data/lib/rubocop/runner.rb +55 -32
  212. data/lib/rubocop/target_finder.rb +12 -6
  213. data/lib/rubocop/version.rb +1 -1
  214. metadata +47 -32
  215. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
  216. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -22
@@ -35,6 +35,18 @@ module RuboCop
35
35
  # end
36
36
  # end
37
37
  #
38
+ # @example AllowMultipleReturnValues: false (default)
39
+ # # bad
40
+ # def test
41
+ # return x, y
42
+ # end
43
+ #
44
+ # @example AllowMultipleReturnValues: true
45
+ # # good
46
+ # def test
47
+ # return x, y
48
+ # end
49
+ #
38
50
  class RedundantReturn < Cop
39
51
  include RangeHelp
40
52
 
@@ -42,33 +54,42 @@ module RuboCop
42
54
  MULTI_RETURN_MSG = 'To return multiple values, use an array.'
43
55
 
44
56
  def on_def(node)
45
- return unless node.body
46
-
47
57
  check_branch(node.body)
48
58
  end
49
59
  alias on_defs on_def
50
60
 
51
- def autocorrect(node) # rubocop:disable Metrics/MethodLength
61
+ def autocorrect(node)
52
62
  lambda do |corrector|
53
- unless arguments?(node.children)
54
- corrector.replace(node.source_range, 'nil')
55
- next
63
+ if node.arguments?
64
+ correct_with_arguments(node, corrector)
65
+ else
66
+ correct_without_arguments(node, corrector)
56
67
  end
57
-
58
- return_value, = *node
59
- if node.children.size > 1
60
- add_brackets(corrector, node)
61
- elsif return_value.hash_type?
62
- add_braces(corrector, return_value) unless return_value.braces?
63
- end
64
- return_kw = range_with_surrounding_space(range: node.loc.keyword,
65
- side: :right)
66
- corrector.remove(return_kw)
67
68
  end
68
69
  end
69
70
 
70
71
  private
71
72
 
73
+ def correct_without_arguments(return_node, corrector)
74
+ corrector.replace(return_node.source_range, 'nil')
75
+ end
76
+
77
+ def correct_with_arguments(return_node, corrector)
78
+ if return_node.arguments.size > 1
79
+ add_brackets(corrector, return_node)
80
+ elsif hash_without_braces?(return_node.first_argument)
81
+ add_braces(corrector, return_node.first_argument)
82
+ end
83
+
84
+ keyword = range_with_surrounding_space(range: return_node.loc.keyword,
85
+ side: :right)
86
+ corrector.remove(keyword)
87
+ end
88
+
89
+ def hash_without_braces?(node)
90
+ node.hash_type? && !node.braces?
91
+ end
92
+
72
93
  def add_brackets(corrector, node)
73
94
  kids = node.children.map(&:source_range)
74
95
  corrector.insert_before(kids.first, '[')
@@ -81,13 +102,6 @@ module RuboCop
81
102
  corrector.insert_after(kids.last, '}')
82
103
  end
83
104
 
84
- def arguments?(args)
85
- return false if args.empty?
86
- return true if args.size > 1
87
-
88
- !args.first.begin_type? || !args.first.children.empty?
89
- end
90
-
91
105
  # rubocop:disable Metrics/CyclomaticComplexity
92
106
  def check_branch(node)
93
107
  return unless node
@@ -136,12 +150,8 @@ module RuboCop
136
150
  end
137
151
 
138
152
  def check_begin_node(node)
139
- expressions = *node
140
- last_expr = expressions.last
141
-
142
- return unless last_expr&.return_type?
143
-
144
- check_return_node(last_expr)
153
+ last_expr = node.children.last
154
+ check_branch(last_expr)
145
155
  end
146
156
 
147
157
  def allow_multiple_return_values?
@@ -83,9 +83,16 @@ module RuboCop
83
83
  on_argument(node)
84
84
  end
85
85
 
86
+ def on_masgn(node)
87
+ lhs, rhs = *node
88
+ lhs.children.each do |child|
89
+ add_lhs_to_local_variables_scopes(rhs, child.to_a.first)
90
+ end
91
+ end
92
+
86
93
  def on_lvasgn(node)
87
94
  lhs, rhs = *node
88
- @local_variables_scopes[rhs] << lhs
95
+ add_lhs_to_local_variables_scopes(rhs, lhs)
89
96
  end
90
97
 
91
98
  def on_send(node)
@@ -148,6 +155,16 @@ module RuboCop
148
155
 
149
156
  @allowed_send_nodes << node
150
157
  end
158
+
159
+ def add_lhs_to_local_variables_scopes(rhs, lhs)
160
+ if rhs&.send_type? && !rhs.arguments.empty?
161
+ rhs.arguments.each do |argument|
162
+ @local_variables_scopes[argument] << lhs
163
+ end
164
+ else
165
+ @local_variables_scopes[rhs] << lhs
166
+ end
167
+ end
151
168
  end
152
169
  end
153
170
  end
@@ -49,13 +49,13 @@ module RuboCop
49
49
  # # good
50
50
  # arr.max_by(&:foo)
51
51
  #
52
- class UnneededSort < Cop
52
+ class RedundantSort < Cop
53
53
  include RangeHelp
54
54
 
55
55
  MSG = 'Use `%<suggestion>s` instead of '\
56
56
  '`%<sorter>s...%<accessor_source>s`.'
57
57
 
58
- def_node_matcher :unneeded_sort?, <<~MATCHER
58
+ def_node_matcher :redundant_sort?, <<~MATCHER
59
59
  {
60
60
  (send $(send _ $:sort ...) ${:last :first})
61
61
  (send $(send _ $:sort ...) ${:[] :at :slice} {(int 0) (int -1)})
@@ -72,7 +72,7 @@ module RuboCop
72
72
  MATCHER
73
73
 
74
74
  def on_send(node)
75
- unneeded_sort?(node) do |sort_node, sorter, accessor|
75
+ redundant_sort?(node) do |sort_node, sorter, accessor|
76
76
  range = range_between(
77
77
  sort_node.loc.selector.begin_pos,
78
78
  node.loc.expression.end_pos
@@ -87,7 +87,7 @@ module RuboCop
87
87
  end
88
88
 
89
89
  def autocorrect(node)
90
- sort_node, sorter, accessor = unneeded_sort?(node)
90
+ sort_node, sorter, accessor = redundant_sort?(node)
91
91
 
92
92
  lambda do |corrector|
93
93
  # Remove accessor, e.g. `first` or `[-1]`.
@@ -127,7 +127,7 @@ module RuboCop
127
127
  end
128
128
 
129
129
  def base(accessor, arg)
130
- if accessor == :first || (arg&.zero?)
130
+ if accessor == :first || arg&.zero?
131
131
  'min'
132
132
  elsif accessor == :last || arg == -1
133
133
  'max'
@@ -5,16 +5,40 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks for uses of rescue in its modifier form.
7
7
  #
8
+ # The cop to check `rescue` in its modifier form is added for following
9
+ # reasons:
10
+ #
11
+ # * The syntax of modifier form `rescue` can be misleading because it
12
+ # might led us to believe that `rescue` handles the given exception
13
+ # but it actually rescue all exceptions to return the given rescue
14
+ # block. In this case, value returned by handle_error or
15
+ # SomeException.
16
+ #
17
+ # * Modifier form `rescue` would rescue all the exceptions. It would
18
+ # silently skip all exception or errors and handle the error.
19
+ # Example: If `NoMethodError` is raised, modifier form rescue would
20
+ # handle the exception.
21
+ #
8
22
  # @example
9
23
  # # bad
10
24
  # some_method rescue handle_error
11
25
  #
26
+ # # bad
27
+ # some_method rescue SomeException
28
+ #
12
29
  # # good
13
30
  # begin
14
31
  # some_method
15
32
  # rescue
16
33
  # handle_error
17
34
  # end
35
+ #
36
+ # # good
37
+ # begin
38
+ # some_method
39
+ # rescue SomeException
40
+ # handle_error
41
+ # end
18
42
  class RescueModifier < Cop
19
43
  include Alignment
20
44
  include RescueNode
@@ -112,14 +112,14 @@ module RuboCop
112
112
  end
113
113
 
114
114
  def autocorrect(node)
115
- _check, body, = node.node_parts
116
- _checked_variable, matching_receiver, = extract_parts(node)
117
- method_call, = matching_receiver.parent
115
+ body = node.node_parts[1]
116
+ method_call = method_call(node)
118
117
 
119
118
  lambda do |corrector|
120
119
  corrector.remove(begin_range(node, body))
121
120
  corrector.remove(end_range(node, body))
122
121
  corrector.insert_before(method_call.loc.dot, '&')
122
+ handle_comments(corrector, node, method_call)
123
123
 
124
124
  add_safe_nav_to_all_methods_in_chain(corrector, method_call, body)
125
125
  end
@@ -127,10 +127,30 @@ module RuboCop
127
127
 
128
128
  private
129
129
 
130
+ def handle_comments(corrector, node, method_call)
131
+ comments = comments(node)
132
+ return if comments.empty?
133
+
134
+ corrector.insert_before(method_call.loc.expression,
135
+ "#{comments.map(&:text).join("\n")}\n")
136
+ end
137
+
138
+ def comments(node)
139
+ processed_source.comments.select do |comment|
140
+ comment.loc.first_line > node.loc.first_line &&
141
+ comment.loc.last_line < node.loc.last_line
142
+ end
143
+ end
144
+
130
145
  def allowed_if_condition?(node)
131
146
  node.else? || node.elsif? || node.ternary?
132
147
  end
133
148
 
149
+ def method_call(node)
150
+ _checked_variable, matching_receiver, = extract_parts(node)
151
+ matching_receiver.parent
152
+ end
153
+
134
154
  def extract_parts(node)
135
155
  case node.type
136
156
  when :if
@@ -6,6 +6,9 @@ module RuboCop
6
6
  # This cop checks for multiple expressions placed on the same line.
7
7
  # It also checks for lines terminated with a semicolon.
8
8
  #
9
+ # This cop has `AllowAsExpressionSeparator` configuration option.
10
+ # It allows `;` to separate several expressions on the same line.
11
+ #
9
12
  # @example
10
13
  # # bad
11
14
  # foo = 1; bar = 2;
@@ -15,6 +18,14 @@ module RuboCop
15
18
  # foo = 1
16
19
  # bar = 2
17
20
  # baz = 3
21
+ #
22
+ # @example AllowAsExpressionSeparator: false (default)
23
+ # # bad
24
+ # foo = 1; bar = 2
25
+ #
26
+ # @example AllowAsExpressionSeparator: true
27
+ # # good
28
+ # foo = 1; bar = 2
18
29
  class Semicolon < Cop
19
30
  include RangeHelp
20
31
 
@@ -36,8 +47,8 @@ module RuboCop
36
47
  return if exprs.size < 2
37
48
 
38
49
  # create a map matching lines to the number of expressions on them
39
- exprs_lines = exprs.map { |e| e.source_range.line }
40
- lines = exprs_lines.group_by { |i| i }
50
+ exprs_lines = exprs.map(&:first_line)
51
+ lines = exprs_lines.group_by(&:itself)
41
52
 
42
53
  lines.each do |line, expr_on_line|
43
54
  # Every line with more than one expression on it is a
@@ -13,10 +13,17 @@ module RuboCop
13
13
  # def @table.columns; super; end
14
14
  #
15
15
  # # good
16
- # def no_op; end
17
16
  # def self.resource_class=(klass); end
18
17
  # def @table.columns; end
19
18
  #
19
+ # @example AllowIfMethodIsEmpty: true (default)
20
+ # # good
21
+ # def no_op; end
22
+ #
23
+ # @example AllowIfMethodIsEmpty: false
24
+ # # bad
25
+ # def no_op; end
26
+ #
20
27
  class SingleLineMethods < Cop
21
28
  include Alignment
22
29
 
@@ -160,17 +160,15 @@ module RuboCop
160
160
  end
161
161
 
162
162
  def format_message(english, regular, global)
163
- if !regular.empty? && !english.empty?
163
+ if regular.empty?
164
+ format(MSG_ENGLISH, prefer: format_list(english), global: global)
165
+ elsif english.empty?
166
+ format(MSG_REGULAR, prefer: format_list(regular), global: global)
167
+ else
164
168
  format(MSG_BOTH,
165
169
  prefer: format_list(english),
166
170
  regular: format_list(regular),
167
171
  global: global)
168
- elsif !regular.empty?
169
- format(MSG_REGULAR, prefer: format_list(regular), global: global)
170
- elsif !english.empty?
171
- format(MSG_ENGLISH, prefer: format_list(english), global: global)
172
- else
173
- raise 'Bug in SpecialGlobalVars - global var w/o preferred vars!'
174
172
  end
175
173
  end
176
174
 
@@ -8,6 +8,11 @@ module RuboCop
8
8
  # parentheses using `EnforcedStyle`. Omission is only enforced when
9
9
  # removing the parentheses won't cause a different behavior.
10
10
  #
11
+ # `AllowSafeAssignment` option for safe assignment.
12
+ # By safe assignment we mean putting parentheses around
13
+ # an assignment to indicate "I know I'm using an assignment
14
+ # as a condition. It's not a mistake."
15
+ #
11
16
  # @example EnforcedStyle: require_no_parentheses (default)
12
17
  # # bad
13
18
  # foo = (bar?) ? a : b
@@ -40,6 +45,15 @@ module RuboCop
40
45
  # foo = bar? ? a : b
41
46
  # foo = bar.baz? ? a : b
42
47
  # foo = (bar && baz) ? a : b
48
+ #
49
+ # @example AllowSafeAssignment: true (default)
50
+ # # good
51
+ # foo = (bar = baz) ? a : b
52
+ #
53
+ # @example AllowSafeAssignment: false
54
+ # # bad
55
+ # foo = (bar = baz) ? a : b
56
+ #
43
57
  class TernaryParentheses < Cop
44
58
  include SafeAssignment
45
59
  include ConfigurableEnforcedStyle
@@ -53,11 +67,16 @@ module RuboCop
53
67
  ' complex conditions.'
54
68
 
55
69
  def on_if(node)
70
+ return if only_closing_parenthesis_is_last_line?(node.condition)
56
71
  return unless node.ternary? && !infinite_loop? && offense?(node)
57
72
 
58
73
  add_offense(node, location: node.source_range)
59
74
  end
60
75
 
76
+ def only_closing_parenthesis_is_last_line?(condition)
77
+ condition.source.split("\n").last == ')'
78
+ end
79
+
61
80
  def autocorrect(node)
62
81
  condition = node.condition
63
82
 
@@ -42,7 +42,7 @@ module RuboCop
42
42
  def on_def(node)
43
43
  return unless trailing_end?(node)
44
44
 
45
- add_offense(node.to_a.last, location: end_token(node).pos)
45
+ add_offense(node, location: end_token(node).pos)
46
46
  end
47
47
 
48
48
  def autocorrect(node)
@@ -61,7 +61,7 @@ module RuboCop
61
61
  end
62
62
 
63
63
  def end_token(node)
64
- @end_token ||= tokens(node).reverse.find(&:end?)
64
+ tokens(node).reverse.find(&:end?)
65
65
  end
66
66
 
67
67
  def body_and_end_on_same_line?(node)
@@ -69,10 +69,8 @@ module RuboCop
69
69
  end
70
70
 
71
71
  def token_before_end(node)
72
- @token_before_end ||= begin
73
- i = tokens(node).index(end_token(node))
74
- tokens(node)[i - 1]
75
- end
72
+ i = tokens(node).index(end_token(node))
73
+ tokens(node)[i - 1]
76
74
  end
77
75
 
78
76
  def break_line_before_end(node, corrector)
@@ -60,7 +60,7 @@ module RuboCop
60
60
  when :module
61
61
  return true
62
62
  else
63
- return true if pnode.method_name == :instance_eval
63
+ return true if pnode.method?(:instance_eval)
64
64
  end
65
65
  end
66
66
  false
@@ -95,9 +95,9 @@ module RuboCop
95
95
  cop_config['IgnoreClassMethods']
96
96
  end
97
97
 
98
- def whitelist
99
- whitelist = cop_config['Whitelist']
100
- Array(whitelist).map(&:to_sym) + [:initialize]
98
+ def allowed_methods
99
+ allowed_methods = cop_config['AllowedMethods']
100
+ Array(allowed_methods).map(&:to_sym) + [:initialize]
101
101
  end
102
102
 
103
103
  def dsl_writer?(method_name)
@@ -124,7 +124,7 @@ module RuboCop
124
124
  PATTERN
125
125
 
126
126
  def allowed_method?(node)
127
- whitelist.include?(node.method_name) ||
127
+ allowed_methods.include?(node.method_name) ||
128
128
  exact_name_match? && !names_match?(node)
129
129
  end
130
130