rubocop 0.89.1 → 0.90.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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +79 -11
  4. data/lib/rubocop.rb +13 -0
  5. data/lib/rubocop/cached_data.rb +1 -0
  6. data/lib/rubocop/cli/command.rb +1 -0
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -0
  8. data/lib/rubocop/cli/command/base.rb +1 -0
  9. data/lib/rubocop/cli/command/execute_runner.rb +1 -0
  10. data/lib/rubocop/cli/command/init_dotfile.rb +1 -0
  11. data/lib/rubocop/cli/command/show_cops.rb +1 -0
  12. data/lib/rubocop/cli/command/version.rb +1 -0
  13. data/lib/rubocop/cli/environment.rb +1 -0
  14. data/lib/rubocop/comment_config.rb +5 -0
  15. data/lib/rubocop/config_loader.rb +17 -6
  16. data/lib/rubocop/config_loader_resolver.rb +1 -0
  17. data/lib/rubocop/config_obsoletion.rb +1 -0
  18. data/lib/rubocop/config_validator.rb +3 -0
  19. data/lib/rubocop/cop/base.rb +23 -0
  20. data/lib/rubocop/cop/bundler/gem_comment.rb +7 -3
  21. data/lib/rubocop/cop/commissioner.rb +47 -7
  22. data/lib/rubocop/cop/correctors/alignment_corrector.rb +4 -4
  23. data/lib/rubocop/cop/correctors/condition_corrector.rb +3 -5
  24. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +9 -10
  25. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
  26. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +8 -3
  27. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -8
  28. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +4 -9
  29. data/lib/rubocop/cop/correctors/punctuation_corrector.rb +8 -10
  30. data/lib/rubocop/cop/documentation.rb +22 -0
  31. data/lib/rubocop/cop/generator.rb +1 -0
  32. data/lib/rubocop/cop/layout/block_alignment.rb +23 -19
  33. data/lib/rubocop/cop/layout/class_structure.rb +10 -9
  34. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +4 -6
  35. data/lib/rubocop/cop/layout/condition_position.rb +13 -15
  36. data/lib/rubocop/cop/layout/def_end_alignment.rb +7 -4
  37. data/lib/rubocop/cop/layout/dot_position.rb +21 -17
  38. data/lib/rubocop/cop/layout/empty_comment.rb +30 -23
  39. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +19 -16
  40. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +13 -13
  41. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +144 -0
  42. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +21 -23
  43. data/lib/rubocop/cop/layout/empty_lines.rb +6 -7
  44. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +4 -6
  45. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +7 -8
  46. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +3 -6
  47. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +2 -5
  48. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -5
  49. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -5
  50. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -5
  51. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +2 -5
  52. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +2 -5
  53. data/lib/rubocop/cop/layout/end_alignment.rb +6 -7
  54. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +2 -5
  55. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +2 -5
  56. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +4 -8
  57. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +2 -5
  58. data/lib/rubocop/cop/layout/hash_alignment.rb +17 -20
  59. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +15 -14
  60. data/lib/rubocop/cop/layout/heredoc_indentation.rb +14 -11
  61. data/lib/rubocop/cop/layout/initial_indentation.rb +6 -7
  62. data/lib/rubocop/cop/layout/leading_comment_space.rb +11 -9
  63. data/lib/rubocop/cop/layout/leading_empty_lines.rb +6 -11
  64. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +2 -5
  65. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +2 -5
  66. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +10 -14
  67. data/lib/rubocop/cop/layout/multiline_block_layout.rb +21 -19
  68. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +2 -5
  69. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +2 -5
  70. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +5 -9
  71. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -5
  72. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +2 -5
  73. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +18 -21
  74. data/lib/rubocop/cop/layout/space_after_colon.rb +11 -7
  75. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -5
  76. data/lib/rubocop/cop/layout/space_after_method_name.rb +5 -6
  77. data/lib/rubocop/cop/layout/space_after_not.rb +9 -11
  78. data/lib/rubocop/cop/layout/space_after_semicolon.rb +2 -5
  79. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +20 -15
  80. data/lib/rubocop/cop/layout/space_around_keyword.rb +17 -18
  81. data/lib/rubocop/cop/layout/space_around_operators.rb +17 -16
  82. data/lib/rubocop/cop/layout/space_before_block_braces.rb +23 -22
  83. data/lib/rubocop/cop/layout/space_before_comma.rb +3 -5
  84. data/lib/rubocop/cop/layout/space_before_comment.rb +10 -7
  85. data/lib/rubocop/cop/layout/space_before_first_arg.rb +7 -7
  86. data/lib/rubocop/cop/layout/space_before_semicolon.rb +2 -5
  87. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -17
  88. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +13 -16
  89. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +3 -8
  90. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +17 -16
  91. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +16 -19
  92. data/lib/rubocop/cop/layout/space_inside_parens.rb +9 -14
  93. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +5 -10
  94. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +8 -17
  95. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +13 -16
  96. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +10 -11
  97. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +10 -15
  98. data/lib/rubocop/cop/layout/trailing_whitespace.rb +11 -11
  99. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
  100. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  101. data/lib/rubocop/cop/lint/duplicate_require.rb +41 -0
  102. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +0 -11
  103. data/lib/rubocop/cop/lint/empty_file.rb +53 -0
  104. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  105. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +2 -35
  106. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +9 -19
  107. data/lib/rubocop/cop/lint/percent_string_array.rb +8 -12
  108. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -4
  109. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  110. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +57 -0
  111. data/lib/rubocop/cop/lint/useless_method_definition.rb +77 -0
  112. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +2 -0
  113. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -0
  114. data/lib/rubocop/cop/mixin/alignment.rb +3 -0
  115. data/lib/rubocop/cop/mixin/allowed_methods.rb +2 -0
  116. data/lib/rubocop/cop/mixin/annotation_comment.rb +5 -0
  117. data/lib/rubocop/cop/mixin/check_line_breakable.rb +16 -7
  118. data/lib/rubocop/cop/mixin/comments_help.rb +54 -0
  119. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +8 -7
  120. data/lib/rubocop/cop/mixin/empty_parameter.rb +3 -1
  121. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +3 -1
  122. data/lib/rubocop/cop/mixin/first_element_line_break.rb +3 -1
  123. data/lib/rubocop/cop/mixin/hash_transform_method.rb +17 -0
  124. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +3 -1
  125. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +12 -10
  126. data/lib/rubocop/cop/mixin/negative_conditional.rb +2 -2
  127. data/lib/rubocop/cop/mixin/percent_array.rb +14 -3
  128. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +1 -1
  129. data/lib/rubocop/cop/mixin/rescue_node.rb +10 -1
  130. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +4 -3
  131. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +4 -3
  132. data/lib/rubocop/cop/mixin/surrounding_space.rb +8 -4
  133. data/lib/rubocop/cop/mixin/trailing_comma.rb +7 -7
  134. data/lib/rubocop/cop/offense.rb +1 -0
  135. data/lib/rubocop/cop/severity.rb +0 -8
  136. data/lib/rubocop/cop/style/case_equality.rb +8 -3
  137. data/lib/rubocop/cop/style/case_like_if.rb +20 -4
  138. data/lib/rubocop/cop/style/class_methods_definitions.rb +131 -0
  139. data/lib/rubocop/cop/style/combinable_loops.rb +89 -0
  140. data/lib/rubocop/cop/style/empty_block_parameter.rb +9 -10
  141. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +9 -10
  142. data/lib/rubocop/cop/style/guard_clause.rb +1 -0
  143. data/lib/rubocop/cop/style/hash_syntax.rb +6 -5
  144. data/lib/rubocop/cop/style/hash_transform_keys.rb +14 -1
  145. data/lib/rubocop/cop/style/hash_transform_values.rb +14 -1
  146. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
  147. data/lib/rubocop/cop/style/keyword_parameters_order.rb +58 -0
  148. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +10 -1
  149. data/lib/rubocop/cop/style/multiline_when_then.rb +2 -2
  150. data/lib/rubocop/cop/style/negated_if.rb +6 -6
  151. data/lib/rubocop/cop/style/negated_unless.rb +6 -6
  152. data/lib/rubocop/cop/style/negated_while.rb +7 -15
  153. data/lib/rubocop/cop/style/nested_modifier.rb +10 -13
  154. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +11 -11
  155. data/lib/rubocop/cop/style/nested_ternary_operator.rb +14 -16
  156. data/lib/rubocop/cop/style/next.rb +10 -14
  157. data/lib/rubocop/cop/style/nil_comparison.rb +11 -11
  158. data/lib/rubocop/cop/style/non_nil_check.rb +32 -26
  159. data/lib/rubocop/cop/style/not.rb +19 -26
  160. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +4 -9
  161. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -11
  162. data/lib/rubocop/cop/style/one_line_conditional.rb +71 -23
  163. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  164. data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
  165. data/lib/rubocop/cop/style/or_assignment.rb +13 -10
  166. data/lib/rubocop/cop/style/parallel_assignment.rb +14 -14
  167. data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -6
  168. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +13 -19
  169. data/lib/rubocop/cop/style/percent_q_literals.rb +8 -10
  170. data/lib/rubocop/cop/style/perl_backrefs.rb +8 -10
  171. data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -14
  172. data/lib/rubocop/cop/style/proc.rb +6 -6
  173. data/lib/rubocop/cop/style/raise_args.rb +13 -24
  174. data/lib/rubocop/cop/style/random_with_offset.rb +15 -16
  175. data/lib/rubocop/cop/style/redundant_assignment.rb +8 -10
  176. data/lib/rubocop/cop/style/redundant_begin.rb +7 -9
  177. data/lib/rubocop/cop/style/redundant_capital_w.rb +6 -9
  178. data/lib/rubocop/cop/style/redundant_condition.rb +5 -6
  179. data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -12
  180. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +8 -8
  181. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -6
  182. data/lib/rubocop/cop/style/redundant_interpolation.rb +25 -24
  183. data/lib/rubocop/cop/style/redundant_parentheses.rb +7 -9
  184. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -13
  185. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +5 -14
  186. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  187. data/lib/rubocop/cop/style/redundant_self_assignment.rb +116 -0
  188. data/lib/rubocop/cop/style/regexp_literal.rb +10 -21
  189. data/lib/rubocop/cop/style/rescue_modifier.rb +29 -9
  190. data/lib/rubocop/cop/style/return_nil.rb +5 -5
  191. data/lib/rubocop/cop/style/safe_navigation.rb +13 -12
  192. data/lib/rubocop/cop/style/sample.rb +10 -13
  193. data/lib/rubocop/cop/style/self_assignment.rb +26 -22
  194. data/lib/rubocop/cop/style/semicolon.rb +6 -9
  195. data/lib/rubocop/cop/style/send.rb +2 -2
  196. data/lib/rubocop/cop/style/signal_exception.rb +21 -19
  197. data/lib/rubocop/cop/style/single_line_block_params.rb +4 -2
  198. data/lib/rubocop/cop/style/single_line_methods.rb +17 -16
  199. data/lib/rubocop/cop/style/slicing_with_range.rb +4 -7
  200. data/lib/rubocop/cop/style/sole_nested_conditional.rb +66 -0
  201. data/lib/rubocop/cop/style/special_global_vars.rb +10 -15
  202. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +17 -21
  203. data/lib/rubocop/cop/style/stderr_puts.rb +4 -6
  204. data/lib/rubocop/cop/style/string_hash_keys.rb +6 -7
  205. data/lib/rubocop/cop/style/string_methods.rb +7 -17
  206. data/lib/rubocop/cop/style/strip.rb +8 -14
  207. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -6
  208. data/lib/rubocop/cop/style/symbol_array.rb +5 -16
  209. data/lib/rubocop/cop/style/symbol_literal.rb +4 -6
  210. data/lib/rubocop/cop/style/symbol_proc.rb +14 -18
  211. data/lib/rubocop/cop/style/ternary_parentheses.rb +21 -20
  212. data/lib/rubocop/cop/style/trailing_body_on_class.rb +3 -6
  213. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +4 -7
  214. data/lib/rubocop/cop/style/trailing_body_on_module.rb +3 -6
  215. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
  216. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +2 -5
  217. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +7 -6
  218. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +2 -5
  219. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +8 -17
  220. data/lib/rubocop/cop/style/trivial_accessors.rb +26 -30
  221. data/lib/rubocop/cop/style/unless_else.rb +5 -8
  222. data/lib/rubocop/cop/style/unpack_first.rb +4 -8
  223. data/lib/rubocop/cop/style/variable_interpolation.rb +7 -10
  224. data/lib/rubocop/cop/style/when_then.rb +4 -6
  225. data/lib/rubocop/cop/style/while_until_do.rb +6 -16
  226. data/lib/rubocop/cop/style/while_until_modifier.rb +6 -20
  227. data/lib/rubocop/cop/style/word_array.rb +5 -23
  228. data/lib/rubocop/cop/style/yoda_condition.rb +4 -15
  229. data/lib/rubocop/cop/style/zero_length_predicate.rb +11 -13
  230. data/lib/rubocop/cop/team.rb +1 -0
  231. data/lib/rubocop/cop/util.rb +1 -1
  232. data/lib/rubocop/cop/utils/format_string.rb +3 -5
  233. data/lib/rubocop/cop/variable_force.rb +2 -0
  234. data/lib/rubocop/cops_documentation_generator.rb +4 -2
  235. data/lib/rubocop/core_ext/string.rb +1 -1
  236. data/lib/rubocop/ext/regexp_node.rb +46 -0
  237. data/lib/rubocop/file_finder.rb +1 -0
  238. data/lib/rubocop/formatter/auto_gen_config_formatter.rb +2 -1
  239. data/lib/rubocop/formatter/html_formatter.rb +2 -0
  240. data/lib/rubocop/formatter/progress_formatter.rb +2 -1
  241. data/lib/rubocop/formatter/quiet_formatter.rb +1 -1
  242. data/lib/rubocop/formatter/simple_text_formatter.rb +36 -6
  243. data/lib/rubocop/name_similarity.rb +1 -0
  244. data/lib/rubocop/options.rb +3 -0
  245. data/lib/rubocop/remote_config.rb +1 -0
  246. data/lib/rubocop/result_cache.rb +1 -0
  247. data/lib/rubocop/rspec/cop_helper.rb +4 -1
  248. data/lib/rubocop/rspec/expect_offense.rb +10 -5
  249. data/lib/rubocop/rspec/shared_contexts.rb +12 -0
  250. data/lib/rubocop/runner.rb +1 -0
  251. data/lib/rubocop/string_interpreter.rb +3 -0
  252. data/lib/rubocop/target_finder.rb +1 -0
  253. data/lib/rubocop/target_ruby.rb +6 -0
  254. data/lib/rubocop/version.rb +2 -1
  255. data/lib/rubocop/yaml_duplication_checker.rb +1 -0
  256. metadata +15 -2
@@ -64,25 +64,15 @@ module RuboCop
64
64
 
65
65
  private
66
66
 
67
- def check_regexp(regexp)
68
- return if contain_non_literal?(regexp)
69
-
70
- tree = Regexp::Parser.parse(regexp.content)
71
- @valid_ref = regexp_captures(tree)
72
- end
73
-
74
- def contain_non_literal?(node)
75
- node.children.size != 2 || !node.children.first.str_type?
76
- end
77
-
78
- def regexp_captures(tree)
79
- named_capture = numbered_capture = 0
80
- tree.each_expression do |e|
81
- if e.type?(:group)
82
- e.respond_to?(:name) ? named_capture += 1 : numbered_capture += 1
83
- end
84
- end
85
- named_capture.positive? ? named_capture : numbered_capture
67
+ def check_regexp(node)
68
+ return if node.interpolation?
69
+
70
+ named_capture = node.each_capture(named: true).count
71
+ @valid_ref = if named_capture.positive?
72
+ named_capture
73
+ else
74
+ node.each_capture(named: false).count
75
+ end
86
76
  end
87
77
  end
88
78
  end
@@ -39,23 +39,19 @@ module RuboCop
39
39
  return unless contains_quotes_or_commas?(node)
40
40
 
41
41
  add_offense(node) do |corrector|
42
- autocorrect(corrector, node)
43
- end
44
- end
45
-
46
- private
42
+ node.each_value do |value|
43
+ range = value.loc.expression
47
44
 
48
- def autocorrect(corrector, node)
49
- node.each_value do |value|
50
- range = value.loc.expression
45
+ match = range.source.match(TRAILING_QUOTE)
46
+ corrector.remove_trailing(range, match[0].length) if match
51
47
 
52
- match = range.source.match(TRAILING_QUOTE)
53
- corrector.remove_trailing(range, match[0].length) if match
54
-
55
- corrector.remove_leading(range, 1) if LEADING_QUOTE.match?(range.source)
48
+ corrector.remove_leading(range, 1) if LEADING_QUOTE.match?(range.source)
49
+ end
56
50
  end
57
51
  end
58
52
 
53
+ private
54
+
59
55
  def contains_quotes_or_commas?(node)
60
56
  node.values.any? do |value|
61
57
  literal = value.children.first.to_s.scrub
@@ -3,10 +3,10 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # This cop looks for use of the same name as outer local variables
7
- # for block arguments or block local variables.
8
- # This is a mimic of the warning
9
- # "shadowing outer local variable - foo" from `ruby -cw`.
6
+ # This cop checks for the use of local variable names from an outer scope
7
+ # in block arguments or block-local variables. This mirrors the warning
8
+ # given by `ruby -cw` prior to Ruby 2.6:
9
+ # "shadowing outer local variable - foo".
10
10
  #
11
11
  # @example
12
12
  #
@@ -11,7 +11,7 @@ module RuboCop
11
11
  #
12
12
  # # Detected since Ruby 2.7
13
13
  # return 1 # 1 is always ignored.
14
- class TopLevelReturnWithArgument < Cop
14
+ class TopLevelReturnWithArgument < Base
15
15
  # This cop works by validating the ancestors of the return node. A
16
16
  # top-level return node's ancestors should not be of block, def, or
17
17
  # defs type.
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for trailing commas in attribute declarations, such as
7
+ # `#attr_reader`. Leaving a trailing comma will nullify the next method
8
+ # definition by overriding it with a getter method.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # class Foo
14
+ # attr_reader :foo,
15
+ #
16
+ # def bar
17
+ # puts "Unreachable."
18
+ # end
19
+ # end
20
+ #
21
+ # # good
22
+ # class Foo
23
+ # attr_reader :foo
24
+ #
25
+ # def bar
26
+ # puts "No problem!"
27
+ # end
28
+ # end
29
+ #
30
+ class TrailingCommaInAttributeDeclaration < Base
31
+ extend AutoCorrector
32
+ include RangeHelp
33
+
34
+ MSG = 'Avoid leaving a trailing comma in attribute declarations.'
35
+
36
+ def on_send(node)
37
+ return unless node.attribute_accessor? && node.arguments.last.def_type?
38
+
39
+ trailing_comma = trailing_comma_range(node)
40
+
41
+ add_offense(trailing_comma) do |corrector|
42
+ corrector.remove(trailing_comma)
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def trailing_comma_range(node)
49
+ range_with_surrounding_space(
50
+ range: node.arguments[-2].source_range,
51
+ side: :right
52
+ ).end.resize(1)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for useless method definitions, specifically: empty constructors
7
+ # and methods just delegating to `super`.
8
+ #
9
+ # This cop is marked as unsafe as it can trigger false positives for cases when
10
+ # an empty constructor just overrides the parent constructor, which is bad anyway.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # def initialize
15
+ # end
16
+ #
17
+ # def method
18
+ # super
19
+ # end
20
+ #
21
+ # # good
22
+ # def initialize
23
+ # initialize_internals
24
+ # end
25
+ #
26
+ # def method
27
+ # super
28
+ # do_something_else
29
+ # end
30
+ #
31
+ # @example AllowComments: true (default)
32
+ # # good
33
+ # def initialize
34
+ # # Comment.
35
+ # end
36
+ #
37
+ # @example AllowComments: false
38
+ # # bad
39
+ # def initialize
40
+ # # Comment.
41
+ # end
42
+ #
43
+ class UselessMethodDefinition < Base
44
+ extend AutoCorrector
45
+
46
+ MSG = 'Useless method definition detected.'
47
+
48
+ def on_def(node)
49
+ return unless (constructor?(node) && empty_constructor?(node)) ||
50
+ delegating?(node.body, node)
51
+
52
+ add_offense(node) { |corrector| corrector.remove(node) }
53
+ end
54
+ alias on_defs on_def
55
+
56
+ private
57
+
58
+ def empty_constructor?(node)
59
+ return false if node.body
60
+ return false if cop_config['AllowComments'] && comment_lines?(node)
61
+
62
+ true
63
+ end
64
+
65
+ def constructor?(node)
66
+ node.def_type? && node.method?(:initialize)
67
+ end
68
+
69
+ def delegating?(node, def_node)
70
+ return false unless node&.super_type? || node&.zsuper_type?
71
+
72
+ !node.arguments? || node.arguments.map(&:source) == def_node.arguments.map(&:source)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -31,6 +31,8 @@ module RuboCop
31
31
  # TODO: move to rubocop-ast
32
32
  ARGUMENT_TYPES = %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg].freeze
33
33
 
34
+ private_constant :BRANCH_NODES, :CONDITION_NODES, :ARGUMENT_TYPES
35
+
34
36
  def initialize(node)
35
37
  @assignment = 0
36
38
  @branch = 0
@@ -11,6 +11,7 @@ module RuboCop
11
11
 
12
12
  FOLDABLE_TYPES = %i[array hash heredoc].freeze
13
13
  CLASSLIKE_TYPES = %i[class module].freeze
14
+ private_constant :FOLDABLE_TYPES, :CLASSLIKE_TYPES
14
15
 
15
16
  def initialize(node, processed_source, count_comments: false, foldable_types: [])
16
17
  @node = node
@@ -42,6 +42,7 @@ module RuboCop
42
42
  end
43
43
  end
44
44
 
45
+ # @api private
45
46
  def each_bad_alignment(items, base_column)
46
47
  prev_line = -1
47
48
  items.each do |current|
@@ -55,11 +56,13 @@ module RuboCop
55
56
  end
56
57
  end
57
58
 
59
+ # @api public
58
60
  def display_column(range)
59
61
  line = processed_source.lines[range.line - 1]
60
62
  Unicode::DisplayWidth.of(line[0, range.column])
61
63
  end
62
64
 
65
+ # @api public
63
66
  def within?(inner, outer)
64
67
  inner.begin_pos >= outer.begin_pos && inner.end_pos <= outer.end_pos
65
68
  end
@@ -7,10 +7,12 @@ module RuboCop
7
7
  module AllowedMethods
8
8
  private
9
9
 
10
+ # @api public
10
11
  def allowed_method?(name)
11
12
  allowed_methods.include?(name.to_s)
12
13
  end
13
14
 
15
+ # @api public
14
16
  def allowed_methods
15
17
  cop_config.fetch('AllowedMethods', [])
16
18
  end
@@ -7,12 +7,14 @@ module RuboCop
7
7
  module AnnotationComment
8
8
  private
9
9
 
10
+ # @api public
10
11
  def annotation?(comment)
11
12
  _margin, first_word, colon, space, note = split_comment(comment)
12
13
  keyword_appearance?(first_word, colon, space) &&
13
14
  !just_first_word_of_sentence?(first_word, colon, space, note)
14
15
  end
15
16
 
17
+ # @api public
16
18
  def split_comment(comment)
17
19
  match = comment.text.match(/^(# ?)([A-Za-z]+)(\s*:)?(\s+)?(\S+)?/)
18
20
  return false unless match
@@ -20,14 +22,17 @@ module RuboCop
20
22
  match.captures
21
23
  end
22
24
 
25
+ # @api public
23
26
  def keyword_appearance?(first_word, colon, space)
24
27
  first_word && keyword?(first_word.upcase) && (colon || space)
25
28
  end
26
29
 
30
+ # @api private
27
31
  def just_first_word_of_sentence?(first_word, colon, space, note)
28
32
  first_word == first_word.capitalize && !colon && space && note
29
33
  end
30
34
 
35
+ # @api public
31
36
  def keyword?(word)
32
37
  config.for_cop('Style/CommentAnnotation')['Keywords'].include?(word)
33
38
  end
@@ -54,6 +54,7 @@ module RuboCop
54
54
 
55
55
  private
56
56
 
57
+ # @api private
57
58
  def extract_breakable_node_from_elements(node, elements, max)
58
59
  return unless breakable_collection?(node, elements)
59
60
  return if safe_to_ignore?(node)
@@ -65,6 +66,7 @@ module RuboCop
65
66
  extract_first_element_over_column_limit(node, elements, max)
66
67
  end
67
68
 
69
+ # @api private
68
70
  def extract_first_element_over_column_limit(node, elements, max)
69
71
  line = node.first_line
70
72
  i = 0
@@ -74,10 +76,12 @@ module RuboCop
74
76
  elements[i - 1]
75
77
  end
76
78
 
79
+ # @api private
77
80
  def within_column_limit?(element, max, line)
78
81
  element && element.loc.column < max && element.loc.line == line
79
82
  end
80
83
 
84
+ # @api private
81
85
  def safe_to_ignore?(node)
82
86
  return true unless max
83
87
  return true if already_on_multiple_lines?(node)
@@ -93,6 +97,7 @@ module RuboCop
93
97
  false
94
98
  end
95
99
 
100
+ # @api private
96
101
  def breakable_collection?(node, elements)
97
102
  # For simplicity we only want to insert breaks in normal
98
103
  # hashes wrapped in a set of curly braces like {foo: 1}.
@@ -109,6 +114,7 @@ module RuboCop
109
114
  starts_with_bracket && has_second_element
110
115
  end
111
116
 
117
+ # @api private
112
118
  def contained_by_breakable_collection_on_same_line?(node)
113
119
  node.each_ancestor.find do |ancestor|
114
120
  # Ignore ancestors on different lines.
@@ -128,12 +134,12 @@ module RuboCop
128
134
  false
129
135
  end
130
136
 
137
+ # @api private
131
138
  def contained_by_multiline_collection_that_could_be_broken_up?(node)
132
139
  node.each_ancestor.find do |ancestor|
133
- if ancestor.hash_type? || ancestor.array_type?
134
- if breakable_collection?(ancestor, ancestor.children)
135
- return children_could_be_broken_up?(ancestor.children)
136
- end
140
+ if (ancestor.hash_type? || ancestor.array_type?) &&
141
+ breakable_collection?(ancestor, ancestor.children)
142
+ return children_could_be_broken_up?(ancestor.children)
137
143
  end
138
144
 
139
145
  next unless ancestor.send_type?
@@ -145,6 +151,7 @@ module RuboCop
145
151
  false
146
152
  end
147
153
 
154
+ # @api private
148
155
  def children_could_be_broken_up?(children)
149
156
  return false if all_on_same_line?(children)
150
157
 
@@ -157,12 +164,14 @@ module RuboCop
157
164
  false
158
165
  end
159
166
 
167
+ # @api private
160
168
  def all_on_same_line?(nodes)
161
169
  return true if nodes.empty?
162
170
 
163
171
  nodes.first.first_line == nodes.last.last_line
164
172
  end
165
173
 
174
+ # @api private
166
175
  def process_args(args)
167
176
  # If there is a trailing hash arg without explicit braces, like this:
168
177
  #
@@ -170,12 +179,12 @@ module RuboCop
170
179
  #
171
180
  # ...then each key/value pair is treated as a method 'argument'
172
181
  # when determining where line breaks should appear.
173
- if (last_arg = args.last)
174
- args = args[0...-1] + last_arg.children if last_arg.hash_type? && !last_arg.braces?
175
- end
182
+ last_arg = args.last
183
+ args = args[0...-1] + last_arg.children if last_arg&.hash_type? && !last_arg&.braces?
176
184
  args
177
185
  end
178
186
 
187
+ # @api private
179
188
  def already_on_multiple_lines?(node)
180
189
  node.first_line != node.last_line
181
190
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Help methods for working with nodes containing comments.
6
+ module CommentsHelp
7
+ include VisibilityHelp
8
+
9
+ def source_range_with_comment(node)
10
+ begin_pos, end_pos =
11
+ if node.def_type?
12
+ start_node = find_visibility_start(node) || node
13
+ end_node = find_visibility_end(node) || node
14
+ [begin_pos_with_comment(start_node),
15
+ end_position_for(end_node) + 1]
16
+ else
17
+ [begin_pos_with_comment(node), end_position_for(node)]
18
+ end
19
+
20
+ Parser::Source::Range.new(buffer, begin_pos, end_pos)
21
+ end
22
+
23
+ private
24
+
25
+ def end_position_for(node)
26
+ end_line = buffer.line_for_position(node.loc.expression.end_pos)
27
+ buffer.line_range(end_line).end_pos
28
+ end
29
+
30
+ def begin_pos_with_comment(node)
31
+ annotation_line = node.first_line - 1
32
+ first_comment = nil
33
+
34
+ processed_source.comments_before_line(annotation_line)
35
+ .reverse_each do |comment|
36
+ if comment.location.line == annotation_line
37
+ first_comment = comment
38
+ annotation_line -= 1
39
+ end
40
+ end
41
+
42
+ start_line_position(first_comment || node)
43
+ end
44
+
45
+ def start_line_position(node)
46
+ buffer.line_range(node.loc.line).begin_pos - 1
47
+ end
48
+
49
+ def buffer
50
+ processed_source.buffer
51
+ end
52
+ end
53
+ end
54
+ end