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
@@ -41,12 +41,7 @@ module RuboCop
41
41
  def investigate(processed_source)
42
42
  return if processed_source.blank?
43
43
 
44
- if force_equal_sign_alignment?
45
- @asgn_tokens = assignment_tokens
46
- @asgn_lines = @asgn_tokens.map(&:line)
47
- # Don't attempt to correct the same = more than once
48
- @corrected = Set.new
49
- end
44
+ @corrected = Set.new if force_equal_sign_alignment?
50
45
 
51
46
  processed_source.tokens.each_cons(2) do |token1, token2|
52
47
  check_tokens(processed_source.ast, token1, token2)
@@ -65,24 +60,10 @@ module RuboCop
65
60
 
66
61
  private
67
62
 
68
- def assignment_tokens
69
- tokens = processed_source.tokens.select(&:equal_sign?)
70
- # we don't want to operate on equals signs which are part of an
71
- # optarg in a method definition
72
- # e.g.: def method(optarg = default_val); end
73
- tokens = remove_optarg_equals(tokens, processed_source)
74
-
75
- # Only attempt to align the first = on each line
76
- Set.new(tokens.uniq(&:line))
77
- end
78
-
79
63
  def check_tokens(ast, token1, token2)
80
64
  return if token2.type == :tNL
81
65
 
82
- if force_equal_sign_alignment? &&
83
- @asgn_tokens.include?(token2) &&
84
- (@asgn_lines.include?(token2.line - 1) ||
85
- @asgn_lines.include?(token2.line + 1))
66
+ if force_equal_sign_alignment? && assignment_tokens.include?(token2)
86
67
  check_assignment(token2)
87
68
  else
88
69
  check_other(token1, token2, ast)
@@ -90,32 +71,18 @@ module RuboCop
90
71
  end
91
72
 
92
73
  def check_assignment(token)
93
- assignment_line = ''
94
- message = ''
95
- if should_aligned_with_preceding_line?(token)
96
- assignment_line = processed_source.preceding_line(token)
97
- message = format(MSG_UNALIGNED_ASGN, location: 'preceding')
98
- else
99
- assignment_line = processed_source.following_line(token)
100
- message = format(MSG_UNALIGNED_ASGN, location: 'following')
101
- end
102
- return if aligned_assignment?(token.pos, assignment_line)
74
+ return unless aligned_with_preceding_assignment(token) == :no
103
75
 
76
+ message = format(MSG_UNALIGNED_ASGN, location: 'preceding')
104
77
  add_offense(token.pos, location: token.pos, message: message)
105
78
  end
106
79
 
107
- def should_aligned_with_preceding_line?(token)
108
- @asgn_lines.include?(token.line - 1)
109
- end
110
-
111
80
  def check_other(token1, token2, ast)
112
81
  return false if allow_for_trailing_comments? &&
113
82
  token2.text.start_with?('#')
114
83
 
115
84
  extra_space_range(token1, token2) do |range|
116
- # Unary + doesn't appear as a token and needs special handling.
117
85
  next if ignored_range?(ast, range.begin_pos)
118
- next if unary_plus_non_offense?(range)
119
86
 
120
87
  add_offense(range, location: range, message: MSG_UNNECESSARY)
121
88
  end
@@ -145,10 +112,6 @@ module RuboCop
145
112
  ignored_ranges(ast).any? { |r| r.include?(start_pos) }
146
113
  end
147
114
 
148
- def unary_plus_non_offense?(range)
149
- range.resize(range.size + 1).source =~ /^ ?\+$/
150
- end
151
-
152
115
  # Returns an array of ranges that should not be reported. It's the
153
116
  # extra spaces between the keys and values in a multiline hash,
154
117
  # since those are handled by the Style/AlignHash cop.
@@ -188,8 +151,8 @@ module RuboCop
188
151
  end
189
152
 
190
153
  def align_equal_signs(range, corrector)
191
- lines = contiguous_assignment_lines(range)
192
- tokens = @asgn_tokens.select { |t| lines.include?(t.line) }
154
+ lines = all_relevant_assignment_lines(range.line)
155
+ tokens = assignment_tokens.select { |t| lines.include?(t.line) }
193
156
 
194
157
  columns = tokens.map { |t| align_column(t) }
195
158
  align_to = columns.max
@@ -209,17 +172,15 @@ module RuboCop
209
172
  end
210
173
  end
211
174
 
212
- def contiguous_assignment_lines(range)
213
- result = [range.line]
175
+ def all_relevant_assignment_lines(line_number)
176
+ last_line_number = processed_source.lines.size
214
177
 
215
- range.line.downto(1) do |lineno|
216
- @asgn_lines.include?(lineno) ? result << lineno : break
217
- end
218
- range.line.upto(processed_source.lines.size) do |lineno|
219
- @asgn_lines.include?(lineno) ? result << lineno : break
220
- end
221
-
222
- result.sort!
178
+ (
179
+ relevant_assignment_lines(line_number.downto(1)) +
180
+ relevant_assignment_lines(line_number.upto(last_line_number))
181
+ )
182
+ .uniq
183
+ .sort
223
184
  end
224
185
 
225
186
  def align_column(asgn_token)
@@ -231,12 +192,6 @@ module RuboCop
231
192
  asgn_token.pos.last_column - spaces + 1
232
193
  end
233
194
 
234
- def remove_optarg_equals(asgn_tokens, processed_source)
235
- optargs = processed_source.ast.each_node(:optarg)
236
- optarg_eql = optargs.map { |o| o.loc.operator.begin_pos }.to_set
237
- asgn_tokens.reject { |t| optarg_eql.include?(t.begin_pos) }
238
- end
239
-
240
195
  def allow_for_trailing_comments?
241
196
  cop_config['AllowBeforeTrailingComments']
242
197
  end
@@ -33,13 +33,22 @@ module RuboCop
33
33
  return unless node.loc.operator
34
34
  return if node.loc.operator.line == rhs.first_line
35
35
 
36
- base = display_column(node.source_range)
36
+ base = display_column(leftmost_multiple_assignment(node).source_range)
37
37
  check_alignment([rhs], base + configured_indentation_width)
38
38
  end
39
39
 
40
40
  def autocorrect(node)
41
41
  AlignmentCorrector.correct(processed_source, node, column_delta)
42
42
  end
43
+
44
+ def leftmost_multiple_assignment(node)
45
+ return node unless same_line?(node, node.parent) &&
46
+ node.parent.assignment?
47
+
48
+ leftmost_multiple_assignment(node.parent)
49
+
50
+ node.parent
51
+ end
43
52
  end
44
53
  end
45
54
  end
@@ -204,7 +204,7 @@ module RuboCop
204
204
  node.source_range.begin_pos > parent.source_range.begin_pos
205
205
  end
206
206
 
207
- def_node_matcher :eligible_method_call?, <<-PATTERN
207
+ def_node_matcher :eligible_method_call?, <<~PATTERN
208
208
  (send _ !:[]= ...)
209
209
  PATTERN
210
210
 
@@ -228,19 +228,21 @@ module RuboCop
228
228
  # containing the previous line that's not a comment line or a blank
229
229
  # line.
230
230
  def previous_code_line(line_number)
231
- @comment_lines ||=
232
- processed_source
233
- .comments
234
- .select { |c| begins_its_line?(c.loc.expression) }
235
- .map { |c| c.loc.line }
236
-
237
231
  line = ''
238
- while line.blank? || @comment_lines.include?(line_number)
232
+ while line.blank? || comment_lines.include?(line_number)
239
233
  line_number -= 1
240
234
  line = processed_source.lines[line_number - 1]
241
235
  end
242
236
  line
243
237
  end
238
+
239
+ def comment_lines
240
+ @comment_lines ||=
241
+ processed_source
242
+ .comments
243
+ .select { |c| begins_its_line?(c.loc.expression) }
244
+ .map { |c| c.loc.line }
245
+ end
244
246
  end
245
247
  end
246
248
  end
@@ -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,
@@ -37,7 +37,7 @@ module RuboCop
37
37
  # # good
38
38
  # # When EnforcedStyle is powerpack, bad code is auto-corrected to
39
39
  # # the following code.
40
- # <<~RUBY
40
+ # <<-RUBY.strip_indent
41
41
  # something
42
42
  # RUBY
43
43
  #
@@ -206,7 +206,8 @@ module RuboCop
206
206
  body = heredoc_body(node)
207
207
  body_indent_level = indent_level(body)
208
208
  correct_indent_level = base_indent_level(node) + indentation_width
209
- body.gsub(/^\s{#{body_indent_level}}/, ' ' * correct_indent_level)
209
+ body.gsub(/^[^\S\r\n]{#{body_indent_level}}/,
210
+ ' ' * correct_indent_level)
210
211
  end
211
212
 
212
213
  def indented_end(node)
@@ -239,7 +240,7 @@ module RuboCop
239
240
  end
240
241
 
241
242
  def indentation_width
242
- @config.for_cop('IndentationWidth')['Width'] || 2
243
+ @config.for_cop('Layout/IndentationWidth')['Width'] || 2
243
244
  end
244
245
 
245
246
  def heredoc_body(node)
@@ -52,7 +52,7 @@ module RuboCop
52
52
  MSG = 'Use %<configured_indentation_width>d (not %<indentation>d) ' \
53
53
  'spaces for%<name>s indentation.'
54
54
 
55
- def_node_matcher :access_modifier?, <<-PATTERN
55
+ def_node_matcher :access_modifier?, <<~PATTERN
56
56
  [(send ...) access_modifier?]
57
57
  PATTERN
58
58
 
@@ -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
@@ -16,6 +16,25 @@ module RuboCop
16
16
  #
17
17
  # # good
18
18
  # # Some comment
19
+ #
20
+ # @example AllowDoxygenCommentStyle: false (default)
21
+ #
22
+ # # bad
23
+ #
24
+ # #**
25
+ # # Some comment
26
+ # # Another line of comment
27
+ # #*
28
+ #
29
+ # @example AllowDoxygenCommentStyle: true
30
+ #
31
+ # # good
32
+ #
33
+ # #**
34
+ # # Some comment
35
+ # # Another line of comment
36
+ # #*
37
+ #
19
38
  class LeadingCommentSpace < Cop
20
39
  include RangeHelp
21
40
 
@@ -25,6 +44,7 @@ module RuboCop
25
44
  processed_source.each_comment do |comment|
26
45
  next unless comment.text =~ /\A#+[^#\s=:+-]/
27
46
  next if comment.loc.line == 1 && allowed_on_first_line?(comment)
47
+ next if allow_doxygen_comment? && doxygen_comment_style?(comment)
28
48
 
29
49
  add_offense(comment)
30
50
  end
@@ -54,6 +74,14 @@ module RuboCop
54
74
  def rackup_config_file?
55
75
  File.basename(processed_source.file_path).eql?('config.ru')
56
76
  end
77
+
78
+ def allow_doxygen_comment?
79
+ cop_config['AllowDoxygenCommentStyle']
80
+ end
81
+
82
+ def doxygen_comment_style?(comment)
83
+ comment.text.start_with?('#*')
84
+ end
57
85
  end
58
86
  end
59
87
  end
@@ -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)
@@ -30,6 +30,8 @@ module RuboCop
30
30
  ANCESTOR_TYPES = %i[kwbegin def defs class module].freeze
31
31
  RUBY_2_5_ANCESTOR_TYPES = (ANCESTOR_TYPES + %i[block]).freeze
32
32
  ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS = %i[def defs].freeze
33
+ ALTERNATIVE_ACCESS_MODIFIERS = %i[public_class_method
34
+ private_class_method].freeze
33
35
 
34
36
  def on_resbody(node)
35
37
  check(node) unless modifier?(node)
@@ -94,13 +96,18 @@ module RuboCop
94
96
  )
95
97
  end
96
98
 
99
+ # rubocop:disable Metrics/AbcSize
97
100
  def alignment_source(node, starting_loc)
98
101
  ending_loc =
99
102
  case node.type
100
103
  when :block, :kwbegin
101
104
  node.loc.begin
102
- when :def, :defs, :class, :module
105
+ when :def, :defs, :class, :module,
106
+ :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
103
107
  node.loc.name
108
+ when :masgn
109
+ mlhs_node, = *node
110
+ mlhs_node.loc.expression
104
111
  else
105
112
  # It is a wrapper with access modifier.
106
113
  node.child_nodes.first.loc.name
@@ -108,6 +115,7 @@ module RuboCop
108
115
 
109
116
  range_between(starting_loc.begin_pos, ending_loc.end_pos).source
110
117
  end
118
+ # rubocop:enable Metrics/AbcSize
111
119
 
112
120
  # We will use ancestor or wrapper with access modifier.
113
121
 
@@ -150,9 +158,7 @@ module RuboCop
150
158
  ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS.include?(node.type)
151
159
 
152
160
  access_modifier_node = node.ancestors.first
153
- return nil unless
154
- access_modifier_node.respond_to?(:access_modifier?) &&
155
- access_modifier_node.access_modifier?
161
+ return nil unless access_modifier?(access_modifier_node)
156
162
 
157
163
  access_modifier_node
158
164
  end
@@ -169,6 +175,16 @@ module RuboCop
169
175
 
170
176
  range_between(begin_pos - current_column, begin_pos)
171
177
  end
178
+
179
+ def access_modifier?(node)
180
+ return true if node.respond_to?(:access_modifier?) &&
181
+ node.access_modifier?
182
+
183
+ return true if node.respond_to?(:method_name) &&
184
+ ALTERNATIVE_ACCESS_MODIFIERS.include?(node.method_name)
185
+
186
+ false
187
+ end
172
188
  end
173
189
  end
174
190
  end