rubocop 0.72.0 → 0.76.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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/bin/console +1 -0
  4. data/config/default.yml +93 -56
  5. data/lib/rubocop.rb +21 -10
  6. data/lib/rubocop/ast/builder.rb +1 -0
  7. data/lib/rubocop/ast/node.rb +12 -14
  8. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +4 -4
  9. data/lib/rubocop/ast/node/return_node.rb +24 -0
  10. data/lib/rubocop/ast/traversal.rb +3 -3
  11. data/lib/rubocop/cli.rb +7 -4
  12. data/lib/rubocop/comment_config.rb +5 -4
  13. data/lib/rubocop/config.rb +28 -537
  14. data/lib/rubocop/config_loader.rb +21 -3
  15. data/lib/rubocop/config_loader_resolver.rb +4 -3
  16. data/lib/rubocop/config_obsoletion.rb +222 -0
  17. data/lib/rubocop/config_validator.rb +248 -0
  18. data/lib/rubocop/cop/autocorrect_logic.rb +71 -1
  19. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
  20. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  21. data/lib/rubocop/cop/commissioner.rb +18 -16
  22. data/lib/rubocop/cop/cop.rb +49 -14
  23. data/lib/rubocop/cop/corrector.rb +10 -10
  24. data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
  25. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +2 -2
  26. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  27. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  28. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  29. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  30. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  31. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
  32. data/lib/rubocop/cop/generator.rb +4 -4
  33. data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
  34. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  35. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -2
  36. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  37. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -2
  38. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  39. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -2
  40. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
  41. data/lib/rubocop/cop/layout/align_hash.rb +6 -2
  42. data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
  43. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  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 +14 -59
  52. data/lib/rubocop/cop/layout/indent_assignment.rb +10 -1
  53. data/lib/rubocop/cop/layout/indent_first_argument.rb +10 -8
  54. data/lib/rubocop/cop/layout/indent_first_hash_element.rb +1 -1
  55. data/lib/rubocop/cop/layout/indent_heredoc.rb +4 -3
  56. data/lib/rubocop/cop/layout/indentation_width.rb +20 -6
  57. data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -0
  58. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  59. data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
  60. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +20 -4
  61. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
  62. data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
  63. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
  64. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +8 -5
  65. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +21 -2
  66. data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
  67. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
  68. data/lib/rubocop/cop/layout/tab.rb +10 -22
  69. data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
  70. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  71. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -1
  72. data/lib/rubocop/cop/lint/debugger.rb +4 -6
  73. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
  74. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  75. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  76. data/lib/rubocop/cop/lint/erb_new_arguments.rb +62 -5
  77. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +11 -37
  78. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  79. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -1
  80. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  81. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
  82. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  83. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -3
  84. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  85. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  86. data/lib/rubocop/cop/lint/number_conversion.rb +3 -3
  87. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  88. data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +24 -24
  89. data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +6 -8
  90. data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +2 -2
  91. data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +12 -7
  92. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  93. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  94. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +10 -11
  95. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  96. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  97. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
  98. data/lib/rubocop/cop/lint/unified_integer.rb +1 -1
  99. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  100. data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
  101. data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
  102. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
  103. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -2
  104. data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -6
  105. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  106. data/lib/rubocop/cop/lint/void.rb +7 -26
  107. data/lib/rubocop/cop/message_annotator.rb +16 -7
  108. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  109. data/lib/rubocop/cop/metrics/class_length.rb +1 -1
  110. data/lib/rubocop/cop/metrics/line_length.rb +7 -4
  111. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  112. data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
  113. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
  114. data/lib/rubocop/cop/migration/department_name.rb +44 -0
  115. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  116. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  117. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  118. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -1
  119. data/lib/rubocop/cop/mixin/enforce_superclass.rb +4 -4
  120. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  121. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  122. data/lib/rubocop/cop/mixin/method_complexity.rb +3 -2
  123. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  124. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  125. data/lib/rubocop/cop/mixin/safe_mode.rb +2 -0
  126. data/lib/rubocop/cop/mixin/statement_modifier.rb +5 -2
  127. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  128. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -6
  129. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  130. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  131. data/lib/rubocop/cop/naming/file_name.rb +12 -5
  132. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  133. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  134. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  135. data/lib/rubocop/cop/offense.rb +18 -7
  136. data/lib/rubocop/cop/registry.rb +22 -1
  137. data/lib/rubocop/cop/security/eval.rb +1 -1
  138. data/lib/rubocop/cop/security/json_load.rb +1 -1
  139. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  140. data/lib/rubocop/cop/security/open.rb +1 -1
  141. data/lib/rubocop/cop/security/yaml_load.rb +1 -1
  142. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  143. data/lib/rubocop/cop/style/alias.rb +1 -1
  144. data/lib/rubocop/cop/style/attr.rb +2 -2
  145. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  146. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +35 -16
  147. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  148. data/lib/rubocop/cop/style/colon_method_call.rb +1 -1
  149. data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
  150. data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
  151. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -8
  152. data/lib/rubocop/cop/style/constant_visibility.rb +14 -3
  153. data/lib/rubocop/cop/style/copyright.rb +11 -7
  154. data/lib/rubocop/cop/style/date_time.rb +3 -3
  155. data/lib/rubocop/cop/style/dir.rb +1 -1
  156. data/lib/rubocop/cop/style/documentation_method.rb +45 -1
  157. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +55 -0
  158. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  159. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  160. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  161. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  162. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  163. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  164. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  165. data/lib/rubocop/cop/style/expand_path_arguments.rb +4 -4
  166. data/lib/rubocop/cop/style/float_division.rb +4 -4
  167. data/lib/rubocop/cop/style/format_string.rb +17 -14
  168. data/lib/rubocop/cop/style/format_string_token.rb +19 -68
  169. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +28 -33
  170. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  171. data/lib/rubocop/cop/style/hash_syntax.rb +4 -4
  172. data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -15
  173. data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
  174. data/lib/rubocop/cop/style/inverse_methods.rb +21 -15
  175. data/lib/rubocop/cop/style/lambda.rb +0 -2
  176. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
  177. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -25
  178. data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
  179. data/lib/rubocop/cop/style/min_max.rb +1 -1
  180. data/lib/rubocop/cop/style/mixin_usage.rb +12 -2
  181. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  182. data/lib/rubocop/cop/style/multiline_when_then.rb +55 -0
  183. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  184. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  185. data/lib/rubocop/cop/style/nested_modifier.rb +22 -4
  186. data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
  187. data/lib/rubocop/cop/style/numeric_predicate.rb +3 -3
  188. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  189. data/lib/rubocop/cop/style/or_assignment.rb +8 -3
  190. data/lib/rubocop/cop/style/parentheses_around_condition.rb +15 -1
  191. data/lib/rubocop/cop/style/random_with_offset.rb +6 -6
  192. data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
  193. data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
  194. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -2
  195. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  196. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  197. data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
  198. data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -6
  199. data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
  200. data/lib/rubocop/cop/style/redundant_return.rb +37 -21
  201. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  202. data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +4 -4
  203. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  204. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  205. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  206. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  207. data/lib/rubocop/cop/style/safe_navigation.rb +24 -4
  208. data/lib/rubocop/cop/style/sample.rb +1 -1
  209. data/lib/rubocop/cop/style/semicolon.rb +13 -2
  210. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  211. data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
  212. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  213. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -2
  214. data/lib/rubocop/cop/style/strip.rb +1 -1
  215. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
  216. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  217. data/lib/rubocop/cop/style/ternary_parentheses.rb +20 -1
  218. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  219. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  220. data/lib/rubocop/cop/style/unpack_first.rb +1 -1
  221. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  222. data/lib/rubocop/cop/style/zero_length_predicate.rb +5 -5
  223. data/lib/rubocop/cop/team.rb +15 -14
  224. data/lib/rubocop/cop/util.rb +1 -1
  225. data/lib/rubocop/cop/utils/format_string.rb +120 -0
  226. data/lib/rubocop/cop/variable_force.rb +7 -5
  227. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  228. data/lib/rubocop/core_ext/string.rb +0 -24
  229. data/lib/rubocop/error.rb +23 -0
  230. data/lib/rubocop/formatter/clang_style_formatter.rb +8 -3
  231. data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
  232. data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
  233. data/lib/rubocop/formatter/formatter_set.rb +16 -15
  234. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  235. data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
  236. data/lib/rubocop/formatter/tap_formatter.rb +17 -4
  237. data/lib/rubocop/magic_comment.rb +4 -0
  238. data/lib/rubocop/node_pattern.rb +5 -3
  239. data/lib/rubocop/options.rb +33 -21
  240. data/lib/rubocop/path_util.rb +1 -1
  241. data/lib/rubocop/processed_source.rb +4 -0
  242. data/lib/rubocop/result_cache.rb +1 -1
  243. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  244. data/lib/rubocop/rspec/shared_contexts.rb +12 -0
  245. data/lib/rubocop/runner.rb +42 -31
  246. data/lib/rubocop/target_finder.rb +12 -4
  247. data/lib/rubocop/version.rb +1 -1
  248. metadata +21 -12
  249. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
@@ -80,7 +80,7 @@ module RuboCop
80
80
  end
81
81
 
82
82
  def_node_matcher :chained_send?, '(send !nil? ...)'
83
- def_node_matcher :define_method?, <<-PATTERN
83
+ def_node_matcher :define_method?, <<~PATTERN
84
84
  (send _ {:define_method :define_singleton_method} _)
85
85
  PATTERN
86
86
  end
@@ -69,7 +69,7 @@ module RuboCop
69
69
 
70
70
  # if format: (if checked_variable body nil)
71
71
  # unless format: (if checked_variable nil body)
72
- def_node_matcher :modifier_if_safe_navigation_candidate, <<-PATTERN
72
+ def_node_matcher :modifier_if_safe_navigation_candidate, <<~PATTERN
73
73
  {
74
74
  (if {
75
75
  (send $_ {:nil? :!})
@@ -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
@@ -30,7 +30,7 @@ module RuboCop
30
30
  class Sample < Cop
31
31
  MSG = 'Use `%<correct>s` instead of `%<incorrect>s`.'
32
32
 
33
- def_node_matcher :sample_candidate?, <<-PATTERN
33
+ def_node_matcher :sample_candidate?, <<~PATTERN
34
34
  (send $(send _ :shuffle $...) ${:first :last :[] :at :slice} $...)
35
35
  PATTERN
36
36
 
@@ -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
 
@@ -20,7 +20,7 @@ module RuboCop
20
20
  MSG =
21
21
  'Use `warn` instead of `%<bad>s` to allow such output to be disabled.'
22
22
 
23
- def_node_matcher :stderr_puts?, <<-PATTERN
23
+ def_node_matcher :stderr_puts?, <<~PATTERN
24
24
  (send
25
25
  {(gvar #stderr_gvar?) (const nil? :STDERR)}
26
26
  :puts $_
@@ -15,11 +15,11 @@ module RuboCop
15
15
  class StringHashKeys < Cop
16
16
  MSG = 'Prefer symbols instead of strings as hash keys.'
17
17
 
18
- def_node_matcher :string_hash_key?, <<-PATTERN
18
+ def_node_matcher :string_hash_key?, <<~PATTERN
19
19
  (pair (str _) _)
20
20
  PATTERN
21
21
 
22
- def_node_matcher :receive_environments_method?, <<-PATTERN
22
+ def_node_matcher :receive_environments_method?, <<~PATTERN
23
23
  {
24
24
  ^^(send (const {nil? cbase} :IO) :popen ...)
25
25
  ^^(send (const {nil? cbase} :Open3)
@@ -18,7 +18,7 @@ module RuboCop
18
18
 
19
19
  MSG = 'Use `strip` instead of `%<methods>s`.'
20
20
 
21
- def_node_matcher :lstrip_rstrip, <<-PATTERN
21
+ def_node_matcher :lstrip_rstrip, <<~PATTERN
22
22
  {(send $(send _ $:rstrip) $:lstrip)
23
23
  (send $(send _ $:lstrip) $:rstrip)}
24
24
  PATTERN
@@ -29,9 +29,9 @@ module RuboCop
29
29
  add_offense(node, location: node.parent_class.source_range)
30
30
  end
31
31
 
32
- def_node_matcher :struct_constructor?, <<-PATTERN
33
- {(send (const nil? :Struct) :new ...)
34
- (block (send (const nil? :Struct) :new ...) ...)}
32
+ def_node_matcher :struct_constructor?, <<~PATTERN
33
+ {(send (const nil? :Struct) :new ...)
34
+ (block (send (const nil? :Struct) :new ...) ...)}
35
35
  PATTERN
36
36
  end
37
37
  end
@@ -20,7 +20,7 @@ module RuboCop
20
20
  SUPER_TYPES = %i[super zsuper].freeze
21
21
 
22
22
  def_node_matcher :proc_node?, '(send (const nil? :Proc) :new)'
23
- def_node_matcher :symbol_proc?, <<-PATTERN
23
+ def_node_matcher :symbol_proc?, <<~PATTERN
24
24
  (block
25
25
  ${(send ...) (super ...) zsuper}
26
26
  $(args (arg _var))
@@ -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
 
@@ -167,7 +186,7 @@ module RuboCop
167
186
  (child.send_type? && child.prefix_not?)
168
187
  end
169
188
 
170
- def_node_matcher :method_name, <<-PATTERN
189
+ def_node_matcher :method_name, <<~PATTERN
171
190
  {($:defined? (send nil? _) ...)
172
191
  (send {_ nil?} $_ _ ...)}
173
192
  PATTERN
@@ -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)
@@ -118,7 +118,7 @@ module RuboCop
118
118
  !allowed_method?(node) && !allowed_writer?(node.method_name)
119
119
  end
120
120
 
121
- def_node_matcher :looks_like_trivial_writer?, <<-PATTERN
121
+ def_node_matcher :looks_like_trivial_writer?, <<~PATTERN
122
122
  {(def _ (args (arg ...)) (ivasgn _ (lvar _)))
123
123
  (defs _ _ (args (arg ...)) (ivasgn _ (lvar _)))}
124
124
  PATTERN
@@ -25,7 +25,7 @@ module RuboCop
25
25
  MSG = 'Use `%<receiver>s.unpack1(%<format>s)` instead of '\
26
26
  '`%<receiver>s.unpack(%<format>s)%<method>s`.'
27
27
 
28
- def_node_matcher :unpack_and_first_element?, <<-PATTERN
28
+ def_node_matcher :unpack_and_first_element?, <<~PATTERN
29
29
  {
30
30
  (send $(send (...) :unpack $(...)) :first)
31
31
  (send $(send (...) :unpack $(...)) {:[] :slice :at} (int 0))
@@ -16,19 +16,15 @@ module RuboCop
16
16
  # /check #{$pattern}/
17
17
  # "Let's go to the #{@store}"
18
18
  class VariableInterpolation < Cop
19
+ include Interpolation
20
+
19
21
  MSG = 'Replace interpolated variable `%<variable>s` ' \
20
22
  'with expression `#{%<variable>s}`.'
21
23
 
22
- def on_dstr(node)
23
- check_for_interpolation(node)
24
- end
25
-
26
- def on_regexp(node)
27
- check_for_interpolation(node)
28
- end
29
-
30
- def on_xstr(node)
31
- check_for_interpolation(node)
24
+ def on_node_with_interpolations(node)
25
+ var_nodes(node.children).each do |var_node|
26
+ add_offense(var_node)
27
+ end
32
28
  end
33
29
 
34
30
  def autocorrect(node)
@@ -39,12 +35,6 @@ module RuboCop
39
35
 
40
36
  private
41
37
 
42
- def check_for_interpolation(node)
43
- var_nodes(node.children).each do |var_node|
44
- add_offense(var_node)
45
- end
46
- end
47
-
48
38
  def message(node)
49
39
  format(MSG, variable: node.source)
50
40
  end
@@ -73,14 +73,14 @@ module RuboCop
73
73
  )
74
74
  end
75
75
 
76
- def_node_matcher :zero_length_predicate, <<-PATTERN
76
+ def_node_matcher :zero_length_predicate, <<~PATTERN
77
77
  {(send (send (...) ${:length :size}) $:== (int $0))
78
78
  (send (int $0) $:== (send (...) ${:length :size}))
79
79
  (send (send (...) ${:length :size}) $:< (int $1))
80
80
  (send (int $1) $:> (send (...) ${:length :size}))}
81
81
  PATTERN
82
82
 
83
- def_node_matcher :nonzero_length_predicate, <<-PATTERN
83
+ def_node_matcher :nonzero_length_predicate, <<~PATTERN
84
84
  {(send (send (...) ${:length :size}) ${:> :!=} (int $0))
85
85
  (send (int $0) ${:< :!=} (send (...) ${:length :size}))}
86
86
  PATTERN
@@ -92,14 +92,14 @@ module RuboCop
92
92
  "!#{other_receiver(node).source}.empty?"
93
93
  end
94
94
 
95
- def_node_matcher :zero_length_receiver, <<-PATTERN
95
+ def_node_matcher :zero_length_receiver, <<~PATTERN
96
96
  {(send (send $_ _) :== (int 0))
97
97
  (send (int 0) :== (send $_ _))
98
98
  (send (send $_ _) :< (int 1))
99
99
  (send (int 1) :> (send $_ _))}
100
100
  PATTERN
101
101
 
102
- def_node_matcher :other_receiver, <<-PATTERN
102
+ def_node_matcher :other_receiver, <<~PATTERN
103
103
  {(send (send $_ _) _ _)
104
104
  (send _ _ (send $_ _))}
105
105
  PATTERN
@@ -107,7 +107,7 @@ module RuboCop
107
107
  # Some collection like objects in the Ruby standard library
108
108
  # implement `#size`, but not `#empty`. We ignore those to
109
109
  # reduce false positives.
110
- def_node_matcher :non_polymorphic_collection?, <<-PATTERN
110
+ def_node_matcher :non_polymorphic_collection?, <<~PATTERN
111
111
  {(send (send (send (const nil? :File) :stat _) ...) ...)
112
112
  (send (send (send (const nil? {:Tempfile :StringIO}) {:new :open} ...) ...) ...)}
113
113
  PATTERN
@@ -81,6 +81,9 @@ module RuboCop
81
81
  File.open(filename, 'w') { |f| f.write(new_source) }
82
82
  end
83
83
  @updated_source_file = true
84
+ rescue RuboCop::ErrorWithAnalyzedFileLocation => e
85
+ process_errors(buffer.name, [e])
86
+ raise e.cause
84
87
  end
85
88
 
86
89
  private
@@ -103,8 +106,8 @@ module RuboCop
103
106
 
104
107
  other = investigate(other_cops, processed_source)
105
108
 
106
- errors = autocorrect.errors.merge(other.errors)
107
- process_commissioner_errors(processed_source.path, errors)
109
+ errors = [*autocorrect.errors, *other.errors]
110
+ process_errors(processed_source.path, errors)
108
111
 
109
112
  autocorrect.offenses.concat(other.offenses)
110
113
  end
@@ -149,19 +152,17 @@ module RuboCop
149
152
  end
150
153
  end
151
154
 
152
- def process_commissioner_errors(file, file_errors)
153
- file_errors.each do |cop, errors|
154
- errors.each do |cop_error|
155
- e = cop_error.error
156
- line = ":#{cop_error.line}" if cop_error.line
157
- column = ":#{cop_error.column}" if cop_error.column
158
- location = "#{file}#{line}#{column}"
155
+ def process_errors(file, errors)
156
+ errors.each do |error|
157
+ line = ":#{error.line}" if error.line
158
+ column = ":#{error.column}" if error.column
159
+ location = "#{file}#{line}#{column}"
160
+ cause = error.cause
159
161
 
160
- if e.is_a?(Warning)
161
- handle_warning(e, location)
162
- else
163
- handle_error(e, location, cop)
164
- end
162
+ if cause.is_a?(Warning)
163
+ handle_warning(cause, location)
164
+ else
165
+ handle_error(cause, location, error.cop)
165
166
  end
166
167
  end
167
168
  end