rubocop 1.9.0 → 1.12.1

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 (275) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -14
  3. data/assets/output.html.erb +1 -1
  4. data/config/default.yml +70 -17
  5. data/config/obsoletion.yml +4 -0
  6. data/lib/rubocop.rb +5 -0
  7. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  8. data/lib/rubocop/cli/command/suggest_extensions.rb +3 -2
  9. data/lib/rubocop/comment_config.rb +43 -94
  10. data/lib/rubocop/config.rb +4 -1
  11. data/lib/rubocop/cop/base.rb +1 -0
  12. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -1
  13. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
  14. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -0
  15. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -0
  16. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  17. data/lib/rubocop/cop/exclude_limit.rb +26 -0
  18. data/lib/rubocop/cop/gemspec/date_assignment.rb +57 -0
  19. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -0
  20. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -0
  21. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +2 -0
  22. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +2 -0
  23. data/lib/rubocop/cop/generator.rb +2 -2
  24. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  25. data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -0
  26. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
  27. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -0
  28. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +151 -0
  29. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
  30. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -0
  31. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +1 -0
  32. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +1 -0
  33. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
  34. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +3 -0
  35. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +4 -0
  36. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  37. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +11 -8
  38. data/lib/rubocop/cop/layout/argument_alignment.rb +6 -5
  39. data/lib/rubocop/cop/layout/array_alignment.rb +7 -6
  40. data/lib/rubocop/cop/layout/assignment_indentation.rb +6 -3
  41. data/lib/rubocop/cop/layout/block_alignment.rb +1 -0
  42. data/lib/rubocop/cop/layout/block_end_newline.rb +4 -8
  43. data/lib/rubocop/cop/layout/class_structure.rb +1 -0
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +14 -15
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +16 -16
  46. data/lib/rubocop/cop/layout/else_alignment.rb +9 -6
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +20 -3
  48. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +37 -17
  49. data/lib/rubocop/cop/layout/extra_spacing.rb +2 -2
  50. data/lib/rubocop/cop/layout/first_argument_indentation.rb +27 -7
  51. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +9 -6
  52. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +22 -15
  53. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +6 -5
  54. data/lib/rubocop/cop/layout/indentation_consistency.rb +9 -6
  55. data/lib/rubocop/cop/layout/indentation_style.rb +27 -30
  56. data/lib/rubocop/cop/layout/indentation_width.rb +20 -9
  57. data/lib/rubocop/cop/layout/line_length.rb +2 -1
  58. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +26 -0
  59. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -5
  60. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +10 -5
  61. data/lib/rubocop/cop/layout/parameter_alignment.rb +6 -5
  62. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -1
  63. data/lib/rubocop/cop/layout/space_before_brackets.rb +9 -4
  64. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  65. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -0
  66. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -0
  67. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +2 -0
  68. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -0
  69. data/lib/rubocop/cop/lint/debugger.rb +60 -14
  70. data/lib/rubocop/cop/lint/deprecated_constants.rb +5 -0
  71. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +14 -4
  72. data/lib/rubocop/cop/lint/duplicate_branch.rb +1 -1
  73. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -0
  74. data/lib/rubocop/cop/lint/duplicate_require.rb +3 -2
  75. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
  76. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  77. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -0
  78. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -0
  79. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +1 -0
  80. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -0
  81. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -0
  82. data/lib/rubocop/cop/lint/multiple_comparison.rb +5 -4
  83. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -0
  84. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -0
  85. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +7 -0
  86. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -0
  87. data/lib/rubocop/cop/lint/number_conversion.rb +11 -2
  88. data/lib/rubocop/cop/lint/raise_exception.rb +2 -0
  89. data/lib/rubocop/cop/lint/rand_one.rb +1 -0
  90. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +1 -2
  91. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
  92. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -0
  93. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -3
  94. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -0
  95. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -0
  96. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -0
  97. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -0
  98. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -0
  99. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -0
  100. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  101. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
  102. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
  103. data/lib/rubocop/cop/lint/suppressed_exception.rb +44 -1
  104. data/lib/rubocop/cop/lint/symbol_conversion.rb +91 -3
  105. data/lib/rubocop/cop/lint/to_enum_arguments.rb +3 -0
  106. data/lib/rubocop/cop/lint/unified_integer.rb +1 -0
  107. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +5 -0
  108. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
  109. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -0
  110. data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -0
  111. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -0
  112. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -0
  113. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -0
  114. data/lib/rubocop/cop/lint/useless_times.rb +3 -0
  115. data/lib/rubocop/cop/message_annotator.rb +4 -1
  116. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  117. data/lib/rubocop/cop/metrics/module_length.rb +1 -0
  118. data/lib/rubocop/cop/metrics/parameter_lists.rb +6 -2
  119. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -4
  120. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +2 -0
  121. data/lib/rubocop/cop/mixin/alignment.rb +10 -3
  122. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  123. data/lib/rubocop/cop/mixin/code_length.rb +3 -1
  124. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  125. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -0
  126. data/lib/rubocop/cop/mixin/def_node.rb +1 -0
  127. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  128. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +3 -0
  129. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -0
  130. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -0
  131. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -0
  132. data/lib/rubocop/cop/mixin/line_length_help.rb +11 -6
  133. data/lib/rubocop/cop/mixin/method_complexity.rb +4 -1
  134. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +3 -1
  135. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -23
  136. data/lib/rubocop/cop/mixin/negative_conditional.rb +3 -0
  137. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +3 -3
  138. data/lib/rubocop/cop/mixin/rational_literal.rb +1 -0
  139. data/lib/rubocop/cop/mixin/safe_assignment.rb +5 -0
  140. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +4 -6
  141. data/lib/rubocop/cop/mixin/visibility_help.rb +1 -0
  142. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -0
  143. data/lib/rubocop/cop/naming/constant_name.rb +2 -0
  144. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +6 -0
  145. data/lib/rubocop/cop/naming/method_name.rb +3 -0
  146. data/lib/rubocop/cop/naming/predicate_name.rb +1 -0
  147. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -0
  148. data/lib/rubocop/cop/registry.rb +10 -1
  149. data/lib/rubocop/cop/security/eval.rb +1 -0
  150. data/lib/rubocop/cop/security/json_load.rb +1 -0
  151. data/lib/rubocop/cop/security/marshal_load.rb +1 -0
  152. data/lib/rubocop/cop/security/open.rb +1 -0
  153. data/lib/rubocop/cop/security/yaml_load.rb +1 -0
  154. data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -2
  155. data/lib/rubocop/cop/style/alias.rb +1 -0
  156. data/lib/rubocop/cop/style/and_or.rb +3 -1
  157. data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -0
  158. data/lib/rubocop/cop/style/array_coercion.rb +2 -0
  159. data/lib/rubocop/cop/style/array_join.rb +1 -0
  160. data/lib/rubocop/cop/style/attr.rb +1 -0
  161. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +59 -71
  162. data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +62 -0
  163. data/lib/rubocop/cop/style/case_equality.rb +2 -1
  164. data/lib/rubocop/cop/style/case_like_if.rb +15 -4
  165. data/lib/rubocop/cop/style/class_equality_comparison.rb +3 -0
  166. data/lib/rubocop/cop/style/collection_compact.rb +2 -0
  167. data/lib/rubocop/cop/style/colon_method_call.rb +1 -0
  168. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  169. data/lib/rubocop/cop/style/commented_keyword.rb +10 -10
  170. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
  171. data/lib/rubocop/cop/style/constant_visibility.rb +28 -0
  172. data/lib/rubocop/cop/style/date_time.rb +3 -0
  173. data/lib/rubocop/cop/style/dir.rb +1 -0
  174. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  175. data/lib/rubocop/cop/style/documentation.rb +30 -3
  176. data/lib/rubocop/cop/style/documentation_method.rb +1 -0
  177. data/lib/rubocop/cop/style/double_negation.rb +3 -2
  178. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -0
  179. data/lib/rubocop/cop/style/each_with_object.rb +1 -0
  180. data/lib/rubocop/cop/style/empty_literal.rb +9 -0
  181. data/lib/rubocop/cop/style/endless_method.rb +1 -0
  182. data/lib/rubocop/cop/style/eval_with_location.rb +90 -28
  183. data/lib/rubocop/cop/style/even_odd.rb +1 -0
  184. data/lib/rubocop/cop/style/expand_path_arguments.rb +3 -0
  185. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -1
  186. data/lib/rubocop/cop/style/exponential_notation.rb +6 -7
  187. data/lib/rubocop/cop/style/float_division.rb +4 -0
  188. data/lib/rubocop/cop/style/format_string.rb +2 -0
  189. data/lib/rubocop/cop/style/format_string_token.rb +1 -0
  190. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +0 -3
  191. data/lib/rubocop/cop/style/global_std_stream.rb +1 -0
  192. data/lib/rubocop/cop/style/hash_conversion.rb +108 -0
  193. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -0
  194. data/lib/rubocop/cop/style/hash_except.rb +1 -0
  195. data/lib/rubocop/cop/style/hash_like_case.rb +1 -0
  196. data/lib/rubocop/cop/style/hash_syntax.rb +16 -15
  197. data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -0
  198. data/lib/rubocop/cop/style/hash_transform_values.rb +4 -0
  199. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +37 -11
  200. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
  201. data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
  202. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +46 -2
  203. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -3
  204. data/lib/rubocop/cop/style/min_max.rb +1 -0
  205. data/lib/rubocop/cop/style/mixin_usage.rb +2 -0
  206. data/lib/rubocop/cop/style/module_function.rb +5 -0
  207. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -3
  208. data/lib/rubocop/cop/style/multiple_comparison.rb +21 -2
  209. data/lib/rubocop/cop/style/mutable_constant.rb +3 -0
  210. data/lib/rubocop/cop/style/negated_if_else_condition.rb +16 -2
  211. data/lib/rubocop/cop/style/nil_comparison.rb +6 -1
  212. data/lib/rubocop/cop/style/nil_lambda.rb +1 -0
  213. data/lib/rubocop/cop/style/non_nil_check.rb +7 -0
  214. data/lib/rubocop/cop/style/numeric_literals.rb +6 -9
  215. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -1
  216. data/lib/rubocop/cop/style/option_hash.rb +1 -0
  217. data/lib/rubocop/cop/style/or_assignment.rb +2 -0
  218. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -0
  219. data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -0
  220. data/lib/rubocop/cop/style/proc.rb +1 -0
  221. data/lib/rubocop/cop/style/random_with_offset.rb +5 -0
  222. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -0
  223. data/lib/rubocop/cop/style/redundant_begin.rb +44 -4
  224. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -0
  225. data/lib/rubocop/cop/style/redundant_exception.rb +2 -0
  226. data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -0
  227. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
  228. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -0
  229. data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -0
  230. data/lib/rubocop/cop/style/redundant_return.rb +4 -0
  231. data/lib/rubocop/cop/style/redundant_self.rb +7 -3
  232. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -0
  233. data/lib/rubocop/cop/style/redundant_sort.rb +1 -0
  234. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -0
  235. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  236. data/lib/rubocop/cop/style/rescue_modifier.rb +17 -14
  237. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -0
  238. data/lib/rubocop/cop/style/return_nil.rb +6 -0
  239. data/lib/rubocop/cop/style/safe_navigation.rb +2 -0
  240. data/lib/rubocop/cop/style/sample.rb +1 -0
  241. data/lib/rubocop/cop/style/signal_exception.rb +3 -0
  242. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
  243. data/lib/rubocop/cop/style/single_line_methods.rb +4 -1
  244. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -0
  245. data/lib/rubocop/cop/style/sole_nested_conditional.rb +20 -4
  246. data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
  247. data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
  248. data/lib/rubocop/cop/style/string_chars.rb +38 -0
  249. data/lib/rubocop/cop/style/string_concatenation.rb +1 -0
  250. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -0
  251. data/lib/rubocop/cop/style/strip.rb +1 -0
  252. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -0
  253. data/lib/rubocop/cop/style/symbol_proc.rb +25 -1
  254. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -0
  255. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +5 -0
  256. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
  257. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -0
  258. data/lib/rubocop/cop/style/unless_logical_operators.rb +105 -0
  259. data/lib/rubocop/cop/style/unpack_first.rb +1 -0
  260. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  261. data/lib/rubocop/cop/style/zero_length_predicate.rb +5 -0
  262. data/lib/rubocop/cop/util.rb +4 -1
  263. data/lib/rubocop/directive_comment.rb +69 -9
  264. data/lib/rubocop/ext/regexp_parser.rb +3 -6
  265. data/lib/rubocop/formatter/clang_style_formatter.rb +4 -2
  266. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  267. data/lib/rubocop/formatter/simple_text_formatter.rb +2 -1
  268. data/lib/rubocop/formatter/tap_formatter.rb +4 -2
  269. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  270. data/lib/rubocop/magic_comment.rb +1 -1
  271. data/lib/rubocop/name_similarity.rb +1 -1
  272. data/lib/rubocop/target_finder.rb +1 -0
  273. data/lib/rubocop/target_ruby.rb +21 -13
  274. data/lib/rubocop/version.rb +1 -1
  275. metadata +14 -7
@@ -47,14 +47,13 @@ module RuboCop
47
47
 
48
48
  if node.modifier_form? && last_argument_is_heredoc?(node)
49
49
  heredoc_node = last_heredoc_argument(node)
50
-
51
- return if next_line_empty?(heredoc_line(node, heredoc_node))
50
+ return if next_line_empty_or_enable_directive_comment?(heredoc_line(node, heredoc_node))
52
51
 
53
52
  add_offense(heredoc_node.loc.heredoc_end) do |corrector|
54
53
  autocorrect(corrector, heredoc_node)
55
54
  end
56
55
  else
57
- return if next_line_empty?(node.last_line)
56
+ return if next_line_empty_or_enable_directive_comment?(node.last_line)
58
57
 
59
58
  add_offense(offense_location(node)) do |corrector|
60
59
  autocorrect(corrector, node)
@@ -71,6 +70,11 @@ module RuboCop
71
70
  range_by_whole_lines(node.source_range)
72
71
  end
73
72
 
73
+ next_line = node_range.last_line + 1
74
+ if next_line_enable_directive_comment?(next_line)
75
+ node_range = processed_source.comment_at_line(next_line)
76
+ end
77
+
74
78
  corrector.insert_after(node_range, "\n")
75
79
  end
76
80
 
@@ -85,10 +89,23 @@ module RuboCop
85
89
  node.if_branch&.guard_clause?
86
90
  end
87
91
 
92
+ def next_line_empty_or_enable_directive_comment?(line)
93
+ return true if next_line_empty?(line)
94
+
95
+ next_line = line + 1
96
+ next_line_enable_directive_comment?(next_line) && next_line_empty?(next_line)
97
+ end
98
+
88
99
  def next_line_empty?(line)
89
100
  processed_source[line].blank?
90
101
  end
91
102
 
103
+ def next_line_enable_directive_comment?(line)
104
+ return false unless (comment = processed_source.comment_at_line(line))
105
+
106
+ DirectiveComment.new(comment).enabled?
107
+ end
108
+
92
109
  def next_line_rescue_or_ensure?(node)
93
110
  parent = node.parent
94
111
  parent.nil? || parent.rescue_type? || parent.ensure_type?
@@ -88,7 +88,7 @@ module RuboCop
88
88
  include RangeHelp
89
89
  extend AutoCorrector
90
90
 
91
- MSG = 'Use empty lines between %<type>s definitions.'
91
+ MSG = 'Expected %<expected>s between %<type>s definitions; found %<actual>d.'
92
92
 
93
93
  def self.autocorrect_incompatible_with
94
94
  [Layout::EmptyLines]
@@ -107,19 +107,21 @@ module RuboCop
107
107
  end
108
108
 
109
109
  def check_defs(nodes)
110
- return if blank_lines_between?(*nodes)
110
+ count = blank_lines_count_between(*nodes)
111
+
112
+ return if line_count_allowed?(count)
111
113
  return if multiple_blank_lines_groups?(*nodes)
112
114
  return if nodes.all?(&:single_line?) &&
113
115
  cop_config['AllowAdjacentOneLineDefs']
114
116
 
115
117
  correction_node = nodes.last
116
118
  location = correction_node.loc.keyword.join(correction_node.loc.name)
117
- add_offense(location, message: message(correction_node)) do |corrector|
118
- autocorrect(corrector, *nodes)
119
+ add_offense(location, message: message(correction_node, count: count)) do |corrector|
120
+ autocorrect(corrector, *nodes, count)
119
121
  end
120
122
  end
121
123
 
122
- def autocorrect(corrector, prev_def, node)
124
+ def autocorrect(corrector, prev_def, node, count)
123
125
  # finds position of first newline
124
126
  end_pos = end_loc(prev_def).end_pos
125
127
  source_buffer = end_loc(prev_def).source_buffer
@@ -128,8 +130,6 @@ module RuboCop
128
130
  # Handle the case when multiple one-liners are on the same line.
129
131
  newline_pos = end_pos + 1 if newline_pos > node.source_range.begin_pos
130
132
 
131
- count = blank_lines_count_between(prev_def, node)
132
-
133
133
  if count > maximum_empty_lines
134
134
  autocorrect_remove_lines(corrector, newline_pos, count)
135
135
  else
@@ -157,14 +157,22 @@ module RuboCop
157
157
  cop_config['EmptyLineBetweenModuleDefs'] && node.module_type?
158
158
  end
159
159
 
160
- def message(node)
161
- type = case node.type
162
- when :def, :defs
163
- :method
164
- else
165
- node.type
166
- end
167
- format(MSG, type: type)
160
+ def message(node, count: nil)
161
+ type = node_type(node)
162
+
163
+ format(MSG,
164
+ type: type,
165
+ expected: expected_lines,
166
+ actual: count)
167
+ end
168
+
169
+ def expected_lines
170
+ if allowance_range?
171
+ "#{minimum_empty_lines..maximum_empty_lines} empty lines"
172
+ else
173
+ lines = maximum_empty_lines == 1 ? 'line' : 'lines'
174
+ "#{maximum_empty_lines} empty #{lines}"
175
+ end
168
176
  end
169
177
 
170
178
  def multiple_blank_lines_groups?(first_def_node, second_def_node)
@@ -176,8 +184,7 @@ module RuboCop
176
184
  blank_start > non_blank_end
177
185
  end
178
186
 
179
- def blank_lines_between?(first_def_node, second_def_node)
180
- count = blank_lines_count_between(first_def_node, second_def_node)
187
+ def line_count_allowed?(count)
181
188
  (minimum_empty_lines..maximum_empty_lines).cover?(count)
182
189
  end
183
190
 
@@ -230,6 +237,19 @@ module RuboCop
230
237
 
231
238
  corrector.insert_after(where_to_insert, "\n" * difference)
232
239
  end
240
+
241
+ def node_type(node)
242
+ case node.type
243
+ when :def, :defs
244
+ :method
245
+ else
246
+ node.type
247
+ end
248
+ end
249
+
250
+ def allowance_range?
251
+ minimum_empty_lines != maximum_empty_lines
252
+ end
233
253
  end
234
254
  end
235
255
  end
@@ -11,12 +11,12 @@ module RuboCop
11
11
  # name = "RuboCop"
12
12
  # # Some comment and an empty line
13
13
  #
14
- # website += "/rubocop-hq/rubocop" unless cond
14
+ # website += "/rubocop/rubocop" unless cond
15
15
  # puts "rubocop" if debug
16
16
  #
17
17
  # # bad for any configuration
18
18
  # set_app("RuboCop")
19
- # website = "https://github.com/rubocop-hq/rubocop"
19
+ # website = "https://github.com/rubocop/rubocop"
20
20
  #
21
21
  # # good only if AllowBeforeTrailingComments is true
22
22
  # object.method(arg) # this is a comment
@@ -4,11 +4,14 @@ module RuboCop
4
4
  module Cop
5
5
  module Layout
6
6
  # This cop checks the indentation of the first argument in a method call.
7
- # Arguments after the first one are checked by Layout/ArgumentAlignment,
7
+ # Arguments after the first one are checked by `Layout/ArgumentAlignment`,
8
8
  # not by this cop.
9
9
  #
10
10
  # For indenting the first parameter of method _definitions_, check out
11
- # Layout/FirstParameterIndentation.
11
+ # `Layout/FirstParameterIndentation`.
12
+ #
13
+ # This cop will respect `Layout/ArgumentAlignment` and will not work when
14
+ # `EnforcedStyle: with_fixed_indentation` is specified for `Layout/ArgumentAlignment`.
12
15
  #
13
16
  # @example
14
17
  #
@@ -141,15 +144,17 @@ module RuboCop
141
144
  # nested_first_param),
142
145
  # second_param
143
146
  #
144
- class FirstArgumentIndentation < Cop
147
+ class FirstArgumentIndentation < Base
145
148
  include Alignment
146
149
  include ConfigurableEnforcedStyle
147
150
  include RangeHelp
151
+ extend AutoCorrector
148
152
 
149
153
  MSG = 'Indent the first argument one step more than %<base>s.'
150
154
 
151
155
  def on_send(node)
152
- return if !node.arguments? || node.operator_method?
156
+ return if style != :consistent && enforce_first_argument_with_fixed_indentation?
157
+ return if !node.arguments? || bare_operator?(node)
153
158
 
154
159
  indent = base_indentation(node) + configured_indentation_width
155
160
 
@@ -157,11 +162,15 @@ module RuboCop
157
162
  end
158
163
  alias on_csend on_send
159
164
 
160
- def autocorrect(node)
161
- AlignmentCorrector.correct(processed_source, node, column_delta)
165
+ private
166
+
167
+ def autocorrect(corrector, node)
168
+ AlignmentCorrector.correct(corrector, processed_source, node, column_delta)
162
169
  end
163
170
 
164
- private
171
+ def bare_operator?(node)
172
+ node.operator_method? && !node.dot?
173
+ end
165
174
 
166
175
  def message(arg_node)
167
176
  return 'Bad indentation of the first argument.' unless arg_node
@@ -202,6 +211,7 @@ module RuboCop
202
211
  node.source_range.begin_pos > parent.source_range.begin_pos
203
212
  end
204
213
 
214
+ # @!method eligible_method_call?(node)
205
215
  def_node_matcher :eligible_method_call?, <<~PATTERN
206
216
  (send _ !:[]= ...)
207
217
  PATTERN
@@ -250,6 +260,16 @@ module RuboCop
250
260
  def on_new_investigation
251
261
  @comment_lines = nil
252
262
  end
263
+
264
+ def enforce_first_argument_with_fixed_indentation?
265
+ return false unless argument_alignment_config['Enabled']
266
+
267
+ argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
268
+ end
269
+
270
+ def argument_alignment_config
271
+ config.for_cop('Layout/ArgumentAlignment')
272
+ end
253
273
  end
254
274
  end
255
275
  end
@@ -79,10 +79,11 @@ module RuboCop
79
79
  # and_now_for_something = [
80
80
  # :completely_different
81
81
  # ]
82
- class FirstArrayElementIndentation < Cop
82
+ class FirstArrayElementIndentation < Base
83
83
  include Alignment
84
84
  include ConfigurableEnforcedStyle
85
85
  include MultilineElementIndentation
86
+ extend AutoCorrector
86
87
 
87
88
  MSG = 'Use %<configured_indentation_width>d spaces for indentation ' \
88
89
  'in an array, relative to %<base_description>s.'
@@ -98,12 +99,12 @@ module RuboCop
98
99
  end
99
100
  alias on_csend on_send
100
101
 
101
- def autocorrect(node)
102
- AlignmentCorrector.correct(processed_source, node, @column_delta)
103
- end
104
-
105
102
  private
106
103
 
104
+ def autocorrect(corrector, node)
105
+ AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
106
+ end
107
+
107
108
  def brace_alignment_style
108
109
  :align_brackets
109
110
  end
@@ -132,7 +133,9 @@ module RuboCop
132
133
  return if @column_delta.zero?
133
134
 
134
135
  msg = msg(left_parenthesis)
135
- add_offense(right_bracket, location: right_bracket, message: msg)
136
+ add_offense(right_bracket, message: msg) do |corrector|
137
+ autocorrect(corrector, right_bracket)
138
+ end
136
139
  end
137
140
 
138
141
  # Returns the description of what the correct indentation is based on.
@@ -77,10 +77,11 @@ module RuboCop
77
77
  # and_now_for_something = {
78
78
  # completely: :different
79
79
  # }
80
- class FirstHashElementIndentation < Cop
80
+ class FirstHashElementIndentation < Base
81
81
  include Alignment
82
82
  include ConfigurableEnforcedStyle
83
83
  include MultilineElementIndentation
84
+ extend AutoCorrector
84
85
 
85
86
  MSG = 'Use %<configured_indentation_width>d spaces for indentation ' \
86
87
  'in a hash, relative to %<base_description>s.'
@@ -96,12 +97,12 @@ module RuboCop
96
97
  end
97
98
  alias on_csend on_send
98
99
 
99
- def autocorrect(node)
100
- AlignmentCorrector.correct(processed_source, node, @column_delta)
101
- end
102
-
103
100
  private
104
101
 
102
+ def autocorrect(corrector, node)
103
+ AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
104
+ end
105
+
105
106
  def brace_alignment_style
106
107
  :align_braces
107
108
  end
@@ -134,16 +135,10 @@ module RuboCop
134
135
  @column_delta = expected_column - right_brace.column
135
136
  return if @column_delta.zero?
136
137
 
137
- msg = if style == :align_braces
138
- 'Indent the right brace the same as the left brace.'
139
- elsif style == :special_inside_parentheses && left_parenthesis
140
- 'Indent the right brace the same as the first position ' \
141
- 'after the preceding left parenthesis.'
142
- else
143
- 'Indent the right brace the same as the start of the line ' \
144
- 'where the left brace is.'
145
- end
146
- add_offense(right_brace, location: right_brace, message: msg)
138
+ message = message_for_right_brace(left_parenthesis)
139
+ add_offense(right_brace, message: message) do |corrector|
140
+ autocorrect(corrector, right_brace)
141
+ end
147
142
  end
148
143
 
149
144
  def separator_style?(first_pair)
@@ -178,6 +173,18 @@ module RuboCop
178
173
  base_description: base_description
179
174
  )
180
175
  end
176
+
177
+ def message_for_right_brace(left_parenthesis)
178
+ if style == :align_braces
179
+ 'Indent the right brace the same as the left brace.'
180
+ elsif style == :special_inside_parentheses && left_parenthesis
181
+ 'Indent the right brace the same as the first position ' \
182
+ 'after the preceding left parenthesis.'
183
+ else
184
+ 'Indent the right brace the same as the start of the line ' \
185
+ 'where the left brace is.'
186
+ end
187
+ end
181
188
  end
182
189
  end
183
190
  end
@@ -41,10 +41,11 @@ module RuboCop
41
41
  # second_param)
42
42
  # 123
43
43
  # end
44
- class FirstParameterIndentation < Cop
44
+ class FirstParameterIndentation < Base
45
45
  include Alignment
46
46
  include ConfigurableEnforcedStyle
47
47
  include MultilineElementIndentation
48
+ extend AutoCorrector
48
49
 
49
50
  MSG = 'Use %<configured_indentation_width>d spaces for indentation ' \
50
51
  'in method args, relative to %<base_description>s.'
@@ -57,12 +58,12 @@ module RuboCop
57
58
  end
58
59
  alias on_defs on_def
59
60
 
60
- def autocorrect(node)
61
- AlignmentCorrector.correct(processed_source, node, @column_delta)
62
- end
63
-
64
61
  private
65
62
 
63
+ def autocorrect(corrector, node)
64
+ AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
65
+ end
66
+
66
67
  def brace_alignment_style
67
68
  :align_parentheses
68
69
  end
@@ -118,9 +118,10 @@ module RuboCop
118
118
  # def bar
119
119
  # end
120
120
  # end
121
- class IndentationConsistency < Cop
121
+ class IndentationConsistency < Base
122
122
  include Alignment
123
123
  include ConfigurableEnforcedStyle
124
+ extend AutoCorrector
124
125
 
125
126
  MSG = 'Inconsistent indentation detected.'
126
127
 
@@ -132,12 +133,12 @@ module RuboCop
132
133
  check(node)
133
134
  end
134
135
 
135
- def autocorrect(node)
136
- AlignmentCorrector.correct(processed_source, node, column_delta)
137
- end
138
-
139
136
  private
140
137
 
138
+ def autocorrect(corrector, node)
139
+ AlignmentCorrector.correct(corrector, processed_source, node, column_delta)
140
+ end
141
+
141
142
  # Not all nodes define `bare_access_modifier?` (for example,
142
143
  # `RuboCop::AST::DefNode` does not), so we must check `send_type?` first
143
144
  # to avoid a NoMethodError.
@@ -161,8 +162,10 @@ module RuboCop
161
162
  # to the level of the module (see `AccessModifierIndentation` cop) we
162
163
  # return nil so that `check_alignment` will derive the correct
163
164
  # indentation from the first child that is not an access modifier.
164
- module_indent = display_column(node.parent.source_range)
165
165
  access_modifier_indent = display_column(first_child.source_range)
166
+ return access_modifier_indent unless node.parent
167
+
168
+ module_indent = display_column(node.parent.source_range)
166
169
  access_modifier_indent if access_modifier_indent > module_indent
167
170
  end
168
171
 
@@ -31,60 +31,57 @@ module RuboCop
31
31
  # def foo
32
32
  # bar
33
33
  # end
34
- class IndentationStyle < Cop
34
+ class IndentationStyle < Base
35
35
  include Alignment
36
36
  include ConfigurableEnforcedStyle
37
37
  include RangeHelp
38
+ extend AutoCorrector
38
39
 
39
40
  MSG = '%<type>s detected in indentation.'
40
41
 
41
- def investigate(processed_source)
42
+ def on_new_investigation
42
43
  str_ranges = string_literal_ranges(processed_source.ast)
43
44
 
44
45
  processed_source.lines.each.with_index(1) do |line, lineno|
45
- match = find_offence(line)
46
- next unless match
47
-
48
- range = source_range(processed_source.buffer,
49
- lineno,
50
- match.begin(0)...match.end(0))
46
+ next unless (range = find_offence(line, lineno))
51
47
  next if in_string_literal?(str_ranges, range)
52
48
 
53
- add_offense(range, location: range)
49
+ add_offense(range) do |corrector|
50
+ autocorrect(corrector, range)
51
+ end
54
52
  end
55
53
  end
56
54
 
57
- def autocorrect(range)
55
+ private
56
+
57
+ def autocorrect(corrector, range)
58
58
  if range.source.include?("\t")
59
- autocorrect_lambda_for_tabs(range)
59
+ autocorrect_lambda_for_tabs(corrector, range)
60
60
  else
61
- autocorrect_lambda_for_spaces(range)
61
+ autocorrect_lambda_for_spaces(corrector, range)
62
62
  end
63
63
  end
64
64
 
65
- private
65
+ def find_offence(line, lineno)
66
+ match = if style == :spaces
67
+ line.match(/\A\s*\t+/)
68
+ else
69
+ line.match(/\A\s* +/)
70
+ end
71
+ return unless match
66
72
 
67
- def find_offence(line)
68
- if style == :spaces
69
- line.match(/\A\s*\t+/)
70
- else
71
- line.match(/\A\s* +/)
72
- end
73
+ source_range(processed_source.buffer, lineno, match.begin(0)...match.end(0))
73
74
  end
74
75
 
75
- def autocorrect_lambda_for_tabs(range)
76
- lambda do |corrector|
77
- spaces = ' ' * configured_indentation_width
78
- corrector.replace(range, range.source.gsub(/\t/, spaces))
79
- end
76
+ def autocorrect_lambda_for_tabs(corrector, range)
77
+ spaces = ' ' * configured_indentation_width
78
+ corrector.replace(range, range.source.gsub(/\t/, spaces))
80
79
  end
81
80
 
82
- def autocorrect_lambda_for_spaces(range)
83
- lambda do |corrector|
84
- corrector.replace(range, range.source.gsub(/\A\s+/) do |match|
85
- "\t" * (match.size / configured_indentation_width)
86
- end)
87
- end
81
+ def autocorrect_lambda_for_spaces(corrector, range)
82
+ corrector.replace(range, range.source.gsub(/\A\s+/) do |match|
83
+ "\t" * (match.size / configured_indentation_width)
84
+ end)
88
85
  end
89
86
 
90
87
  def in_string_literal?(ranges, tabs_range)