rubocop 0.73.0 → 0.77.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/bin/console +1 -0
  4. data/config/default.yml +332 -295
  5. data/lib/rubocop.rb +46 -30
  6. data/lib/rubocop/ast/builder.rb +1 -0
  7. data/lib/rubocop/ast/node.rb +6 -8
  8. data/lib/rubocop/ast/node/block_node.rb +2 -0
  9. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +1 -12
  10. data/lib/rubocop/ast/node/return_node.rb +24 -0
  11. data/lib/rubocop/cli.rb +11 -227
  12. data/lib/rubocop/cli/command.rb +21 -0
  13. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  14. data/lib/rubocop/cli/command/base.rb +33 -0
  15. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  16. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  17. data/lib/rubocop/cli/command/show_cops.rb +73 -0
  18. data/lib/rubocop/cli/command/version.rb +17 -0
  19. data/lib/rubocop/cli/environment.rb +21 -0
  20. data/lib/rubocop/comment_config.rb +5 -4
  21. data/lib/rubocop/config.rb +28 -537
  22. data/lib/rubocop/config_loader.rb +21 -3
  23. data/lib/rubocop/config_loader_resolver.rb +4 -3
  24. data/lib/rubocop/config_obsoletion.rb +275 -0
  25. data/lib/rubocop/config_validator.rb +246 -0
  26. data/lib/rubocop/cop/autocorrect_logic.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  28. data/lib/rubocop/cop/commissioner.rb +15 -7
  29. data/lib/rubocop/cop/cop.rb +33 -9
  30. data/lib/rubocop/cop/corrector.rb +8 -7
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
  32. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  33. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  34. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
  35. data/lib/rubocop/cop/generator.rb +3 -3
  36. data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
  37. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  38. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  39. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
  40. data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
  41. data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
  42. data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +11 -2
  43. data/lib/rubocop/cop/layout/block_alignment.rb +2 -2
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
  46. data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -7
  48. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -2
  49. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -2
  50. data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
  51. data/lib/rubocop/cop/layout/extra_spacing.rb +15 -60
  52. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +12 -10
  53. data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
  54. data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +4 -4
  55. data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
  56. data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +8 -4
  57. data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +2 -2
  58. data/lib/rubocop/cop/layout/indentation_width.rb +19 -5
  59. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  60. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  61. data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
  62. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  63. data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
  64. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -0
  65. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
  66. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
  67. data/lib/rubocop/cop/layout/space_around_operators.rb +43 -24
  68. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
  69. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +8 -5
  70. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +7 -0
  71. data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
  72. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
  73. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  74. data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
  75. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  76. data/lib/rubocop/cop/lint/debugger.rb +1 -3
  77. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  78. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  79. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  80. data/lib/rubocop/cop/lint/erb_new_arguments.rb +61 -4
  81. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +10 -36
  82. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  83. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  84. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
  85. data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
  86. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  87. data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +24 -24
  88. data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +6 -8
  89. data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +1 -1
  90. data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +12 -7
  91. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +7 -7
  92. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  93. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  94. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -6
  95. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  96. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
  97. data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
  98. data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
  99. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
  100. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  101. data/lib/rubocop/cop/lint/void.rb +7 -26
  102. data/lib/rubocop/cop/message_annotator.rb +16 -7
  103. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  104. data/lib/rubocop/cop/metrics/line_length.rb +48 -42
  105. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  106. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
  107. data/lib/rubocop/cop/migration/department_name.rb +44 -0
  108. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  109. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  110. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  111. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  112. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  113. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  114. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  115. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  116. data/lib/rubocop/cop/mixin/statement_modifier.rb +5 -2
  117. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  118. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -6
  119. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  120. data/lib/rubocop/cop/naming/file_name.rb +12 -5
  121. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
  122. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  123. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +3 -3
  124. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  125. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  126. data/lib/rubocop/cop/offense.rb +18 -7
  127. data/lib/rubocop/cop/registry.rb +22 -1
  128. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  129. data/lib/rubocop/cop/style/alias.rb +1 -1
  130. data/lib/rubocop/cop/style/array_join.rb +1 -1
  131. data/lib/rubocop/cop/style/attr.rb +2 -2
  132. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  133. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +35 -16
  134. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  135. data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
  136. data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +5 -7
  138. data/lib/rubocop/cop/style/constant_visibility.rb +13 -2
  139. data/lib/rubocop/cop/style/copyright.rb +11 -7
  140. data/lib/rubocop/cop/style/documentation_method.rb +44 -0
  141. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +10 -4
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  143. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  144. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  145. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  146. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  147. data/lib/rubocop/cop/style/expand_path_arguments.rb +1 -1
  148. data/lib/rubocop/cop/style/format_string.rb +10 -7
  149. data/lib/rubocop/cop/style/format_string_token.rb +19 -68
  150. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +28 -33
  151. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  152. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  153. data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -15
  154. data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
  155. data/lib/rubocop/cop/style/inverse_methods.rb +19 -13
  156. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  157. data/lib/rubocop/cop/style/lambda.rb +0 -2
  158. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
  159. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -25
  160. data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
  161. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  162. data/lib/rubocop/cop/style/mixin_usage.rb +11 -1
  163. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  164. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
  165. data/lib/rubocop/cop/style/nested_modifier.rb +22 -4
  166. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
  167. data/lib/rubocop/cop/style/next.rb +5 -5
  168. data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
  169. data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
  170. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  171. data/lib/rubocop/cop/style/or_assignment.rb +6 -1
  172. data/lib/rubocop/cop/style/parentheses_around_condition.rb +14 -0
  173. data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
  174. data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
  175. data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
  176. data/lib/rubocop/cop/style/redundant_parentheses.rb +16 -7
  177. data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
  178. data/lib/rubocop/cop/style/redundant_return.rb +39 -29
  179. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  180. data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +5 -5
  181. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  182. data/lib/rubocop/cop/style/safe_navigation.rb +23 -3
  183. data/lib/rubocop/cop/style/semicolon.rb +13 -2
  184. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  185. data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
  186. data/lib/rubocop/cop/style/ternary_parentheses.rb +19 -0
  187. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  188. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  189. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  190. data/lib/rubocop/cop/team.rb +5 -0
  191. data/lib/rubocop/cop/util.rb +1 -1
  192. data/lib/rubocop/cop/utils/format_string.rb +120 -0
  193. data/lib/rubocop/cop/variable_force.rb +7 -5
  194. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  195. data/lib/rubocop/core_ext/string.rb +0 -24
  196. data/lib/rubocop/formatter/clang_style_formatter.rb +9 -6
  197. data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
  198. data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
  199. data/lib/rubocop/formatter/formatter_set.rb +16 -15
  200. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  201. data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
  202. data/lib/rubocop/formatter/tap_formatter.rb +18 -7
  203. data/lib/rubocop/magic_comment.rb +4 -0
  204. data/lib/rubocop/node_pattern.rb +3 -1
  205. data/lib/rubocop/options.rb +17 -22
  206. data/lib/rubocop/path_util.rb +1 -1
  207. data/lib/rubocop/processed_source.rb +5 -1
  208. data/lib/rubocop/rake_task.rb +1 -0
  209. data/lib/rubocop/result_cache.rb +22 -8
  210. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  211. data/lib/rubocop/runner.rb +55 -32
  212. data/lib/rubocop/target_finder.rb +12 -6
  213. data/lib/rubocop/version.rb +1 -1
  214. metadata +47 -32
  215. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
  216. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -22
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Layout
6
6
  # This cop checks the indentation of the first key in a hash literal
7
7
  # where the opening brace and the first key are on separate lines. The
8
- # other keys' indentations are handled by the AlignHash cop.
8
+ # other keys' indentations are handled by the HashAlignment cop.
9
9
  #
10
10
  # By default, Hash literals that are arguments in a method call with
11
11
  # parentheses, and where the opening curly brace of the hash is on the
@@ -77,7 +77,7 @@ module RuboCop
77
77
  # and_now_for_something = {
78
78
  # completely: :different
79
79
  # }
80
- class IndentFirstHashElement < Cop
80
+ class FirstHashElementIndentation < Cop
81
81
  include Alignment
82
82
  include ConfigurableEnforcedStyle
83
83
  include MultilineElementIndentation
@@ -113,7 +113,7 @@ module RuboCop
113
113
  first_pair = hash_node.pairs.first
114
114
 
115
115
  if first_pair
116
- return if first_pair.source_range.line == left_brace.line
116
+ return if first_pair.first_line == left_brace.line
117
117
 
118
118
  if separator_style?(first_pair)
119
119
  check_based_on_longest_key(hash_node, left_brace,
@@ -149,7 +149,7 @@ module RuboCop
149
149
  def separator_style?(first_pair)
150
150
  separator = first_pair.loc.operator
151
151
  key = "Enforced#{separator.is?(':') ? 'Colon' : 'HashRocket'}Style"
152
- config.for_cop('Layout/AlignHash')[key] == 'separator'
152
+ config.for_cop('Layout/HashAlignment')[key] == 'separator'
153
153
  end
154
154
 
155
155
  def check_based_on_longest_key(hash_node, left_brace, left_parenthesis)
@@ -5,10 +5,10 @@ module RuboCop
5
5
  module Layout
6
6
  # This cop checks the indentation of the first parameter in a method
7
7
  # definition. Parameters after the first one are checked by
8
- # Layout/AlignParameters, not by this cop.
8
+ # Layout/ParameterAlignment, not by this cop.
9
9
  #
10
10
  # For indenting the first argument of method *calls*, check out
11
- # Layout/IndentFirstArgument, which supports options related to
11
+ # Layout/FirstArgumentIndentation, which supports options related to
12
12
  # nesting that are irrelevant for method *definitions*.
13
13
  #
14
14
  # @example
@@ -41,7 +41,7 @@ module RuboCop
41
41
  # second_param)
42
42
  # 123
43
43
  # end
44
- class IndentFirstParameter < Cop
44
+ class FirstParameterIndentation < Cop
45
45
  include Alignment
46
46
  include ConfigurableEnforcedStyle
47
47
  include MultilineElementIndentation
@@ -175,8 +175,8 @@ module RuboCop
175
175
  # do_something({foo: 1,
176
176
  # bar: 2})
177
177
  #
178
- class AlignHash < Cop
179
- include HashAlignment
178
+ class HashAlignment < Cop
179
+ include HashAlignmentStyles
180
180
  include RangeHelp
181
181
 
182
182
  MSG = 'Align the elements of a hash literal if they span more than ' \
@@ -220,14 +220,18 @@ module RuboCop
220
220
 
221
221
  private
222
222
 
223
+ def reset!
224
+ self.offences_by = {}
225
+ self.column_deltas = Hash.new { |hash, key| hash[key] = {} }
226
+ end
227
+
223
228
  def double_splat?(node)
224
229
  node.children.last.is_a?(Symbol)
225
230
  end
226
231
 
227
232
  def check_pairs(node)
228
233
  first_pair = node.pairs.first
229
- self.offences_by = {}
230
- self.column_deltas = Hash.new { |hash, key| hash[key] = {} }
234
+ reset!
231
235
 
232
236
  alignment_for(first_pair).each do |alignment|
233
237
  delta = alignment.deltas_for_first_pair(first_pair, node)
@@ -49,7 +49,7 @@ module RuboCop
49
49
  # something
50
50
  # RUBY
51
51
  #
52
- class IndentHeredoc < Cop
52
+ class HeredocIndentation < Cop
53
53
  include Heredoc
54
54
  include ConfigurableEnforcedStyle
55
55
 
@@ -240,7 +240,7 @@ module RuboCop
240
240
  end
241
241
 
242
242
  def indentation_width
243
- @config.for_cop('IndentationWidth')['Width'] || 2
243
+ @config.for_cop('Layout/IndentationWidth')['Width'] || 2
244
244
  end
245
245
 
246
246
  def heredoc_body(node)
@@ -158,11 +158,7 @@ module RuboCop
158
158
  if indentation_consistency_style == 'indented_internal_methods'
159
159
  check_members_for_indented_internal_methods_style(members)
160
160
  else
161
- members.first.children.each do |member|
162
- next if member.send_type? && member.access_modifier?
163
-
164
- check_indentation(base, member)
165
- end
161
+ check_members_for_normal_style(base, members)
166
162
  end
167
163
  end
168
164
 
@@ -170,6 +166,8 @@ module RuboCop
170
166
  return unless member
171
167
 
172
168
  if access_modifier?(member.children.first)
169
+ return if access_modifier_indentation_style == 'outdent'
170
+
173
171
  member.children.first
174
172
  else
175
173
  member
@@ -183,6 +181,14 @@ module RuboCop
183
181
  end
184
182
  end
185
183
 
184
+ def check_members_for_normal_style(base, members)
185
+ members.first.children.each do |member|
186
+ next if member.send_type? && member.access_modifier?
187
+
188
+ check_indentation(base, member)
189
+ end
190
+ end
191
+
186
192
  def each_member(members)
187
193
  previous_modifier = nil
188
194
  members.first.children.each do |member|
@@ -199,6 +205,14 @@ module RuboCop
199
205
  indentation_consistency_style == 'indented_internal_methods'
200
206
  end
201
207
 
208
+ def special_modifier?(node)
209
+ node.bare_access_modifier? && SPECIAL_MODIFIERS.include?(node.source)
210
+ end
211
+
212
+ def access_modifier_indentation_style
213
+ config.for_cop('Layout/AccessModifierIndentation')['EnforcedStyle']
214
+ end
215
+
202
216
  def indentation_consistency_style
203
217
  config.for_cop('Layout/IndentationConsistency')['EnforcedStyle']
204
218
  end
@@ -27,7 +27,7 @@ module RuboCop
27
27
  # # good
28
28
  # # (start of file)
29
29
  # # a comment
30
- class LeadingBlankLines < Cop
30
+ class LeadingEmptyLines < Cop
31
31
  MSG = 'Unnecessary blank line at the beginning of the source.'
32
32
 
33
33
  def investigate(processed_source)
@@ -43,7 +43,7 @@ module RuboCop
43
43
  'on the same line as the assignment operator `=`.'
44
44
 
45
45
  def check_assignment(node, rhs)
46
- return if node.send_type?
46
+ return if node.send_type? && node.loc.operator&.source != '='
47
47
  return unless rhs
48
48
  return unless supported_types.include?(rhs.type)
49
49
  return if rhs.first_line == rhs.last_line
@@ -5,7 +5,9 @@ module RuboCop
5
5
  module Layout
6
6
  # This cop checks whether the multiline do end blocks have a newline
7
7
  # after the start of the block. Additionally, it checks whether the block
8
- # arguments, if any, are on the same line as the start of the block.
8
+ # arguments, if any, are on the same line as the start of the
9
+ # block. Putting block arguments on separate lines, because the whole
10
+ # line would otherwise be too long, is accepted.
9
11
  #
10
12
  # @example
11
13
  # # bad
@@ -35,6 +37,17 @@ module RuboCop
35
37
  # foo(i)
36
38
  # bar(i)
37
39
  # }
40
+ #
41
+ # # good
42
+ # blah { |
43
+ # long_list,
44
+ # of_parameters,
45
+ # that_would_not,
46
+ # fit_on_one_line
47
+ # |
48
+ # foo(i)
49
+ # bar(i)
50
+ # }
38
51
  class MultilineBlockLayout < Cop
39
52
  include RangeHelp
40
53
 
@@ -42,11 +55,13 @@ module RuboCop
42
55
  'the block start.'
43
56
  ARG_MSG = 'Block argument expression is not on the same line as the ' \
44
57
  'block start.'
58
+ PIPE_SIZE = '|'.length
45
59
 
46
60
  def on_block(node)
47
61
  return if node.single_line?
48
62
 
49
- unless args_on_beginning_line?(node)
63
+ unless args_on_beginning_line?(node) ||
64
+ line_break_necessary_in_args?(node)
50
65
  add_offense_for_expression(node, node.arguments, ARG_MSG)
51
66
  end
52
67
 
@@ -79,6 +94,13 @@ module RuboCop
79
94
  node.loc.begin.line == node.arguments.loc.last_line
80
95
  end
81
96
 
97
+ def line_break_necessary_in_args?(node)
98
+ needed_length = node.source_range.column +
99
+ node.source.lines.first.length +
100
+ block_arg_string(node.arguments).length + PIPE_SIZE
101
+ needed_length > max_line_length
102
+ end
103
+
82
104
  def add_offense_for_expression(node, expr, msg)
83
105
  expression = expr.source_range
84
106
  range = range_between(expression.begin_pos, expression.end_pos)
@@ -26,7 +26,7 @@ module RuboCop
26
26
  'on a separate line.'
27
27
 
28
28
  def on_send(node)
29
- return if node.method_name == :[]=
29
+ return if node.method?(:[]=)
30
30
 
31
31
  args = node.arguments
32
32
 
@@ -68,7 +68,7 @@ module RuboCop
68
68
  # baz)
69
69
  # 123
70
70
  # end
71
- class AlignParameters < Cop
71
+ class ParameterAlignment < Cop
72
72
  include Alignment
73
73
 
74
74
  ALIGN_PARAMS_MSG = 'Align the parameters of a method definition if ' \
@@ -96,6 +96,7 @@ module RuboCop
96
96
  )
97
97
  end
98
98
 
99
+ # rubocop:disable Metrics/AbcSize
99
100
  def alignment_source(node, starting_loc)
100
101
  ending_loc =
101
102
  case node.type
@@ -114,6 +115,7 @@ module RuboCop
114
115
 
115
116
  range_between(starting_loc.begin_pos, ending_loc.end_pos).source
116
117
  end
118
+ # rubocop:enable Metrics/AbcSize
117
119
 
118
120
  # We will use ancestor or wrapper with access modifier.
119
121
 
@@ -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
@@ -30,10 +30,12 @@ module RuboCop
30
30
 
31
31
  DO = 'do'
32
32
  SAFE_NAVIGATION = '&.'
33
+ NAMESPACE_OPERATOR = '::'
33
34
  ACCEPT_LEFT_PAREN =
34
35
  %w[break defined? next not rescue return super yield].freeze
35
36
  ACCEPT_LEFT_SQUARE_BRACKET =
36
37
  %w[super yield].freeze
38
+ ACCEPT_NAMESPACE_OPERATOR = 'super'
37
39
 
38
40
  def on_and(node)
39
41
  check(node, [:operator].freeze) if node.keyword?
@@ -193,6 +195,8 @@ module RuboCop
193
195
 
194
196
  return false if accepted_opening_delimiter?(range, char)
195
197
  return false if safe_navigation_call?(range, pos)
198
+ return false if accept_namespace_operator?(range) &&
199
+ namespace_operator?(range, pos)
196
200
 
197
201
  char !~ /[\s;,#\\\)\}\]\.]/
198
202
  end
@@ -212,10 +216,18 @@ module RuboCop
212
216
  ACCEPT_LEFT_SQUARE_BRACKET.include?(range.source)
213
217
  end
214
218
 
219
+ def accept_namespace_operator?(range)
220
+ ACCEPT_NAMESPACE_OPERATOR == range.source
221
+ end
222
+
215
223
  def safe_navigation_call?(range, pos)
216
224
  range.source_buffer.source[pos, 2].start_with?(SAFE_NAVIGATION)
217
225
  end
218
226
 
227
+ def namespace_operator?(range, pos)
228
+ range.source_buffer.source[pos, 2].start_with?(NAMESPACE_OPERATOR)
229
+ end
230
+
219
231
  def preceded_by_operator?(node, _range)
220
232
  # regular dotted method calls bind more tightly than operators
221
233
  # so we need to climb up the AST past them
@@ -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)
@@ -150,7 +169,7 @@ module RuboCop
150
169
  end
151
170
 
152
171
  def align_hash_cop_config
153
- config.for_cop('Layout/AlignHash')
172
+ config.for_cop('Layout/HashAlignment')
154
173
  end
155
174
 
156
175
  def hash_table_style?