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
@@ -3,7 +3,9 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # Checks the spacing inside and after block parameters pipes.
6
+ # Checks the spacing inside and after block parameters pipes. Line breaks
7
+ # inside parameter pipes are checked by `Layout/MultilineBlockLayout` and
8
+ # not by this cop.
7
9
  #
8
10
  # @example EnforcedStyleInsidePipes: no_space (default)
9
11
  # # bad
@@ -156,6 +158,8 @@ module RuboCop
156
158
  return if space_begin_pos >= space_end_pos
157
159
 
158
160
  range = range_between(space_begin_pos, space_end_pos)
161
+ return if range.source.include?("\n")
162
+
159
163
  add_offense(range, location: range,
160
164
  message: "#{msg} block parameter detected.")
161
165
  end
@@ -34,14 +34,14 @@ module RuboCop
34
34
 
35
35
  return if hash_table_style? && !node.parent.pairs_on_same_line?
36
36
 
37
- check_operator(node.loc.operator, node.source_range)
37
+ check_operator(:pair, node.loc.operator, node.source_range)
38
38
  end
39
39
 
40
40
  def on_if(node)
41
41
  return unless node.ternary?
42
42
 
43
- check_operator(node.loc.question, node.if_branch.source_range)
44
- check_operator(node.loc.colon, node.else_branch.source_range)
43
+ check_operator(:if, node.loc.question, node.if_branch.source_range)
44
+ check_operator(:if, node.loc.colon, node.else_branch.source_range)
45
45
  end
46
46
 
47
47
  def on_resbody(node)
@@ -49,23 +49,33 @@ module RuboCop
49
49
 
50
50
  _, variable, = *node
51
51
 
52
- check_operator(node.loc.assoc, variable.source_range)
52
+ check_operator(:resbody, node.loc.assoc, variable.source_range)
53
53
  end
54
54
 
55
55
  def on_send(node)
56
56
  if node.setter_method?
57
57
  on_special_asgn(node)
58
58
  elsif regular_operator?(node)
59
- check_operator(node.loc.selector, node.first_argument.source_range)
59
+ check_operator(:send,
60
+ node.loc.selector,
61
+ node.first_argument.source_range)
60
62
  end
61
63
  end
62
64
 
65
+ def on_assignment(node)
66
+ _, rhs, = *node
67
+
68
+ return unless rhs
69
+
70
+ check_operator(:assignment, node.loc.operator, rhs.source_range)
71
+ end
72
+
63
73
  def on_binary(node)
64
74
  _, rhs, = *node
65
75
 
66
76
  return unless rhs
67
77
 
68
- check_operator(node.loc.operator, rhs.source_range)
78
+ check_operator(:binary, node.loc.operator, rhs.source_range)
69
79
  end
70
80
 
71
81
  def on_special_asgn(node)
@@ -73,20 +83,20 @@ module RuboCop
73
83
 
74
84
  return unless right
75
85
 
76
- check_operator(node.loc.operator, right.source_range)
86
+ check_operator(:special_asgn, node.loc.operator, right.source_range)
77
87
  end
78
88
 
79
89
  alias on_or on_binary
80
90
  alias on_and on_binary
81
- alias on_lvasgn on_binary
82
- alias on_masgn on_binary
91
+ alias on_lvasgn on_assignment
92
+ alias on_masgn on_assignment
83
93
  alias on_casgn on_special_asgn
84
- alias on_ivasgn on_binary
85
- alias on_cvasgn on_binary
86
- alias on_gvasgn on_binary
94
+ alias on_ivasgn on_assignment
95
+ alias on_cvasgn on_assignment
96
+ alias on_gvasgn on_assignment
87
97
  alias on_class on_binary
88
- alias on_or_asgn on_binary
89
- alias on_and_asgn on_binary
98
+ alias on_or_asgn on_assignment
99
+ alias on_and_asgn on_assignment
90
100
  alias on_op_asgn on_special_asgn
91
101
 
92
102
  def autocorrect(range)
@@ -113,35 +123,44 @@ module RuboCop
113
123
  !IRREGULAR_METHODS.include?(send_node.method_name)
114
124
  end
115
125
 
116
- def check_operator(operator, right_operand)
126
+ def check_operator(type, operator, right_operand)
117
127
  with_space = range_with_surrounding_space(range: operator)
118
128
  return if with_space.source.start_with?("\n")
119
129
 
120
- offense(operator, with_space, right_operand) do |msg|
130
+ offense(type, operator, with_space, right_operand) do |msg|
121
131
  add_offense(with_space, location: operator, message: msg)
122
132
  end
123
133
  end
124
134
 
125
- def offense(operator, with_space, right_operand)
126
- msg = offense_message(operator, with_space, right_operand)
135
+ def offense(type, operator, with_space, right_operand)
136
+ msg = offense_message(type, operator, with_space, right_operand)
127
137
  yield msg if msg
128
138
  end
129
139
 
130
- def offense_message(operator, with_space, right_operand)
140
+ def offense_message(type, operator, with_space, right_operand)
131
141
  if operator.is?('**')
132
142
  'Space around operator `**` detected.' unless with_space.is?('**')
133
143
  elsif with_space.source !~ /^\s.*\s$/
134
144
  "Surrounding space missing for operator `#{operator.source}`."
135
- elsif excess_leading_space?(operator, with_space) ||
145
+ elsif excess_leading_space?(type, operator, with_space) ||
136
146
  excess_trailing_space?(right_operand, with_space)
137
147
  "Operator `#{operator.source}` should be surrounded " \
138
148
  'by a single space.'
139
149
  end
140
150
  end
141
151
 
142
- def excess_leading_space?(operator, with_space)
143
- with_space.source.start_with?(EXCESSIVE_SPACE) &&
144
- (!allow_for_alignment? || !aligned_with_operator?(operator))
152
+ def excess_leading_space?(type, operator, with_space)
153
+ return false unless allow_for_alignment?
154
+ return false unless with_space.source.start_with?(EXCESSIVE_SPACE)
155
+
156
+ return !aligned_with_operator?(operator) unless type == :assignment
157
+
158
+ token = Token.new(operator, nil, operator.source)
159
+ align_preceding = aligned_with_preceding_assignment(token)
160
+
161
+ return align_preceding == :no unless align_preceding == :none
162
+
163
+ aligned_with_subsequent_assignment(token) != :yes
145
164
  end
146
165
 
147
166
  def excess_trailing_space?(right_operand, with_space)
@@ -48,9 +48,7 @@ module RuboCop
48
48
  if style == :require_space
49
49
  corrector.insert_before(children[1].source_range, ' ')
50
50
  else
51
- space_range = range_between(children[0].source_range.end_pos,
52
- children[1].source_range.begin_pos)
53
- corrector.remove(space_range)
51
+ corrector.remove(space_after_arrow(lambda_node))
54
52
  end
55
53
  end
56
54
  end
@@ -62,10 +60,14 @@ module RuboCop
62
60
  end
63
61
 
64
62
  def space_after_arrow?(lambda_node)
65
- arrow = lambda_node.parent.children[0]
66
- parentheses = lambda_node.parent.children[1]
67
- (parentheses.source_range.begin_pos - arrow.source_range.end_pos)
68
- .positive?
63
+ !space_after_arrow(lambda_node).empty?
64
+ end
65
+
66
+ def space_after_arrow(lambda_node)
67
+ arrow = lambda_node.parent.children[0].source_range
68
+ parentheses = lambda_node.parent.children[1].source_range
69
+
70
+ arrow.end.join(parentheses.begin)
69
71
  end
70
72
 
71
73
  def range_of_offense(node)
@@ -132,7 +132,7 @@ module RuboCop
132
132
  line, col = line_and_column_for(token)
133
133
  return true if col == -1
134
134
 
135
- processed_source.lines[line][0..col].delete(' ').empty?
135
+ processed_source.lines[line][0..col] !~ /\S/
136
136
  end
137
137
 
138
138
  def index_for(node, token)
@@ -210,18 +210,21 @@ module RuboCop
210
210
 
211
211
  def compact_corrections(corrector, node, left, right)
212
212
  if qualifies_for_compact?(node, left, side: :left)
213
- range = side_space_range(range: left.pos, side: :right)
214
- corrector.remove(range)
213
+ compact(corrector, left, :right)
215
214
  elsif !left.space_after?
216
215
  corrector.insert_after(left.pos, ' ')
217
216
  end
218
217
  if qualifies_for_compact?(node, right)
219
- range = side_space_range(range: right.pos, side: :left)
220
- corrector.remove(range)
218
+ compact(corrector, right, :left)
221
219
  elsif !right.space_before?
222
220
  corrector.insert_before(right.pos, ' ')
223
221
  end
224
222
  end
223
+
224
+ def compact(corrector, bracket, side)
225
+ range = side_space_range(range: bracket.pos, side: side)
226
+ corrector.remove(range)
227
+ end
225
228
  end
226
229
  end
227
230
  end
@@ -84,6 +84,13 @@ module RuboCop
84
84
  def on_block(node)
85
85
  return if node.keywords?
86
86
 
87
+ # Do not register an offense for multi-line empty braces. That means
88
+ # preventing auto-correction to single-line empty braces. It will
89
+ # conflict with auto-correction by `Layout/SpaceInsideBlockBraces` cop
90
+ # if auto-corrected to a single-line empty braces.
91
+ # See: https://github.com/rubocop-hq/rubocop/issues/7363
92
+ return if node.body.nil? && node.multiline?
93
+
87
94
  left_brace = node.loc.begin
88
95
  right_brace = node.loc.end
89
96
 
@@ -130,7 +137,8 @@ module RuboCop
130
137
  args_delimiter = node.arguments.loc.begin # Can be ( | or nil.
131
138
 
132
139
  check_left_brace(inner, node.loc.begin, args_delimiter)
133
- check_right_brace(inner, node.loc.end, node.single_line?)
140
+ check_right_brace(inner, node.loc.begin, node.loc.end,
141
+ node.single_line?)
134
142
  end
135
143
 
136
144
  def check_left_brace(inner, left_brace, args_delimiter)
@@ -141,15 +149,26 @@ module RuboCop
141
149
  end
142
150
  end
143
151
 
144
- def check_right_brace(inner, right_brace, single_line)
152
+ def check_right_brace(inner, left_brace, right_brace, single_line)
145
153
  if single_line && inner =~ /\S$/
146
154
  no_space(right_brace.begin_pos, right_brace.end_pos,
147
155
  'Space missing inside }.')
148
156
  else
157
+ return if multiline_block?(left_brace, right_brace) &&
158
+ aligned_braces?(left_brace, right_brace)
159
+
149
160
  space_inside_right_brace(right_brace)
150
161
  end
151
162
  end
152
163
 
164
+ def multiline_block?(left_brace, right_brace)
165
+ left_brace.first_line != right_brace.first_line
166
+ end
167
+
168
+ def aligned_braces?(left_brace, right_brace)
169
+ left_brace.first_line == right_brace.last_column
170
+ end
171
+
153
172
  def no_space_inside_left_brace(left_brace, args_delimiter)
154
173
  if pipe?(args_delimiter)
155
174
  if left_brace.end_pos == args_delimiter.begin_pos &&
@@ -72,7 +72,7 @@ module RuboCop
72
72
  # If the second token is a comment, that means that a line break
73
73
  # follows, and that the rules for space inside don't apply.
74
74
  next if token2.comment?
75
- next unless token2.line == token1.line && token1.space_after?
75
+ next unless same_line?(token1, token2) && token1.space_after?
76
76
 
77
77
  yield range_between(token1.end_pos, token2.begin_pos)
78
78
  end
@@ -82,17 +82,18 @@ module RuboCop
82
82
  tokens.each_cons(2) do |token1, token2|
83
83
  next if can_be_ignored?(token1, token2)
84
84
 
85
- next unless token2.line == token1.line && !token1.space_after?
86
-
87
85
  if token1.left_parens?
88
86
  yield range_between(token2.begin_pos, token2.begin_pos + 1)
89
-
90
87
  elsif token2.right_parens?
91
88
  yield range_between(token2.begin_pos, token2.end_pos)
92
89
  end
93
90
  end
94
91
  end
95
92
 
93
+ def same_line?(token1, token2)
94
+ token1.line == token2.line
95
+ end
96
+
96
97
  def parens?(token1, token2)
97
98
  token1.left_parens? || token2.right_parens?
98
99
  end
@@ -104,8 +105,7 @@ module RuboCop
104
105
  # follows, and that the rules for space inside don't apply.
105
106
  return true if token2.comment?
106
107
 
107
- # Ignore empty parens. # TODO: Could be configurable.
108
- return true if token1.left_parens? && token2.right_parens?
108
+ return true unless same_line?(token1, token2) && !token1.space_after?
109
109
  end
110
110
  end
111
111
  end
@@ -19,61 +19,45 @@ module RuboCop
19
19
  # # good
20
20
  # var = "This is the #{ space } example"
21
21
  class SpaceInsideStringInterpolation < Cop
22
+ include Interpolation
23
+ include SurroundingSpace
22
24
  include ConfigurableEnforcedStyle
23
25
  include RangeHelp
24
26
 
25
27
  NO_SPACE_MSG = 'Space inside string interpolation detected.'
26
- SPACE_MSG = 'Missing space around string interpolation detected.'
28
+ SPACE_MSG = 'Missing space inside string interpolation detected.'
27
29
 
28
- def on_dstr(node)
29
- each_style_violation(node) do |final_node|
30
- add_offense(final_node)
31
- end
32
- end
30
+ def on_interpolation(begin_node)
31
+ return if begin_node.multiline?
33
32
 
34
- def autocorrect(node)
35
- new_source = style == :no_space ? node.source : " #{node.source} "
36
- lambda do |corrector|
37
- corrector.replace(
38
- range_with_surrounding_space(range: node.source_range),
39
- new_source
40
- )
33
+ delims = delimiters(begin_node)
34
+ return if empty_brackets?(*delims)
35
+
36
+ if style == :no_space
37
+ no_space_offenses(begin_node, *delims, NO_SPACE_MSG)
38
+ else
39
+ space_offenses(begin_node, *delims, SPACE_MSG)
41
40
  end
42
41
  end
43
42
 
44
- private
45
-
46
- def each_style_violation(node)
47
- node.each_child_node(:begin) do |begin_node|
48
- final_node = begin_node.children.last
49
- next unless final_node
43
+ def autocorrect(begin_node)
44
+ lambda do |corrector|
45
+ delims = delimiters(begin_node)
50
46
 
51
- if style == :no_space && space_on_any_side?(final_node)
52
- yield final_node
53
- elsif style == :space && !space_on_each_side?(final_node)
54
- yield final_node
47
+ if style == :no_space
48
+ SpaceCorrector.remove_space(processed_source, corrector, *delims)
49
+ else
50
+ SpaceCorrector.add_space(processed_source, corrector, *delims)
55
51
  end
56
52
  end
57
53
  end
58
54
 
59
- def message(_node)
60
- style == :no_space ? NO_SPACE_MSG : SPACE_MSG
61
- end
62
-
63
- def space_on_any_side?(node)
64
- interp = node.source_range
65
- interp_with_surrounding_space =
66
- range_with_surrounding_space(range: interp)
67
-
68
- interp_with_surrounding_space != interp
69
- end
70
-
71
- def space_on_each_side?(node)
72
- interp = node.source_range
73
- interp_with_surrounding_space =
74
- range_with_surrounding_space(range: interp)
55
+ private
75
56
 
76
- interp_with_surrounding_space.source == " #{interp.source} "
57
+ def delimiters(begin_node)
58
+ left = processed_source.tokens[index_of_first_token(begin_node)]
59
+ right = processed_source.tokens[index_of_last_token(begin_node)]
60
+ [left, right]
77
61
  end
78
62
  end
79
63
  end
@@ -30,16 +30,13 @@ module RuboCop
30
30
  str_ranges = string_literal_ranges(processed_source.ast)
31
31
 
32
32
  processed_source.lines.each.with_index(1) do |line, lineno|
33
- match = line.match(/^([^\t]*)\t+/)
33
+ match = line.match(/\t+/)
34
34
  next unless match
35
35
 
36
- prefix = match.captures[0]
37
- col = prefix.length
38
- next if in_string_literal?(str_ranges, lineno, col)
39
-
40
36
  range = source_range(processed_source.buffer,
41
37
  lineno,
42
- col...match.end(0))
38
+ match.begin(0)...match.end(0))
39
+ next if in_string_literal?(str_ranges, range)
43
40
 
44
41
  add_offense(range, location: range)
45
42
  end
@@ -54,16 +51,9 @@ module RuboCop
54
51
 
55
52
  private
56
53
 
57
- # rubocop:disable Metrics/CyclomaticComplexity
58
- def in_string_literal?(ranges, line, col)
59
- ranges.any? do |range|
60
- (range.line == line && range.column <= col) ||
61
- (range.line < line && line < range.last_line) ||
62
- (range.line != line && range.last_line == line &&
63
- range.last_column >= col)
64
- end
54
+ def in_string_literal?(ranges, tabs_range)
55
+ ranges.any? { |range| range.contains?(tabs_range) }
65
56
  end
66
- # rubocop:enable Metrics/CyclomaticComplexity
67
57
 
68
58
  def string_literal_ranges(ast)
69
59
  # which lines start inside a string literal?
@@ -72,13 +62,11 @@ module RuboCop
72
62
  ast.each_node(:str, :dstr).each_with_object(Set.new) do |str, ranges|
73
63
  loc = str.location
74
64
 
75
- range = if str.heredoc?
76
- loc.heredoc_body
77
- else
78
- loc.expression
79
- end
80
-
81
- ranges << range
65
+ if str.heredoc?
66
+ ranges << loc.heredoc_body
67
+ elsif loc.respond_to?(:begin) && loc.begin
68
+ ranges << loc.expression
69
+ end
82
70
  end
83
71
  end
84
72
  end