rubocop 0.74.0 → 0.78.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 (213) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/config/default.yml +366 -318
  4. data/lib/rubocop.rb +48 -32
  5. data/lib/rubocop/ast/builder.rb +1 -0
  6. data/lib/rubocop/ast/node.rb +5 -1
  7. data/lib/rubocop/ast/node/block_node.rb +2 -0
  8. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +1 -12
  9. data/lib/rubocop/ast/node/return_node.rb +24 -0
  10. data/lib/rubocop/cli.rb +11 -227
  11. data/lib/rubocop/cli/command.rb +21 -0
  12. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  13. data/lib/rubocop/cli/command/base.rb +33 -0
  14. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  15. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  16. data/lib/rubocop/cli/command/show_cops.rb +73 -0
  17. data/lib/rubocop/cli/command/version.rb +17 -0
  18. data/lib/rubocop/cli/environment.rb +21 -0
  19. data/lib/rubocop/comment_config.rb +5 -4
  20. data/lib/rubocop/config.rb +12 -1
  21. data/lib/rubocop/config_loader.rb +21 -3
  22. data/lib/rubocop/config_loader_resolver.rb +4 -3
  23. data/lib/rubocop/config_obsoletion.rb +85 -11
  24. data/lib/rubocop/config_validator.rb +28 -19
  25. data/lib/rubocop/cop/autocorrect_logic.rb +3 -3
  26. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  27. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
  28. data/lib/rubocop/cop/commissioner.rb +15 -7
  29. data/lib/rubocop/cop/cop.rb +35 -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 +1 -7
  52. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +14 -12
  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} +6 -6
  58. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  59. data/lib/rubocop/cop/{metrics → layout}/line_length.rb +41 -114
  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 +32 -7
  68. data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
  69. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
  70. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +8 -5
  71. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +7 -0
  72. data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
  73. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -0
  74. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  75. data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
  76. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  77. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  78. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  79. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  80. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  81. data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -8
  82. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +10 -36
  83. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  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/non_deterministic_require_order.rb +89 -0
  87. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  88. data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +26 -26
  89. data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +10 -12
  90. data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +1 -1
  91. data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +6 -6
  92. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +1 -1
  93. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  94. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  95. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -6
  96. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  97. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
  98. data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
  99. data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
  100. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
  101. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  102. data/lib/rubocop/cop/lint/void.rb +7 -26
  103. data/lib/rubocop/cop/message_annotator.rb +16 -7
  104. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  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 +2 -2
  109. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  110. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  111. data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
  112. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  113. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  114. data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
  115. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -4
  116. data/lib/rubocop/cop/mixin/trailing_comma.rb +14 -9
  117. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  118. data/lib/rubocop/cop/naming/file_name.rb +12 -5
  119. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
  120. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  121. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +3 -3
  122. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  123. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  124. data/lib/rubocop/cop/offense.rb +29 -7
  125. data/lib/rubocop/cop/registry.rb +22 -1
  126. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  127. data/lib/rubocop/cop/style/alias.rb +1 -1
  128. data/lib/rubocop/cop/style/array_join.rb +1 -1
  129. data/lib/rubocop/cop/style/attr.rb +10 -2
  130. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  131. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +35 -16
  132. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  133. data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
  134. data/lib/rubocop/cop/style/commented_keyword.rb +8 -2
  135. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -6
  136. data/lib/rubocop/cop/style/copyright.rb +11 -7
  137. data/lib/rubocop/cop/style/documentation_method.rb +44 -0
  138. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +10 -4
  139. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  140. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  141. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  142. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  143. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  144. data/lib/rubocop/cop/style/expand_path_arguments.rb +1 -1
  145. data/lib/rubocop/cop/style/format_string.rb +10 -7
  146. data/lib/rubocop/cop/style/format_string_token.rb +19 -68
  147. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +28 -33
  148. data/lib/rubocop/cop/style/guard_clause.rb +3 -2
  149. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  150. data/lib/rubocop/cop/style/if_unless_modifier.rb +93 -15
  151. data/lib/rubocop/cop/style/infinite_loop.rb +6 -5
  152. data/lib/rubocop/cop/style/inverse_methods.rb +19 -13
  153. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  154. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
  155. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -25
  156. data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
  157. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  158. data/lib/rubocop/cop/style/mixin_usage.rb +11 -1
  159. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  160. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  161. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
  162. data/lib/rubocop/cop/style/nested_modifier.rb +22 -4
  163. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
  164. data/lib/rubocop/cop/style/next.rb +5 -5
  165. data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
  166. data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
  167. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  168. data/lib/rubocop/cop/style/or_assignment.rb +6 -1
  169. data/lib/rubocop/cop/style/parentheses_around_condition.rb +14 -0
  170. data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
  171. data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
  172. data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
  173. data/lib/rubocop/cop/style/redundant_parentheses.rb +16 -7
  174. data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
  175. data/lib/rubocop/cop/style/redundant_return.rb +39 -29
  176. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  177. data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +5 -5
  178. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  179. data/lib/rubocop/cop/style/safe_navigation.rb +23 -3
  180. data/lib/rubocop/cop/style/semicolon.rb +13 -2
  181. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  182. data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
  183. data/lib/rubocop/cop/style/ternary_parentheses.rb +19 -0
  184. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
  185. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  186. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  187. data/lib/rubocop/cop/team.rb +5 -0
  188. data/lib/rubocop/cop/util.rb +1 -1
  189. data/lib/rubocop/cop/utils/format_string.rb +120 -0
  190. data/lib/rubocop/cop/variable_force.rb +7 -5
  191. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  192. data/lib/rubocop/core_ext/string.rb +0 -24
  193. data/lib/rubocop/formatter/base_formatter.rb +2 -2
  194. data/lib/rubocop/formatter/clang_style_formatter.rb +9 -6
  195. data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
  196. data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
  197. data/lib/rubocop/formatter/formatter_set.rb +16 -15
  198. data/lib/rubocop/formatter/json_formatter.rb +6 -5
  199. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  200. data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
  201. data/lib/rubocop/formatter/tap_formatter.rb +18 -7
  202. data/lib/rubocop/magic_comment.rb +4 -0
  203. data/lib/rubocop/node_pattern.rb +4 -2
  204. data/lib/rubocop/options.rb +21 -26
  205. data/lib/rubocop/processed_source.rb +1 -1
  206. data/lib/rubocop/rake_task.rb +1 -0
  207. data/lib/rubocop/result_cache.rb +24 -8
  208. data/lib/rubocop/runner.rb +60 -33
  209. data/lib/rubocop/target_finder.rb +12 -6
  210. data/lib/rubocop/version.rb +1 -1
  211. metadata +48 -33
  212. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
  213. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -22
@@ -3,11 +3,16 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop is designed to help upgrade to after Ruby 3.0. It will add the
7
- # comment `# frozen_string_literal: true` to the top of files to
8
- # enable frozen string literals. Frozen string literals may be default
9
- # after Ruby 3.0. The comment will be added below a shebang and encoding
10
- # comment. The frozen string literal comment is only valid in Ruby 2.3+.
6
+ # This cop is designed to help you transition from mutable string literals
7
+ # to frozen string literals.
8
+ # It will add the comment `# frozen_string_literal: true` to the top of
9
+ # files to enable frozen string literals. Frozen string literals may be
10
+ # default in future Ruby. The comment will be added below a shebang and
11
+ # encoding comment. The frozen string literal comment is only valid in
12
+ # Ruby 2.3+.
13
+ #
14
+ # Note that the cop will ignore files where the comment exists but is set
15
+ # to `false` instead of `true`.
11
16
  #
12
17
  # @example EnforcedStyle: always (default)
13
18
  # # The `always` style will always add the frozen string literal comment
@@ -25,6 +30,13 @@ module RuboCop
25
30
  # # ...
26
31
  # end
27
32
  #
33
+ # # good
34
+ # # frozen_string_literal: false
35
+ #
36
+ # module Bar
37
+ # # ...
38
+ # end
39
+ #
28
40
  # @example EnforcedStyle: never
29
41
  # # The `never` will enforce that the frozen string literal comment does
30
42
  # # not exist in a file.
@@ -121,42 +133,25 @@ module RuboCop
121
133
  end
122
134
 
123
135
  def insert_comment(corrector)
124
- last_special_comment = last_special_comment(processed_source)
125
- if last_special_comment.nil?
126
- corrector.insert_before(correction_range, preceding_comment)
127
- else
128
- corrector.insert_after(correction_range, proceeding_comment)
129
- end
130
- end
136
+ comment = last_special_comment(processed_source)
131
137
 
132
- def preceding_comment
133
- if processed_source.tokens[0].space_before?
134
- "#{FROZEN_STRING_LITERAL_ENABLED}\n"
138
+ if comment
139
+ corrector.insert_after(line_range(comment.line), following_comment)
135
140
  else
136
- "#{FROZEN_STRING_LITERAL_ENABLED}\n\n"
141
+ corrector.insert_before(line_range(1), preceding_comment)
137
142
  end
138
143
  end
139
144
 
140
- def proceeding_comment
141
- last_special_comment = last_special_comment(processed_source)
142
- following_line = processed_source.following_line(last_special_comment)
143
-
144
- if following_line&.empty?
145
- "\n#{FROZEN_STRING_LITERAL_ENABLED}"
146
- else
147
- "\n#{FROZEN_STRING_LITERAL_ENABLED}\n"
148
- end
145
+ def line_range(line)
146
+ processed_source.buffer.line_range(line)
149
147
  end
150
148
 
151
- def correction_range
152
- last_special_comment = last_special_comment(processed_source)
149
+ def preceding_comment
150
+ "#{FROZEN_STRING_LITERAL_ENABLED}\n"
151
+ end
153
152
 
154
- if last_special_comment.nil?
155
- range_with_surrounding_space(range: processed_source.tokens[0],
156
- side: :left)
157
- else
158
- last_special_comment.pos
159
- end
153
+ def following_comment
154
+ "\n#{FROZEN_STRING_LITERAL_ENABLED}"
160
155
  end
161
156
  end
162
157
  end
@@ -49,8 +49,9 @@ module RuboCop
49
49
 
50
50
  if body.if_type?
51
51
  check_ending_if(body)
52
- elsif body.begin_type? && body.children.last.if_type?
53
- check_ending_if(body.children.last)
52
+ elsif body.begin_type?
53
+ final_expression = body.children.last
54
+ check_ending_if(final_expression) if final_expression&.if_type?
54
55
  end
55
56
  end
56
57
  alias on_defs on_def
@@ -168,10 +168,10 @@ module RuboCop
168
168
  end
169
169
 
170
170
  def autocorrect_ruby19(corrector, pair_node)
171
- key = pair_node.key
171
+ key = pair_node.key.source_range
172
172
  op = pair_node.loc.operator
173
173
 
174
- range = range_between(key.source_range.begin_pos, op.end_pos)
174
+ range = key.join(op)
175
175
  range = range_with_surrounding_space(range: range, side: :right)
176
176
 
177
177
  space = argument_without_space?(pair_node.parent) ? ' ' : ''
@@ -3,10 +3,13 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for if and unless statements that would fit on one line
7
- # if written as a modifier if/unless. The maximum line length is
8
- # configured in the `Metrics/LineLength` cop. The tab size is configured
9
- # in the `IndentationWidth` of the `Layout/Tab` cop.
6
+ # Checks for `if` and `unless` statements that would fit on one line if
7
+ # written as modifier `if`/`unless`. The cop also checks for modifier
8
+ # `if`/`unless` lines that exceed the maximum line length.
9
+ #
10
+ # The maximum line length is configured in the `Layout/LineLength`
11
+ # cop. The tab size is configured in the `IndentationWidth` of the
12
+ # `Layout/Tab` cop.
10
13
  #
11
14
  # @example
12
15
  # # bad
@@ -18,35 +21,101 @@ module RuboCop
18
21
  # Foo.do_something
19
22
  # end
20
23
  #
24
+ # do_something_in_a_method_with_a_long_name(arg) if long_condition
25
+ #
21
26
  # # good
22
27
  # do_stuff(bar) if condition
23
28
  # Foo.do_something unless qux.empty?
29
+ #
30
+ # if long_condition
31
+ # do_something_in_a_method_with_a_long_name(arg)
32
+ # end
24
33
  class IfUnlessModifier < Cop
25
34
  include StatementModifier
35
+ include LineLengthHelp
36
+ include IgnoredPattern
26
37
 
27
- MSG = 'Favor modifier `%<keyword>s` usage when having a single-line ' \
28
- 'body. Another good alternative is the usage of control flow ' \
29
- '`&&`/`||`.'
38
+ MSG_USE_MODIFIER = 'Favor modifier `%<keyword>s` usage when having a ' \
39
+ 'single-line body. Another good alternative is ' \
40
+ 'the usage of control flow `&&`/`||`.'
41
+ MSG_USE_NORMAL =
42
+ 'Modifier form of `%<keyword>s` makes the line too long.'
30
43
 
31
44
  ASSIGNMENT_TYPES = %i[lvasgn casgn cvasgn
32
45
  gvasgn ivasgn masgn].freeze
33
46
 
34
47
  def on_if(node)
35
- return unless eligible_node?(node)
36
- return if named_capture_in_condition?(node)
37
-
38
- add_offense(node, location: :keyword,
39
- message: format(MSG, keyword: node.keyword))
48
+ msg = if eligible_node?(node)
49
+ MSG_USE_MODIFIER unless named_capture_in_condition?(node)
50
+ elsif node.modifier_form? && too_long_single_line?(node)
51
+ MSG_USE_NORMAL
52
+ end
53
+ return unless msg
54
+
55
+ add_offense(node,
56
+ location: :keyword,
57
+ message: format(msg, keyword: node.keyword))
40
58
  end
41
59
 
42
60
  def autocorrect(node)
43
- lambda do |corrector|
44
- corrector.replace(node.source_range, to_modifier_form(node))
45
- end
61
+ replacement = if node.modifier_form?
62
+ to_normal_form(node)
63
+ else
64
+ to_modifier_form(node)
65
+ end
66
+ ->(corrector) { corrector.replace(node.source_range, replacement) }
46
67
  end
47
68
 
48
69
  private
49
70
 
71
+ def ignored_patterns
72
+ config.for_cop('Layout/LineLength')['IgnoredPatterns'] || []
73
+ end
74
+
75
+ def too_long_single_line?(node)
76
+ return false unless max_line_length
77
+
78
+ range = node.source_range
79
+ return false unless range.first_line == range.last_line
80
+ return false unless line_length_enabled_at_line?(range.first_line)
81
+
82
+ line = range.source_line
83
+ return false if line_length(line) <= max_line_length
84
+
85
+ too_long_line_based_on_config?(range, line)
86
+ end
87
+
88
+ def too_long_line_based_on_config?(range, line)
89
+ return false if matches_ignored_pattern?(line)
90
+
91
+ too_long = too_long_line_based_on_ignore_cop_directives?(range, line)
92
+ return too_long unless too_long == :undetermined
93
+
94
+ too_long_line_based_on_allow_uri?(line)
95
+ end
96
+
97
+ def too_long_line_based_on_ignore_cop_directives?(range, line)
98
+ if ignore_cop_directives? && directive_on_source_line?(range.line - 1)
99
+ return line_length_without_directive(line) > max_line_length
100
+ end
101
+
102
+ :undetermined
103
+ end
104
+
105
+ def too_long_line_based_on_allow_uri?(line)
106
+ if allow_uri?
107
+ uri_range = find_excessive_uri_range(line)
108
+ return false if uri_range && allowed_uri_position?(line, uri_range)
109
+ end
110
+
111
+ true
112
+ end
113
+
114
+ def line_length_enabled_at_line?(line)
115
+ processed_source.comment_config
116
+ .cop_enabled_at_line?('Layout/LineLength', line)
117
+ end
118
+
50
119
  def named_capture_in_condition?(node)
51
120
  node.condition.match_with_lvasgn_type?
52
121
  end
@@ -79,6 +148,15 @@ module RuboCop
79
148
  parenthesize?(node) ? "(#{expression})" : expression
80
149
  end
81
150
 
151
+ def to_normal_form(node)
152
+ indentation = ' ' * node.source_range.column
153
+ <<~RUBY.chomp
154
+ #{node.keyword} #{node.condition.source}
155
+ #{indentation} #{node.body.source}
156
+ #{indentation}end
157
+ RUBY
158
+ end
159
+
82
160
  def first_line_comment(node)
83
161
  comment =
84
162
  processed_source.find_comment { |c| c.loc.line == node.loc.line }
@@ -58,7 +58,7 @@ module RuboCop
58
58
  # `loop do` without further modification. The reason is that a
59
59
  # variable that's introduced inside a while/until loop is in scope
60
60
  # outside of that loop too, but a variable that's assigned for the
61
- # first time inside a block can not be accessed after the block. In
61
+ # first time inside a block cannot be accessed after the block. In
62
62
  # those more complicated cases we don't report an offense.
63
63
  return if @variables.any? do |var|
64
64
  assigned_inside_loop?(var, range) &&
@@ -97,12 +97,13 @@ module RuboCop
97
97
  end
98
98
 
99
99
  def modifier_replacement(node)
100
+ body = node.body
100
101
  if node.single_line?
101
- 'loop { ' + node.body.source + ' }'
102
+ 'loop { ' + body.source + ' }'
102
103
  else
103
- indentation = node.body.loc.expression.source_line[LEADING_SPACE]
104
+ indentation = body.source_range.source_line[LEADING_SPACE]
104
105
 
105
- ['loop do', node.body.source.gsub(/^/, configured_indent),
106
+ ['loop do', body.source.gsub(/^/, configured_indent),
106
107
  'end'].join("\n#{indentation}")
107
108
  end
108
109
  end
@@ -119,7 +120,7 @@ module RuboCop
119
120
  end
120
121
 
121
122
  def configured_indent
122
- ' ' * config.for_cop('IndentationWidth')['Width']
123
+ ' ' * config.for_cop('Layout/IndentationWidth')['Width']
123
124
  end
124
125
  end
125
126
  end
@@ -94,20 +94,25 @@ module RuboCop
94
94
  end
95
95
 
96
96
  def autocorrect(node)
97
+ if node.block_type?
98
+ correct_inverse_block(node)
99
+ elsif node.send_type?
100
+ correct_inverse_method(node)
101
+ end
102
+ end
103
+
104
+ def correct_inverse_method(node)
97
105
  method_call, _lhs, method, _rhs = inverse_candidate?(node)
106
+ return unless method_call && method
98
107
 
99
- if method_call && method
100
- lambda do |corrector|
101
- corrector.remove(not_to_receiver(node, method_call))
102
- corrector.replace(method_call.loc.selector,
103
- inverse_methods[method].to_s)
108
+ lambda do |corrector|
109
+ corrector.remove(not_to_receiver(node, method_call))
110
+ corrector.replace(method_call.loc.selector,
111
+ inverse_methods[method].to_s)
104
112
 
105
- if EQUALITY_METHODS.include?(method)
106
- corrector.remove(end_parentheses(node, method_call))
107
- end
113
+ if EQUALITY_METHODS.include?(method)
114
+ corrector.remove(end_parentheses(node, method_call))
108
115
  end
109
- else
110
- correct_inverse_block(node)
111
116
  end
112
117
  end
113
118
 
@@ -122,18 +127,19 @@ module RuboCop
122
127
  end
123
128
 
124
129
  def correct_inverse_selector(block, corrector)
125
- selector = block.loc.selector.source
130
+ selector_loc = block.loc.selector
131
+ selector = selector_loc.source
126
132
 
127
133
  if NEGATED_EQUALITY_METHODS.include?(selector.to_sym)
128
134
  selector[0] = '='
129
- corrector.replace(block.loc.selector, selector)
135
+ corrector.replace(selector_loc, selector)
130
136
  else
131
137
  if block.loc.dot
132
138
  range = dot_range(block.loc)
133
139
  corrector.remove(range)
134
140
  end
135
141
 
136
- corrector.remove(block.loc.selector)
142
+ corrector.remove(selector_loc)
137
143
  end
138
144
  end
139
145
 
@@ -28,7 +28,7 @@ module RuboCop
28
28
  contents = node.source[1...-1]
29
29
  return false if contents.empty?
30
30
 
31
- return false if whitelist.include?(contents.downcase)
31
+ return false if allowed_addresses.include?(contents.downcase)
32
32
 
33
33
  # To try to avoid doing two regex checks on every string,
34
34
  # shortcut out if the string does not look like an IP address
@@ -47,9 +47,9 @@ module RuboCop
47
47
 
48
48
  private
49
49
 
50
- def whitelist
51
- whitelist = cop_config['Whitelist']
52
- Array(whitelist).map(&:downcase)
50
+ def allowed_addresses
51
+ allowed_addresses = cop_config['AllowedAddresses']
52
+ Array(allowed_addresses).map(&:downcase)
53
53
  end
54
54
 
55
55
  def could_be_ip?(str)
@@ -26,13 +26,14 @@ module RuboCop
26
26
  'those strings.'
27
27
  CONCAT_TOKEN_TYPES = %i[tPLUS tLSHFT].freeze
28
28
  SIMPLE_STRING_TOKEN_TYPE = :tSTRING
29
- COMPLEX_STRING_EDGE_TOKEN_TYPES = %i[tSTRING_BEG tSTRING_END].freeze
29
+ COMPLEX_STRING_BEGIN_TOKEN = :tSTRING_BEG
30
+ COMPLEX_STRING_END_TOKEN = :tSTRING_END
30
31
  HIGH_PRECEDENCE_OP_TOKEN_TYPES = %i[tSTAR2 tPERCENT tDOT
31
32
  tLBRACK2].freeze
32
33
  QUOTE_DELIMITERS = %w[' "].freeze
33
34
 
34
35
  def self.autocorrect_incompatible_with
35
- [Style::UnneededInterpolation]
36
+ [Style::RedundantInterpolation]
36
37
  end
37
38
 
38
39
  def investigate(processed_source)
@@ -59,9 +60,7 @@ module RuboCop
59
60
  def check_token_set(index)
60
61
  predecessor, operator, successor = processed_source.tokens[index, 3]
61
62
 
62
- return unless eligible_successor?(successor) &&
63
- eligible_operator?(operator) &&
64
- eligible_predecessor?(predecessor)
63
+ return unless eligible_token_set?(predecessor, operator, successor)
65
64
 
66
65
  return if operator.line == successor.line
67
66
 
@@ -72,6 +71,12 @@ module RuboCop
72
71
  add_offense(operator.pos, location: operator.pos)
73
72
  end
74
73
 
74
+ def eligible_token_set?(predecessor, operator, successor)
75
+ eligible_successor?(successor) &&
76
+ eligible_operator?(operator) &&
77
+ eligible_predecessor?(predecessor)
78
+ end
79
+
75
80
  def eligible_successor?(successor)
76
81
  successor && standard_string_literal?(successor)
77
82
  end
@@ -91,13 +96,12 @@ module RuboCop
91
96
 
92
97
  def token_after_last_string(successor, base_index)
93
98
  index = base_index + 3
94
- begin_token, end_token = COMPLEX_STRING_EDGE_TOKEN_TYPES
95
- if successor.type == begin_token
99
+ if successor.type == COMPLEX_STRING_BEGIN_TOKEN
96
100
  ends_to_find = 1
97
101
  while ends_to_find.positive?
98
102
  case processed_source.tokens[index].type
99
- when begin_token then ends_to_find += 1
100
- when end_token then ends_to_find -= 1
103
+ when COMPLEX_STRING_BEGIN_TOKEN then ends_to_find += 1
104
+ when COMPLEX_STRING_END_TOKEN then ends_to_find -= 1
101
105
  end
102
106
  index += 1
103
107
  end
@@ -109,7 +113,7 @@ module RuboCop
109
113
  case token.type
110
114
  when SIMPLE_STRING_TOKEN_TYPE
111
115
  true
112
- when *COMPLEX_STRING_EDGE_TOKEN_TYPES
116
+ when COMPLEX_STRING_BEGIN_TOKEN, COMPLEX_STRING_END_TOKEN
113
117
  QUOTE_DELIMITERS.include?(token.text)
114
118
  else
115
119
  false
@@ -9,7 +9,7 @@ module RuboCop
9
9
  #
10
10
  # In the default style (require_parentheses), macro methods are ignored.
11
11
  # Additional methods can be added to the `IgnoredMethods`
12
- # or `IgnoredMethodPatterns` list. These options are
12
+ # or `IgnoredPatterns` list. These options are
13
13
  # valid only in the default style. Macros can be included by
14
14
  # either setting `IgnoreMacros` to false or adding specific macros to
15
15
  # the `IncludedMacros` list.
@@ -17,7 +17,7 @@ module RuboCop
17
17
  # Precedence of options is all follows:
18
18
  #
19
19
  # 1. `IgnoredMethods`
20
- # 2. `IgnoredMethodPatterns`
20
+ # 2. `IgnoredPatterns`
21
21
  # 3. `IncludedMacros`
22
22
  #
23
23
  # eg. If a method is listed in both
@@ -61,23 +61,9 @@ module RuboCop
61
61
  # # okay with `puts` listed in `IgnoredMethods`
62
62
  # puts 'test'
63
63
  #
64
- # # okay with `^assert` listed in `IgnoredMethodPatterns`
64
+ # # okay with `^assert` listed in `IgnoredPatterns`
65
65
  # assert_equal 'test', x
66
66
  #
67
- # # IgnoreMacros: true (default)
68
- #
69
- # # good
70
- # class Foo
71
- # bar :baz
72
- # end
73
- #
74
- # # IgnoreMacros: false
75
- #
76
- # # bad
77
- # class Foo
78
- # bar :baz
79
- # end
80
- #
81
67
  # @example EnforcedStyle: omit_parentheses
82
68
  #
83
69
  # # bad
@@ -92,7 +78,21 @@ module RuboCop
92
78
  # # good
93
79
  # foo.enforce strict: true
94
80
  #
95
- # # AllowParenthesesInMultilineCall: false (default)
81
+ # @example IgnoreMacros: true (default)
82
+ #
83
+ # # good
84
+ # class Foo
85
+ # bar :baz
86
+ # end
87
+ #
88
+ # @example IgnoreMacros: false
89
+ #
90
+ # # bad
91
+ # class Foo
92
+ # bar :baz
93
+ # end
94
+ #
95
+ # @example AllowParenthesesInMultilineCall: false (default)
96
96
  #
97
97
  # # bad
98
98
  # foo.enforce(
@@ -103,7 +103,7 @@ module RuboCop
103
103
  # foo.enforce \
104
104
  # strict: true
105
105
  #
106
- # # AllowParenthesesInMultilineCall: true
106
+ # @example AllowParenthesesInMultilineCall: true
107
107
  #
108
108
  # # good
109
109
  # foo.enforce(
@@ -114,7 +114,7 @@ module RuboCop
114
114
  # foo.enforce \
115
115
  # strict: true
116
116
  #
117
- # # AllowParenthesesInChaining: false (default)
117
+ # @example AllowParenthesesInChaining: false (default)
118
118
  #
119
119
  # # bad
120
120
  # foo().bar(1)
@@ -122,7 +122,7 @@ module RuboCop
122
122
  # # good
123
123
  # foo().bar 1
124
124
  #
125
- # # AllowParenthesesInChaining: true
125
+ # @example AllowParenthesesInChaining: true
126
126
  #
127
127
  # # good
128
128
  # foo().bar(1)
@@ -130,7 +130,7 @@ module RuboCop
130
130
  # # good
131
131
  # foo().bar 1
132
132
  #
133
- # # AllowParenthesesInCamelCaseMethod: false (default)
133
+ # @example AllowParenthesesInCamelCaseMethod: false (default)
134
134
  #
135
135
  # # bad
136
136
  # Array(1)
@@ -138,7 +138,7 @@ module RuboCop
138
138
  # # good
139
139
  # Array 1
140
140
  #
141
- # # AllowParenthesesInCamelCaseMethod: true
141
+ # @example AllowParenthesesInCamelCaseMethod: true
142
142
  #
143
143
  # # good
144
144
  # Array(1)
@@ -148,7 +148,7 @@ module RuboCop
148
148
  class MethodCallWithArgsParentheses < Cop
149
149
  include ConfigurableEnforcedStyle
150
150
  include IgnoredMethods
151
- include IgnoredMethodPatterns
151
+ include IgnoredPattern
152
152
 
153
153
  TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
154
154
 
@@ -186,7 +186,7 @@ module RuboCop
186
186
 
187
187
  def add_offense_for_require_parentheses(node)
188
188
  return if ignored_method?(node.method_name)
189
- return if ignored_method_pattern?(node.method_name)
189
+ return if matches_ignored_pattern?(node.method_name)
190
190
  return if eligible_for_parentheses_omission?(node)
191
191
  return unless node.arguments? && !node.parenthesized?
192
192