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
@@ -154,16 +154,17 @@ module RuboCop
154
154
 
155
155
  # :nodoc:
156
156
  def validate_range(range)
157
- return if range.source_buffer == @source_buffer
157
+ buffer = range.source_buffer
158
+ return if buffer == @source_buffer
158
159
 
159
- unless range.source_buffer.is_a?(Parser::Source::Buffer)
160
+ unless buffer.is_a?(Parser::Source::Buffer)
160
161
  # actually this should be enforced by parser gem
161
- raise 'Corrector expected range source buffer to be a '\
162
- "Parser::Source::Buffer, but got #{range.source_buffer.class}"
162
+ raise 'Corrector expected range source buffer to be a ' \
163
+ "Parser::Source::Buffer, but got #{buffer.class}"
163
164
  end
164
- raise "Correction target buffer #{range.source_buffer.object_id} "\
165
- "name:#{range.source_buffer.name.inspect}"\
166
- " is not current #{@source_buffer.object_id} "\
165
+ raise "Correction target buffer #{buffer.object_id} " \
166
+ "name:#{buffer.name.inspect}" \
167
+ " is not current #{@source_buffer.object_id} " \
167
168
  "name:#{@source_buffer.name.inspect} under investigation"
168
169
  end
169
170
  end
@@ -19,10 +19,12 @@ module RuboCop
19
19
  expr = node.respond_to?(:loc) ? node.loc.expression : node
20
20
  return if block_comment_within?(expr)
21
21
 
22
+ taboo_ranges = inside_string_ranges(node)
23
+
22
24
  lambda do |corrector|
23
25
  each_line(expr) do |line_begin_pos|
24
26
  autocorrect_line(corrector, line_begin_pos, expr, column_delta,
25
- heredoc_ranges(node))
27
+ taboo_ranges)
26
28
  end
27
29
  end
28
30
  end
@@ -39,27 +41,48 @@ module RuboCop
39
41
  private
40
42
 
41
43
  def autocorrect_line(corrector, line_begin_pos, expr, column_delta,
42
- heredoc_ranges)
44
+ taboo_ranges)
43
45
  range = calculate_range(expr, line_begin_pos, column_delta)
44
- # We must not change indentation of heredoc strings.
45
- return if heredoc_ranges.any? { |h| within?(range, h) }
46
+ # We must not change indentation of heredoc strings or inside other
47
+ # string literals
48
+ return if taboo_ranges.any? { |t| within?(range, t) }
46
49
 
47
50
  if column_delta.positive?
48
- unless range.source == "\n"
49
- # TODO: Fix ranges instead of using `begin`
50
- corrector.insert_before(range.begin, ' ' * column_delta)
51
+ unless range.resize(1).source == "\n"
52
+ corrector.insert_before(range, ' ' * column_delta)
51
53
  end
52
54
  elsif range.source =~ /\A[ \t]+\z/
53
55
  remove(range, corrector)
54
56
  end
55
57
  end
56
58
 
57
- def heredoc_ranges(node)
59
+ def inside_string_ranges(node)
58
60
  return [] unless node.is_a?(Parser::AST::Node)
59
61
 
60
- node.each_node(:dstr)
61
- .select(&:heredoc?)
62
- .map { |n| n.loc.heredoc_body.join(n.loc.heredoc_end) }
62
+ node.each_node(:str, :dstr, :xstr).map { |n| inside_string_range(n) }
63
+ .compact
64
+ end
65
+
66
+ def inside_string_range(node)
67
+ loc = node.location
68
+
69
+ if node.heredoc?
70
+ loc.heredoc_body.join(loc.heredoc_end)
71
+ elsif delimited_string_literal?(node)
72
+ loc.begin.end.join(loc.end.begin)
73
+ end
74
+ end
75
+
76
+ # Some special kinds of string literals are not composed of literal
77
+ # characters between two delimiters:
78
+ # - The source map of `?a` responds to :begin and :end but its end is
79
+ # nil.
80
+ # - The source map of `__FILE__` responds to neither :begin nor :end.
81
+ def delimited_string_literal?(node)
82
+ loc = node.location
83
+
84
+ loc.respond_to?(:begin) && loc.begin &&
85
+ loc.respond_to?(:end) && loc.end
63
86
  end
64
87
 
65
88
  def block_comment_within?(expr)
@@ -69,15 +92,18 @@ module RuboCop
69
92
  end
70
93
 
71
94
  def calculate_range(expr, line_begin_pos, column_delta)
95
+ if column_delta.positive?
96
+ return range_between(line_begin_pos, line_begin_pos)
97
+ end
98
+
72
99
  starts_with_space =
73
100
  expr.source_buffer.source[line_begin_pos].start_with?(' ')
74
- pos_to_remove = if column_delta.positive? || starts_with_space
75
- line_begin_pos
76
- else
77
- line_begin_pos - column_delta.abs
78
- end
79
101
 
80
- range_between(pos_to_remove, pos_to_remove + column_delta.abs)
102
+ if starts_with_space
103
+ range_between(line_begin_pos, line_begin_pos + column_delta.abs)
104
+ else
105
+ range_between(line_begin_pos - column_delta.abs, line_begin_pos)
106
+ end
81
107
  end
82
108
 
83
109
  def remove(range, corrector)
@@ -40,8 +40,8 @@ module RuboCop
40
40
  range_with_surrounding_space(range: node.loc.end, side: :left)
41
41
  )
42
42
 
43
- corrector.insert_after(
44
- last_element_range_with_trailing_comma(node),
43
+ corrector.insert_before(
44
+ last_element_range_with_trailing_comma(node).end,
45
45
  node.loc.end.source
46
46
  )
47
47
  end
@@ -98,7 +98,7 @@ module RuboCop
98
98
  end
99
99
 
100
100
  def fix_escaped_content(word_node, escape, delimiters)
101
- content = word_node.children.first.to_s
101
+ content = +word_node.children.first.to_s
102
102
  content = escape_string(content) if escape
103
103
  substitute_escaped_delimiters(content, delimiters)
104
104
  content
@@ -12,12 +12,11 @@ module RuboCop
12
12
  def empty_corrections(processed_source, corrector, empty_config,
13
13
  left_token, right_token)
14
14
  @processed_source = processed_source
15
+ range = range_between(left_token.end_pos, right_token.begin_pos)
15
16
  if offending_empty_space?(empty_config, left_token, right_token)
16
- range = side_space_range(range: left_token.pos, side: :right)
17
17
  corrector.remove(range)
18
18
  corrector.insert_after(left_token.pos, ' ')
19
19
  elsif offending_empty_no_space?(empty_config, left_token, right_token)
20
- range = side_space_range(range: left_token.pos, side: :right)
21
20
  corrector.remove(range)
22
21
  end
23
22
  end
@@ -10,10 +10,10 @@ module RuboCop
10
10
  # Note: RDoc 5.1.0 or lower has the following issue.
11
11
  # https://github.com/rubocop-hq/rubocop/issues/7043
12
12
  #
13
- # The following `String#strip_indent` can be replaced with
13
+ # The following `String#gsub` can be replaced with
14
14
  # squiggly heredoc when RuboCop supports Ruby 2.5 or higher
15
15
  # (RDoc 6.0 or higher).
16
- SOURCE_TEMPLATE = <<-RUBY.strip_indent
16
+ SOURCE_TEMPLATE = <<-RUBY.gsub(/^ {8}/, '')
17
17
  # frozen_string_literal: true
18
18
 
19
19
  # TODO: when finished, run `rake generate_cops_documentation` to update the docs
@@ -61,7 +61,7 @@ module RuboCop
61
61
  # See https://github.com/rubocop-hq/rubocop/blob/master/lib/rubocop/node_pattern.rb
62
62
  #
63
63
  # For example
64
- MSG = 'Use `#good_method` instead of `#bad_method`.'.freeze
64
+ MSG = 'Use `#good_method` instead of `#bad_method`.'
65
65
 
66
66
  def_node_matcher :bad_method?, <<~PATTERN
67
67
  (send nil? :bad_method ...)
@@ -12,7 +12,6 @@ module RuboCop
12
12
  Description: 'TODO: Write a description of the cop.'
13
13
  Enabled: true
14
14
  VersionAdded: '%<version_added>s'
15
-
16
15
  YAML
17
16
 
18
17
  def initialize(configuration_file_path:, badge:, version_added:)
@@ -23,8 +22,13 @@ module RuboCop
23
22
  end
24
23
 
25
24
  def inject
26
- configuration_entries.insert(find_target_line,
27
- new_configuration_entry)
25
+ target_line = find_target_line
26
+ if target_line
27
+ configuration_entries.insert(target_line,
28
+ new_configuration_entry + "\n")
29
+ else
30
+ configuration_entries.push("\n" + new_configuration_entry)
31
+ end
28
32
 
29
33
  File.write(configuration_file_path, configuration_entries.join)
30
34
 
@@ -49,7 +53,8 @@ module RuboCop
49
53
 
50
54
  return index if badge.to_s < line
51
55
  end
52
- configuration_entries.size - 1
56
+
57
+ nil
53
58
  end
54
59
 
55
60
  def cop_name_line?(yaml)
@@ -54,7 +54,7 @@ module RuboCop
54
54
  elsif in_the_same_department
55
55
  break index
56
56
  end
57
- end
57
+ end || require_entries.size
58
58
  end
59
59
  end
60
60
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'internal_affairs/method_name_equal'
3
4
  require_relative 'internal_affairs/node_destructuring'
4
5
  require_relative 'internal_affairs/node_type_predicate'
5
6
  require_relative 'internal_affairs/offense_location_keyword'
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks that method names are checked using `method?` method.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # node.method_name == :do_something
11
+ #
12
+ # # good
13
+ # node.method?(:do_something)
14
+ #
15
+ class MethodNameEqual < Cop
16
+ include RangeHelp
17
+
18
+ MSG = 'Use `method?(%<method_name>s)` instead of ' \
19
+ '`method_name == %<method_name>s`.'
20
+
21
+ def_node_matcher :method_name?, <<~PATTERN
22
+ (send
23
+ $(send
24
+ (...) :method_name) :==
25
+ $...)
26
+ PATTERN
27
+
28
+ def on_send(node)
29
+ method_name?(node) do |method_name_node, method_name_arg|
30
+ message = format(MSG, method_name: method_name_arg.first.source)
31
+
32
+ range = range(method_name_node, node)
33
+
34
+ add_offense(node, location: range, message: message)
35
+ end
36
+ end
37
+
38
+ def autocorrect(node)
39
+ lambda do |corrector|
40
+ method_name?(node) do |method_name_node, method_name_arg|
41
+ corrector.replace(
42
+ range(method_name_node, node),
43
+ "method?(#{method_name_arg.first.source})"
44
+ )
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def range(method_name_node, node)
52
+ range_between(
53
+ method_name_node.loc.selector.begin_pos, node.source_range.end_pos
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -37,7 +37,7 @@ module RuboCop
37
37
  #
38
38
  # foo :bar,
39
39
  # :baz
40
- class AlignArguments < Cop
40
+ class ArgumentAlignment < Cop
41
41
  include Alignment
42
42
 
43
43
  ALIGN_PARAMS_MSG = 'Align the arguments of a method call if ' \
@@ -20,7 +20,7 @@ module RuboCop
20
20
  # a = ['run',
21
21
  # 'forrest',
22
22
  # 'run']
23
- class AlignArray < Cop
23
+ class ArrayAlignment < Cop
24
24
  include Alignment
25
25
 
26
26
  MSG = 'Align the elements of an array literal if they span more ' \
@@ -21,7 +21,7 @@ module RuboCop
21
21
  #
22
22
  # The indentation of the remaining lines can be corrected with
23
23
  # other cops such as `IndentationConsistency` and `EndAlignment`.
24
- class IndentAssignment < Cop
24
+ class AssignmentIndentation < Cop
25
25
  include CheckAssignment
26
26
  include Alignment
27
27
 
@@ -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
@@ -44,8 +44,8 @@ module RuboCop
44
44
  #
45
45
  # foo.bar
46
46
  # .each do
47
- # baz
48
- # end
47
+ # baz
48
+ # end
49
49
  #
50
50
  # @example EnforcedStyleAlignWith: start_of_line
51
51
  # # bad
@@ -191,7 +191,7 @@ module RuboCop
191
191
  end
192
192
 
193
193
  def indentation_width
194
- @config.for_cop('IndentationWidth')['Width'] || 2
194
+ @config.for_cop('Layout/IndentationWidth')['Width'] || 2
195
195
  end
196
196
 
197
197
  def line_break_after_left_paren?(left_paren, elements)
@@ -55,23 +55,20 @@ module RuboCop
55
55
  # of correcting, saving the file, parsing and inspecting again, and
56
56
  # then correcting one more line, and so on.
57
57
  def autocorrect_preceding_comments(comment)
58
- corrections = []
59
- line_no = comment.loc.line
60
- column = comment.loc.column
61
58
  comments = processed_source.comments
62
- (comments.index(comment) - 1).downto(0) do |ix|
63
- previous_comment = comments[ix]
64
- break unless should_correct?(previous_comment, column, line_no - 1)
59
+ index = comments.index(comment)
65
60
 
66
- corrections << autocorrect_one(previous_comment)
67
- line_no -= 1
68
- end
69
- corrections
61
+ comments[0..index]
62
+ .reverse_each
63
+ .each_cons(2)
64
+ .take_while { |below, above| should_correct?(above, below) }
65
+ .map { |_, above| autocorrect_one(above) }
70
66
  end
71
67
 
72
- def should_correct?(comment, column, line_no)
73
- loc = comment.loc
74
- loc.line == line_no && loc.column == column
68
+ def should_correct?(preceding_comment, reference_comment)
69
+ loc = preceding_comment.loc
70
+ ref_loc = reference_comment.loc
71
+ loc.line == ref_loc.line - 1 && loc.column == ref_loc.column
75
72
  end
76
73
 
77
74
  def autocorrect_one(comment)
@@ -103,19 +103,12 @@ module RuboCop
103
103
  private
104
104
 
105
105
  def concat_consecutive_comments(comments)
106
- prev_line = nil
106
+ consecutive_comments =
107
+ comments.chunk_while { |i, j| i.loc.line.succ == j.loc.line }
107
108
 
108
- comments.each_with_object([]) do |comment, concatenated_comments|
109
- if prev_line && comment.loc.line == prev_line.next
110
- last_concatenated_comment = concatenated_comments.last
111
-
112
- last_concatenated_comment[0] << comment_text(comment)
113
- last_concatenated_comment[1] << comment
114
- else
115
- concatenated_comments << [comment_text(comment).dup, [comment]]
116
- end
117
-
118
- prev_line = comment.loc.line
109
+ consecutive_comments.map do |chunk|
110
+ joined_text = chunk.map { |c| comment_text(c) }.join
111
+ [joined_text, chunk]
119
112
  end
120
113
  end
121
114
 
@@ -141,11 +134,9 @@ module RuboCop
141
134
  cop_config['AllowMarginComment']
142
135
  end
143
136
 
144
- def current_token(node)
137
+ def current_token(comment)
145
138
  processed_source.find_token do |token|
146
- token.pos.column == node.loc.column &&
147
- token.pos.last_column == node.loc.last_column &&
148
- token.line == node.loc.line
139
+ token.pos == comment.loc.expression
149
140
  end
150
141
  end
151
142
 
@@ -45,7 +45,7 @@ module RuboCop
45
45
  return if correct_style?(node)
46
46
 
47
47
  if node.modifier_form? && last_argument_is_heredoc?(node)
48
- heredoc_node = last_argument(node)
48
+ heredoc_node = last_heredoc_argument(node)
49
49
 
50
50
  return if next_line_empty?(heredoc_line(node, heredoc_node))
51
51
 
@@ -109,16 +109,27 @@ module RuboCop
109
109
 
110
110
  def last_argument_is_heredoc?(node)
111
111
  last_children = node.if_branch
112
-
113
112
  return false unless last_children&.send_type?
114
113
 
115
- last_argument = last_argument(node)
116
-
117
- last_argument.respond_to?(:heredoc?) && last_argument.heredoc?
114
+ heredoc?(last_heredoc_argument(node))
118
115
  end
119
116
 
120
- def last_argument(node)
121
- node.if_branch.children.last
117
+ def last_heredoc_argument(node)
118
+ n = if node.respond_to?(:if_branch)
119
+ node.if_branch.children.last
120
+ else
121
+ node
122
+ end
123
+
124
+ return n if heredoc?(n)
125
+ return unless n.respond_to?(:arguments)
126
+
127
+ n.arguments.each do |argument|
128
+ node = last_heredoc_argument(argument)
129
+ return node if node
130
+ end
131
+
132
+ return last_heredoc_argument(n.receiver) if n.respond_to?(:receiver)
122
133
  end
123
134
 
124
135
  def heredoc_line(node, heredoc_node)
@@ -129,6 +140,10 @@ module RuboCop
129
140
  node.last_line + num_of_heredoc_lines + END_OF_HEREDOC_LINE
130
141
  end
131
142
 
143
+ def heredoc?(node)
144
+ node.respond_to?(:heredoc?) && node.heredoc?
145
+ end
146
+
132
147
  def offense_location(node)
133
148
  if node.loc.respond_to?(:end) && node.loc.end
134
149
  :end