rubocop 0.49.1 → 0.50.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 (292) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -3
  3. data/bin/rubocop +1 -1
  4. data/config/default.yml +160 -99
  5. data/config/disabled.yml +4 -5
  6. data/config/enabled.yml +149 -47
  7. data/lib/rubocop.rb +41 -14
  8. data/lib/rubocop/ast/builder.rb +4 -1
  9. data/lib/rubocop/ast/node.rb +36 -42
  10. data/lib/rubocop/ast/node/args_node.rb +1 -13
  11. data/lib/rubocop/ast/node/array_node.rb +9 -0
  12. data/lib/rubocop/ast/node/block_node.rb +9 -0
  13. data/lib/rubocop/ast/node/def_node.rb +71 -0
  14. data/lib/rubocop/ast/node/for_node.rb +8 -0
  15. data/lib/rubocop/ast/node/if_node.rb +10 -2
  16. data/lib/rubocop/ast/node/mixin/collection_node.rb +15 -0
  17. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +174 -0
  18. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +89 -0
  19. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +18 -31
  20. data/lib/rubocop/ast/node/regexp_node.rb +35 -0
  21. data/lib/rubocop/ast/node/send_node.rb +1 -154
  22. data/lib/rubocop/ast/node/super_node.rb +3 -24
  23. data/lib/rubocop/ast/node/yield_node.rb +21 -0
  24. data/lib/rubocop/ast/traversal.rb +6 -6
  25. data/lib/rubocop/cli.rb +7 -3
  26. data/lib/rubocop/config.rb +45 -8
  27. data/lib/rubocop/config_loader.rb +7 -5
  28. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -3
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +64 -0
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +12 -12
  31. data/lib/rubocop/cop/commissioner.rb +8 -2
  32. data/lib/rubocop/cop/cop.rb +3 -1
  33. data/lib/rubocop/cop/generator.rb +94 -21
  34. data/lib/rubocop/cop/internal_affairs.rb +3 -0
  35. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +14 -3
  36. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +43 -0
  37. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +46 -0
  38. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +49 -0
  39. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +1 -1
  40. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +2 -3
  41. data/lib/rubocop/cop/layout/align_array.rb +2 -2
  42. data/lib/rubocop/cop/layout/align_hash.rb +2 -2
  43. data/lib/rubocop/cop/layout/align_parameters.rb +5 -11
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  46. data/lib/rubocop/cop/layout/dot_position.rb +9 -0
  47. data/lib/rubocop/cop/layout/else_alignment.rb +30 -13
  48. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +4 -0
  49. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +20 -4
  50. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -3
  51. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -3
  52. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +3 -3
  53. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +5 -2
  54. data/lib/rubocop/cop/layout/indent_heredoc.rb +19 -24
  55. data/lib/rubocop/cop/layout/indentation_consistency.rb +1 -2
  56. data/lib/rubocop/cop/layout/indentation_width.rb +12 -8
  57. data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -18
  58. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +20 -17
  59. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +3 -3
  60. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -0
  61. data/lib/rubocop/cop/layout/space_after_colon.rb +7 -0
  62. data/lib/rubocop/cop/layout/space_after_comma.rb +10 -0
  63. data/lib/rubocop/cop/layout/space_after_method_name.rb +5 -3
  64. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  65. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +13 -4
  66. data/lib/rubocop/cop/layout/space_around_keyword.rb +9 -5
  67. data/lib/rubocop/cop/layout/space_before_block_braces.rb +54 -5
  68. data/lib/rubocop/cop/layout/space_before_comment.rb +7 -0
  69. data/lib/rubocop/cop/layout/space_before_semicolon.rb +7 -0
  70. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +1 -1
  71. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  72. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  73. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +8 -4
  74. data/lib/rubocop/cop/layout/tab.rb +1 -1
  75. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +4 -2
  76. data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
  77. data/lib/rubocop/cop/lint/block_alignment.rb +15 -6
  78. data/lib/rubocop/cop/lint/boolean_symbol.rb +38 -0
  79. data/lib/rubocop/cop/lint/condition_position.rb +5 -1
  80. data/lib/rubocop/cop/lint/debugger.rb +16 -9
  81. data/lib/rubocop/cop/lint/def_end_alignment.rb +4 -4
  82. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +3 -3
  83. data/lib/rubocop/cop/lint/duplicate_methods.rb +73 -5
  84. data/lib/rubocop/cop/lint/duplicated_key.rb +1 -1
  85. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  86. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  87. data/lib/rubocop/cop/lint/empty_expression.rb +1 -1
  88. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  89. data/lib/rubocop/cop/lint/empty_when.rb +1 -1
  90. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  91. data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -5
  92. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +35 -40
  93. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -1
  94. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +18 -13
  95. data/lib/rubocop/cop/lint/inherit_exception.rb +8 -7
  96. data/lib/rubocop/cop/lint/interpolation_check.rb +36 -0
  97. data/lib/rubocop/cop/lint/literal_in_condition.rb +3 -3
  98. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  99. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  100. data/lib/rubocop/cop/lint/nested_method_definition.rb +5 -7
  101. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  102. data/lib/rubocop/cop/lint/percent_string_array.rb +3 -12
  103. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  104. data/lib/rubocop/cop/lint/rand_one.rb +7 -1
  105. data/lib/rubocop/cop/lint/redundant_with_index.rb +77 -0
  106. data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
  107. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  108. data/lib/rubocop/cop/lint/rescue_type.rb +13 -6
  109. data/lib/rubocop/cop/lint/rescue_without_error_class.rb +38 -0
  110. data/lib/rubocop/cop/lint/return_in_void_context.rb +63 -0
  111. data/lib/rubocop/cop/lint/script_permission.rb +6 -0
  112. data/lib/rubocop/cop/lint/syntax.rb +17 -20
  113. data/lib/rubocop/cop/lint/unified_integer.rb +3 -2
  114. data/lib/rubocop/cop/lint/unneeded_disable.rb +1 -1
  115. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
  116. data/lib/rubocop/cop/lint/unreachable_code.rb +53 -8
  117. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +74 -0
  118. data/lib/rubocop/cop/lint/uri_regexp.rb +73 -0
  119. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -8
  120. data/lib/rubocop/cop/lint/useless_setter_call.rb +10 -11
  121. data/lib/rubocop/cop/lint/void.rb +29 -23
  122. data/lib/rubocop/cop/metrics/line_length.rb +2 -2
  123. data/lib/rubocop/cop/metrics/method_length.rb +8 -3
  124. data/lib/rubocop/cop/metrics/parameter_lists.rb +5 -2
  125. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +1 -1
  126. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -2
  127. data/lib/rubocop/cop/mixin/first_element_line_break.rb +12 -3
  128. data/lib/rubocop/cop/mixin/heredoc.rb +28 -0
  129. data/lib/rubocop/cop/mixin/method_complexity.rb +9 -6
  130. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +68 -31
  131. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +18 -0
  132. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
  133. data/lib/rubocop/cop/mixin/percent_array.rb +52 -0
  134. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  135. data/lib/rubocop/cop/{style → naming}/accessor_method_name.rb +11 -12
  136. data/lib/rubocop/cop/{style → naming}/ascii_identifiers.rb +1 -1
  137. data/lib/rubocop/cop/{style/op_method.rb → naming/binary_operator_parameter_name.rb} +2 -2
  138. data/lib/rubocop/cop/{style → naming}/class_and_module_camel_case.rb +1 -1
  139. data/lib/rubocop/cop/{style → naming}/constant_name.rb +1 -1
  140. data/lib/rubocop/cop/{style → naming}/file_name.rb +8 -4
  141. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +68 -0
  142. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +58 -0
  143. data/lib/rubocop/cop/{style → naming}/method_name.rb +1 -1
  144. data/lib/rubocop/cop/{style → naming}/predicate_name.rb +6 -7
  145. data/lib/rubocop/cop/{style → naming}/variable_name.rb +11 -15
  146. data/lib/rubocop/cop/{style → naming}/variable_number.rb +1 -1
  147. data/lib/rubocop/cop/performance/caller.rb +39 -11
  148. data/lib/rubocop/cop/performance/casecmp.rb +4 -4
  149. data/lib/rubocop/cop/performance/compare_with_block.rb +4 -4
  150. data/lib/rubocop/cop/performance/double_start_end_with.rb +4 -4
  151. data/lib/rubocop/cop/performance/end_with.rb +3 -3
  152. data/lib/rubocop/cop/performance/fixed_size.rb +1 -1
  153. data/lib/rubocop/cop/performance/hash_each_methods.rb +66 -25
  154. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -2
  155. data/lib/rubocop/cop/performance/range_include.rb +2 -2
  156. data/lib/rubocop/cop/performance/redundant_block_call.rb +6 -6
  157. data/lib/rubocop/cop/performance/redundant_match.rb +5 -5
  158. data/lib/rubocop/cop/performance/redundant_merge.rb +39 -23
  159. data/lib/rubocop/cop/performance/redundant_sort_by.rb +2 -2
  160. data/lib/rubocop/cop/performance/regexp_match.rb +13 -5
  161. data/lib/rubocop/cop/performance/size.rb +1 -1
  162. data/lib/rubocop/cop/performance/start_with.rb +3 -3
  163. data/lib/rubocop/cop/performance/times_map.rb +23 -12
  164. data/lib/rubocop/cop/performance/unfreeze_string.rb +50 -0
  165. data/lib/rubocop/cop/performance/uri_default_parser.rb +47 -0
  166. data/lib/rubocop/cop/rails/active_support_aliases.rb +1 -1
  167. data/lib/rubocop/cop/rails/delegate.rb +36 -7
  168. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +1 -1
  169. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -2
  170. data/lib/rubocop/cop/rails/file_path.rb +3 -4
  171. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  172. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +48 -0
  173. data/lib/rubocop/cop/rails/http_positional_arguments.rb +5 -5
  174. data/lib/rubocop/cop/rails/not_null_column.rb +1 -1
  175. data/lib/rubocop/cop/rails/pluralization_grammar.rb +2 -2
  176. data/lib/rubocop/cop/rails/relative_date_constant.rb +1 -1
  177. data/lib/rubocop/cop/rails/request_referer.rb +2 -2
  178. data/lib/rubocop/cop/rails/reversible_migration.rb +12 -12
  179. data/lib/rubocop/cop/rails/save_bang.rb +8 -6
  180. data/lib/rubocop/cop/rails/scope_args.rb +1 -1
  181. data/lib/rubocop/cop/security/eval.rb +2 -2
  182. data/lib/rubocop/cop/security/json_load.rb +2 -2
  183. data/lib/rubocop/cop/security/marshal_load.rb +2 -2
  184. data/lib/rubocop/cop/security/yaml_load.rb +2 -2
  185. data/lib/rubocop/cop/style/alias.rb +44 -20
  186. data/lib/rubocop/cop/style/and_or.rb +48 -34
  187. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +1 -1
  188. data/lib/rubocop/cop/style/block_comments.rb +3 -1
  189. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  190. data/lib/rubocop/cop/style/command_literal.rb +20 -9
  191. data/lib/rubocop/cop/style/conditional_assignment.rb +30 -28
  192. data/lib/rubocop/cop/style/copyright.rb +10 -10
  193. data/lib/rubocop/cop/style/def_with_parentheses.rb +6 -5
  194. data/lib/rubocop/cop/style/dir.rb +52 -0
  195. data/lib/rubocop/cop/style/documentation_method.rb +2 -6
  196. data/lib/rubocop/cop/style/empty_case_condition.rb +1 -1
  197. data/lib/rubocop/cop/style/empty_else.rb +3 -2
  198. data/lib/rubocop/cop/style/empty_literal.rb +1 -2
  199. data/lib/rubocop/cop/style/empty_method.rb +27 -17
  200. data/lib/rubocop/cop/style/flip_flop.rb +2 -2
  201. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  202. data/lib/rubocop/cop/style/guard_clause.rb +4 -2
  203. data/lib/rubocop/cop/style/hash_syntax.rb +10 -10
  204. data/lib/rubocop/cop/style/identical_conditional_branches.rb +5 -1
  205. data/lib/rubocop/cop/style/if_with_semicolon.rb +1 -1
  206. data/lib/rubocop/cop/style/implicit_runtime_error.rb +4 -3
  207. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  208. data/lib/rubocop/cop/style/inverse_methods.rb +20 -8
  209. data/lib/rubocop/cop/style/lambda.rb +19 -9
  210. data/lib/rubocop/cop/style/lambda_call.rb +22 -1
  211. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +4 -20
  212. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -4
  213. data/lib/rubocop/cop/style/method_def_parentheses.rb +18 -26
  214. data/lib/rubocop/cop/style/method_missing.rb +5 -18
  215. data/lib/rubocop/cop/style/min_max.rb +67 -0
  216. data/lib/rubocop/cop/style/missing_else.rb +16 -3
  217. data/lib/rubocop/cop/style/mixin_grouping.rb +2 -2
  218. data/lib/rubocop/cop/style/module_function.rb +8 -4
  219. data/lib/rubocop/cop/style/multiline_if_modifier.rb +5 -1
  220. data/lib/rubocop/cop/style/multiline_memoization.rb +25 -3
  221. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  222. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  223. data/lib/rubocop/cop/style/mutable_constant.rb +2 -6
  224. data/lib/rubocop/cop/style/negated_if.rb +8 -4
  225. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +8 -8
  226. data/lib/rubocop/cop/style/nested_ternary_operator.rb +1 -1
  227. data/lib/rubocop/cop/style/non_nil_check.rb +14 -14
  228. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +6 -2
  229. data/lib/rubocop/cop/style/numeric_literals.rb +2 -2
  230. data/lib/rubocop/cop/style/numeric_predicate.rb +8 -4
  231. data/lib/rubocop/cop/style/one_line_conditional.rb +8 -3
  232. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  233. data/lib/rubocop/cop/style/optional_arguments.rb +1 -2
  234. data/lib/rubocop/cop/style/or_assignment.rb +88 -0
  235. data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
  236. data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -11
  237. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  238. data/lib/rubocop/cop/style/percent_q_literals.rb +2 -2
  239. data/lib/rubocop/cop/style/perl_backrefs.rb +1 -1
  240. data/lib/rubocop/cop/style/proc.rb +1 -1
  241. data/lib/rubocop/cop/style/raise_args.rb +16 -17
  242. data/lib/rubocop/cop/style/redundant_begin.rb +6 -5
  243. data/lib/rubocop/cop/style/redundant_conditional.rb +95 -0
  244. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  245. data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -11
  246. data/lib/rubocop/cop/style/redundant_return.rb +23 -11
  247. data/lib/rubocop/cop/style/redundant_self.rb +18 -9
  248. data/lib/rubocop/cop/style/regexp_literal.rb +12 -4
  249. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  250. data/lib/rubocop/cop/style/return_nil.rb +98 -0
  251. data/lib/rubocop/cop/style/safe_navigation.rb +80 -43
  252. data/lib/rubocop/cop/style/single_line_block_params.rb +14 -13
  253. data/lib/rubocop/cop/style/single_line_methods.rb +9 -13
  254. data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
  255. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +17 -39
  256. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +22 -1
  257. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  258. data/lib/rubocop/cop/style/symbol_array.rb +5 -25
  259. data/lib/rubocop/cop/style/symbol_literal.rb +1 -1
  260. data/lib/rubocop/cop/style/symbol_proc.rb +3 -18
  261. data/lib/rubocop/cop/style/ternary_parentheses.rb +14 -10
  262. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +28 -9
  263. data/lib/rubocop/cop/style/trivial_accessors.rb +39 -56
  264. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  265. data/lib/rubocop/cop/style/unneeded_capital_w.rb +1 -1
  266. data/lib/rubocop/cop/style/unneeded_interpolation.rb +1 -1
  267. data/lib/rubocop/cop/style/unneeded_percent_q.rb +1 -1
  268. data/lib/rubocop/cop/style/variable_interpolation.rb +8 -3
  269. data/lib/rubocop/cop/style/word_array.rb +7 -24
  270. data/lib/rubocop/cop/style/yoda_condition.rb +49 -14
  271. data/lib/rubocop/cop/style/zero_length_predicate.rb +25 -18
  272. data/lib/rubocop/cop/team.rb +16 -8
  273. data/lib/rubocop/cop/util.rb +11 -0
  274. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  275. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  276. data/lib/rubocop/formatter/offense_count_formatter.rb +2 -0
  277. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  278. data/lib/rubocop/formatter/tap_formatter.rb +71 -0
  279. data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -0
  280. data/lib/rubocop/node_pattern.rb +44 -26
  281. data/lib/rubocop/options.rb +1 -0
  282. data/lib/rubocop/processed_source.rb +3 -1
  283. data/lib/rubocop/remote_config.rb +5 -1
  284. data/lib/rubocop/result_cache.rb +1 -0
  285. data/lib/rubocop/rspec/cop_helper.rb +10 -10
  286. data/lib/rubocop/rspec/expect_offense.rb +6 -8
  287. data/lib/rubocop/rspec/shared_examples.rb +8 -8
  288. data/lib/rubocop/string_util.rb +2 -0
  289. data/lib/rubocop/version.rb +1 -1
  290. metadata +51 -18
  291. data/lib/rubocop/cop/mixin/access_modifier_node.rb +0 -41
  292. data/lib/rubocop/cop/mixin/on_method_def.rb +0 -44
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Common functionality for working with heredoc strings.
4
+ module Heredoc
5
+ OPENING_DELIMITER = /<<[~-]?'?(\w+)'?\b/
6
+
7
+ def on_str(node)
8
+ return unless heredoc?(node)
9
+
10
+ on_heredoc(node)
11
+ end
12
+ alias on_dstr on_str
13
+ alias on_xstr on_str
14
+
15
+ def on_heredoc(_node)
16
+ raise NotImplementedError
17
+ end
18
+
19
+ private
20
+
21
+ def heredoc?(node)
22
+ node.loc.is_a?(Parser::Source::Map::Heredoc)
23
+ end
24
+
25
+ def delimiter_string(node)
26
+ node.source.match(OPENING_DELIMITER).captures.first
27
+ end
28
+ end
@@ -4,21 +4,24 @@ module RuboCop
4
4
  module Cop
5
5
  # This module handles measurement and reporting of complexity in methods.
6
6
  module MethodComplexity
7
- include OnMethodDef
8
7
  include ConfigurableMax
9
8
 
10
- private
11
-
12
- def on_method_def(node, method_name, _args, _body)
9
+ def on_def(node)
13
10
  max = cop_config['Max']
14
11
  complexity = complexity(node)
12
+
15
13
  return unless complexity > max
16
14
 
17
- add_offense(node, :keyword,
18
- format(self.class::MSG, method_name, complexity, max)) do
15
+ add_offense(node, :keyword, format(self.class::MSG,
16
+ node.method_name,
17
+ complexity,
18
+ max)) do
19
19
  self.max = complexity.ceil
20
20
  end
21
21
  end
22
+ alias on_defs on_def
23
+
24
+ private
22
25
 
23
26
  def complexity(node)
24
27
  node.each_node(*self.class::COUNTED_NODES).reduce(1) do |score, n|
@@ -5,6 +5,14 @@ module RuboCop
5
5
  # Common functionality for checking multiline method calls and binary
6
6
  # operations.
7
7
  module MultilineExpressionIndentation
8
+ KEYWORD_ANCESTOR_TYPES = [:for, :return, *Util::MODIFIER_NODES].freeze
9
+ UNALIGNED_RHS_TYPES = %i[if while until for return
10
+ array kwbegin].freeze
11
+ ASSIGNMENT_RHS_TYPES = [:send, *Util::ASGN_NODES].freeze
12
+ DEFAULT_MESSAGE_TAIL = 'an expression'.freeze
13
+ ASSIGNMENT_MESSAGE_TAIL = 'an expression in an assignment'.freeze
14
+ KEYWORD_MESSAGE_TAIL = 'a %s in %s `%s` statement'.freeze
15
+
8
16
  def on_send(node)
9
17
  return if !node.receiver || node.method?(:[])
10
18
  return unless relevant_node?(node)
@@ -79,30 +87,46 @@ module RuboCop
79
87
  end
80
88
 
81
89
  def operation_description(node, rhs)
82
- ancestor = kw_node_with_special_indentation(node)
83
- if ancestor
84
- kw = ancestor.loc.keyword.source
85
- kind = kw == 'for' ? 'collection' : 'condition'
86
- article = kw =~ /^[iu]/ ? 'an' : 'a'
87
- "a #{kind} in #{article} `#{kw}` statement"
88
- else
89
- 'an expression' +
90
- (part_of_assignment_rhs(node, rhs) ? ' in an assignment' : '')
90
+ kw_node_with_special_indentation(node) do |ancestor|
91
+ return keyword_message_tail(ancestor)
92
+ end
93
+
94
+ part_of_assignment_rhs(node, rhs) do |_node|
95
+ return ASSIGNMENT_MESSAGE_TAIL
91
96
  end
97
+
98
+ DEFAULT_MESSAGE_TAIL
92
99
  end
93
100
 
94
- def kw_node_with_special_indentation(node)
95
- node.each_ancestor.find do |a|
96
- next unless a.loc.respond_to?(:keyword)
101
+ def keyword_message_tail(node)
102
+ keyword = node.loc.keyword.source
103
+ kind = keyword == 'for' ? 'collection' : 'condition'
104
+ article = keyword =~ /^[iu]/ ? 'an' : 'a'
97
105
 
98
- case a.type
99
- when :for then _, expression, = *a
100
- when :return then expression, = *a
101
- when *Util::MODIFIER_NODES then expression, = *a
106
+ format(KEYWORD_MESSAGE_TAIL, kind, article, keyword)
107
+ end
108
+
109
+ def kw_node_with_special_indentation(node)
110
+ keyword_node =
111
+ node.each_ancestor(*KEYWORD_ANCESTOR_TYPES).find do |ancestor|
112
+ within_node?(node, indented_keyword_expression(ancestor))
102
113
  end
103
114
 
104
- within_node?(node, expression) if expression
115
+ if keyword_node && block_given?
116
+ yield keyword_node
117
+ else
118
+ keyword_node
119
+ end
120
+ end
121
+
122
+ def indented_keyword_expression(node)
123
+ if node.for_type?
124
+ expression = node.collection
125
+ else
126
+ expression, = *node
105
127
  end
128
+
129
+ expression
106
130
  end
107
131
 
108
132
  def argument_in_method_call(node, kind)
@@ -122,17 +146,31 @@ module RuboCop
122
146
  end
123
147
 
124
148
  def part_of_assignment_rhs(node, candidate)
125
- node.each_ancestor.find do |a|
126
- case a.type
127
- when :if, :while, :until, :for, :return, :array, :kwbegin
128
- break # other kinds of alignment
129
- when :block
130
- break if part_of_block_body?(candidate, a)
131
- when :send
132
- valid_method_rhs_candidate?(candidate, a)
133
- when *Util::ASGN_NODES
134
- valid_rhs_candidate?(candidate, assignment_rhs(a))
135
- end
149
+ rhs_node = node.each_ancestor.find do |ancestor|
150
+ break if disqualified_rhs?(candidate, ancestor)
151
+
152
+ valid_rhs?(candidate, ancestor)
153
+ end
154
+
155
+ if rhs_node && block_given?
156
+ yield rhs_node
157
+ else
158
+ rhs_node
159
+ end
160
+ end
161
+
162
+ def disqualified_rhs?(candidate, ancestor)
163
+ UNALIGNED_RHS_TYPES.include?(ancestor.type) ||
164
+ ancestor.block_type? && part_of_block_body?(candidate, ancestor)
165
+ end
166
+
167
+ def valid_rhs?(candidate, ancestor)
168
+ if ancestor.send_type?
169
+ valid_method_rhs_candidate?(candidate, ancestor)
170
+ elsif Util::ASGN_NODES.include?(ancestor.type)
171
+ valid_rhs_candidate?(candidate, assignment_rhs(ancestor))
172
+ else
173
+ false
136
174
  end
137
175
  end
138
176
 
@@ -146,9 +184,8 @@ module RuboCop
146
184
  !candidate || within_node?(candidate, node)
147
185
  end
148
186
 
149
- def part_of_block_body?(candidate, node)
150
- _method, _args, body = *node
151
- body && within_node?(candidate, body)
187
+ def part_of_block_body?(candidate, block_node)
188
+ block_node.body && within_node?(candidate, block_node.body)
152
189
  end
153
190
 
154
191
  def assignment_rhs(node)
@@ -23,6 +23,12 @@ module RuboCop
23
23
  corrector.insert_before(node.loc.end, "\n".freeze)
24
24
  end
25
25
  else
26
+ # When a comment immediately before the closing brace gets in the way
27
+ # of an easy correction, the offense is reported but not auto-
28
+ # corrected. The user must handle the delicate decision of where to
29
+ # put the comment.
30
+ return if new_line_needed_before_closing_brace?(node)
31
+
26
32
  lambda do |corrector|
27
33
  corrector.remove(range_with_surrounding_space(node.loc.end,
28
34
  :left))
@@ -35,6 +41,18 @@ module RuboCop
35
41
 
36
42
  private
37
43
 
44
+ # Returns true for the case
45
+ # [a,
46
+ # b # comment
47
+ # ].some_method
48
+ def new_line_needed_before_closing_brace?(node)
49
+ return unless node.chained?
50
+
51
+ last_element_line =
52
+ last_element_range_with_trailing_comma(node).last_line
53
+ processed_source.comments.any? { |c| c.loc.line == last_element_line }
54
+ end
55
+
38
56
  def check(node)
39
57
  case style
40
58
  when :symmetrical then check_symmetrical(node)
@@ -20,7 +20,7 @@ module RuboCop
20
20
  return unless single_negative?(condition)
21
21
  return if node.if_type? && node.else?
22
22
 
23
- add_offense(node, :expression)
23
+ add_offense(node)
24
24
  end
25
25
 
26
26
  def negative_conditional_corrector(node)
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Common functionality for handling percent arrays.
6
+ module PercentArray
7
+ private
8
+
9
+ # Ruby does not allow percent arrays in an ambiguous block context.
10
+ #
11
+ # @example
12
+ #
13
+ # foo %i[bar baz] { qux }
14
+ def invalid_percent_array_context?(node)
15
+ parent = node.parent
16
+
17
+ parent && parent.send_type? && parent.arguments.include?(node) &&
18
+ !parent.parenthesized? && parent.block_literal?
19
+ end
20
+
21
+ def allowed_bracket_array?(node)
22
+ comments_in_array?(node) || below_array_length?(node) ||
23
+ invalid_percent_array_context?(node)
24
+ end
25
+
26
+ def message(_node)
27
+ style == :percent ? self.class::PERCENT_MSG : self.class::ARRAY_MSG
28
+ end
29
+
30
+ def comments_in_array?(node)
31
+ comments = processed_source.comments
32
+ array_range = node.source_range.to_a
33
+
34
+ comments.any? do |comment|
35
+ !(comment.loc.expression.to_a & array_range).empty?
36
+ end
37
+ end
38
+
39
+ def check_percent_array(node)
40
+ array_style_detected(:percent, node.values.size)
41
+ add_offense(node) if style == :brackets
42
+ end
43
+
44
+ def check_bracketed_array(node)
45
+ return if allowed_bracket_array?(node)
46
+
47
+ array_style_detected(:brackets, node.values.size)
48
+ add_offense(node) if style == :percent
49
+ end
50
+ end
51
+ end
52
+ end
@@ -14,7 +14,7 @@ module RuboCop
14
14
  return if part_of_ignored_node?(node)
15
15
 
16
16
  if offense?(node)
17
- add_offense(node, :expression) { opposite_style_detected }
17
+ add_offense(node) { opposite_style_detected }
18
18
  else
19
19
  correct_style_detected
20
20
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- module Style
5
+ module Naming
6
6
  # This cop makes sure that accessor methods are named properly.
7
7
  #
8
8
  # @example
@@ -18,26 +18,25 @@ module RuboCop
18
18
  # # good
19
19
  # def attribute ...
20
20
  class AccessorMethodName < Cop
21
- include OnMethodDef
22
-
23
- private
24
-
25
- def on_method_def(node, method_name, args, _body)
26
- if bad_reader_name?(method_name.to_s, args)
21
+ def on_def(node)
22
+ if bad_reader_name?(node)
27
23
  add_offense(node, :name,
28
24
  'Do not prefix reader method names with `get_`.')
29
- elsif bad_writer_name?(method_name.to_s, args)
25
+ elsif bad_writer_name?(node)
30
26
  add_offense(node, :name,
31
27
  'Do not prefix writer method names with `set_`.')
32
28
  end
33
29
  end
30
+ alias on_defs on_def
31
+
32
+ private
34
33
 
35
- def bad_reader_name?(method_name, args)
36
- method_name.start_with?('get_') && args.to_a.empty?
34
+ def bad_reader_name?(node)
35
+ node.method_name.to_s.start_with?('get_') && !node.arguments?
37
36
  end
38
37
 
39
- def bad_writer_name?(method_name, args)
40
- method_name.start_with?('set_') && args.to_a.one?
38
+ def bad_writer_name?(node)
39
+ node.method_name.to_s.start_with?('set_') && node.arguments.one?
41
40
  end
42
41
  end
43
42
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- module Style
5
+ module Naming
6
6
  # This cop checks for non-ascii characters in identifier names.
7
7
  class AsciiIdentifiers < Cop
8
8
  MSG = 'Use only ascii symbols in identifiers.'.freeze
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- module Style
5
+ module Naming
6
6
  # This cop makes sure that certain binary operator methods have their
7
7
  # sole parameter named `other`.
8
8
  #
@@ -13,7 +13,7 @@ module RuboCop
13
13
  #
14
14
  # # good
15
15
  # def +(other); end
16
- class OpMethod < Cop
16
+ class BinaryOperatorParameterName < Cop
17
17
  MSG = 'When defining the `%s` operator, ' \
18
18
  'name its argument `other`.'.freeze
19
19
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- module Style
5
+ module Naming
6
6
  # This cops checks for class and module names with
7
7
  # an underscore in them.
8
8
  class ClassAndModuleCamelCase < Cop
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- module Style
5
+ module Naming
6
6
  # This cop checks whether constant names are written using
7
7
  # SCREAMING_SNAKE_CASE.
8
8
  #
@@ -4,7 +4,7 @@ require 'pathname'
4
4
 
5
5
  module RuboCop
6
6
  module Cop
7
- module Style
7
+ module Naming
8
8
  # This cop makes sure that Ruby source files have snake_case
9
9
  # names. Ruby scripts (i.e. source files with a shebang in the
10
10
  # first line) are ignored.
@@ -87,8 +87,10 @@ module RuboCop
87
87
  basename =~ (regex || SNAKE_CASE)
88
88
  end
89
89
 
90
+ # rubocop:disable Metrics/CyclomaticComplexity
90
91
  def find_class_or_module(node, namespace)
91
- return nil if node.nil?
92
+ return nil unless node
93
+
92
94
  name = namespace.pop
93
95
 
94
96
  on_node(%i[class module casgn], node) do |child|
@@ -96,13 +98,15 @@ module RuboCop
96
98
 
97
99
  const_namespace, const_name = *const
98
100
  next if name != const_name && !match_acronym?(name, const_name)
101
+ next unless namespace.empty? ||
102
+ match_namespace(child, const_namespace, namespace)
99
103
 
100
- return node if namespace.empty?
101
- return node if match_namespace(child, const_namespace, namespace)
104
+ return node
102
105
  end
103
106
 
104
107
  nil
105
108
  end
109
+ # rubocop:enable Metrics/CyclomaticComplexity
106
110
 
107
111
  def match_namespace(node, namespace, expected)
108
112
  match_partial = partial_matcher!(expected)
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Naming
6
+ # This cop checks that your heredocs are using the configured case.
7
+ # By default it is configured to enforce uppercase heredocs.
8
+ #
9
+ # @example
10
+ #
11
+ # # EnforcedStyle: uppercase (default)
12
+ #
13
+ # # good
14
+ # <<-SQL
15
+ # SELECT * FROM foo
16
+ # SQL
17
+ #
18
+ # # bad
19
+ # <<-sql
20
+ # SELECT * FROM foo
21
+ # sql
22
+ #
23
+ # @example
24
+ #
25
+ # # EnforcedStyle: lowercase
26
+ #
27
+ # # good
28
+ # <<-sql
29
+ # SELECT * FROM foo
30
+ # sql
31
+ #
32
+ # # bad
33
+ # <<-SQL
34
+ # SELECT * FROM foo
35
+ # SQL
36
+ class HeredocDelimiterCase < Cop
37
+ include Heredoc
38
+ include ConfigurableEnforcedStyle
39
+
40
+ MSG = 'Use %s heredoc delimiters.'.freeze
41
+
42
+ def on_heredoc(node)
43
+ return if correct_case_delimiters?(node)
44
+
45
+ add_offense(node, :heredoc_end)
46
+ end
47
+
48
+ private
49
+
50
+ def message(_node)
51
+ format(MSG, style)
52
+ end
53
+
54
+ def correct_case_delimiters?(node)
55
+ delimiter_string(node) == correct_delimiters(node)
56
+ end
57
+
58
+ def correct_delimiters(node)
59
+ if style == :uppercase
60
+ delimiter_string(node).upcase
61
+ else
62
+ delimiter_string(node).downcase
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end