rubbycop 0.49.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 (499) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +211 -0
  4. data/assets/logo.png +0 -0
  5. data/assets/output.html.erb +261 -0
  6. data/bin/rubbycop +17 -0
  7. data/config/default.yml +1548 -0
  8. data/config/disabled.yml +119 -0
  9. data/config/enabled.yml +1734 -0
  10. data/lib/rubbycop.rb +510 -0
  11. data/lib/rubbycop/ast/builder.rb +64 -0
  12. data/lib/rubbycop/ast/node.rb +610 -0
  13. data/lib/rubbycop/ast/node/and_node.rb +37 -0
  14. data/lib/rubbycop/ast/node/array_node.rb +48 -0
  15. data/lib/rubbycop/ast/node/case_node.rb +64 -0
  16. data/lib/rubbycop/ast/node/ensure_node.rb +25 -0
  17. data/lib/rubbycop/ast/node/for_node.rb +53 -0
  18. data/lib/rubbycop/ast/node/hash_node.rb +109 -0
  19. data/lib/rubbycop/ast/node/if_node.rb +138 -0
  20. data/lib/rubbycop/ast/node/keyword_splat_node.rb +45 -0
  21. data/lib/rubbycop/ast/node/mixin/binary_operator_node.rb +23 -0
  22. data/lib/rubbycop/ast/node/mixin/conditional_node.rb +45 -0
  23. data/lib/rubbycop/ast/node/mixin/hash_element_node.rb +125 -0
  24. data/lib/rubbycop/ast/node/mixin/modifier_node.rb +17 -0
  25. data/lib/rubbycop/ast/node/mixin/predicate_operator_node.rb +35 -0
  26. data/lib/rubbycop/ast/node/or_node.rb +37 -0
  27. data/lib/rubbycop/ast/node/pair_node.rb +64 -0
  28. data/lib/rubbycop/ast/node/resbody_node.rb +25 -0
  29. data/lib/rubbycop/ast/node/send_node.rb +209 -0
  30. data/lib/rubbycop/ast/node/until_node.rb +43 -0
  31. data/lib/rubbycop/ast/node/when_node.rb +61 -0
  32. data/lib/rubbycop/ast/node/while_node.rb +43 -0
  33. data/lib/rubbycop/ast/sexp.rb +16 -0
  34. data/lib/rubbycop/ast/traversal.rb +171 -0
  35. data/lib/rubbycop/cached_data.rb +63 -0
  36. data/lib/rubbycop/cli.rb +199 -0
  37. data/lib/rubbycop/comment_config.rb +155 -0
  38. data/lib/rubbycop/config.rb +444 -0
  39. data/lib/rubbycop/config_loader.rb +244 -0
  40. data/lib/rubbycop/config_loader_resolver.rb +43 -0
  41. data/lib/rubbycop/config_store.rb +48 -0
  42. data/lib/rubbycop/cop/autocorrect_logic.rb +26 -0
  43. data/lib/rubbycop/cop/badge.rb +73 -0
  44. data/lib/rubbycop/cop/bundler/duplicated_gem.rb +69 -0
  45. data/lib/rubbycop/cop/bundler/ordered_gems.rb +113 -0
  46. data/lib/rubbycop/cop/commissioner.rb +118 -0
  47. data/lib/rubbycop/cop/cop.rb +222 -0
  48. data/lib/rubbycop/cop/corrector.rb +135 -0
  49. data/lib/rubbycop/cop/force.rb +41 -0
  50. data/lib/rubbycop/cop/ignored_node.rb +38 -0
  51. data/lib/rubbycop/cop/layout/access_modifier_indentation.rb +109 -0
  52. data/lib/rubbycop/cop/layout/align_array.rb +35 -0
  53. data/lib/rubbycop/cop/layout/align_hash.rb +235 -0
  54. data/lib/rubbycop/cop/layout/align_parameters.rb +97 -0
  55. data/lib/rubbycop/cop/layout/block_end_newline.rb +56 -0
  56. data/lib/rubbycop/cop/layout/case_indentation.rb +163 -0
  57. data/lib/rubbycop/cop/layout/closing_parenthesis_indentation.rb +88 -0
  58. data/lib/rubbycop/cop/layout/comment_indentation.rb +71 -0
  59. data/lib/rubbycop/cop/layout/dot_position.rb +84 -0
  60. data/lib/rubbycop/cop/layout/else_alignment.rb +105 -0
  61. data/lib/rubbycop/cop/layout/empty_line_after_magic_comment.rb +63 -0
  62. data/lib/rubbycop/cop/layout/empty_line_between_defs.rb +143 -0
  63. data/lib/rubbycop/cop/layout/empty_lines.rb +60 -0
  64. data/lib/rubbycop/cop/layout/empty_lines_around_access_modifier.rb +90 -0
  65. data/lib/rubbycop/cop/layout/empty_lines_around_begin_body.rb +42 -0
  66. data/lib/rubbycop/cop/layout/empty_lines_around_block_body.rb +41 -0
  67. data/lib/rubbycop/cop/layout/empty_lines_around_class_body.rb +39 -0
  68. data/lib/rubbycop/cop/layout/empty_lines_around_exception_handling_keywords.rb +127 -0
  69. data/lib/rubbycop/cop/layout/empty_lines_around_method_body.rb +41 -0
  70. data/lib/rubbycop/cop/layout/empty_lines_around_module_body.rb +44 -0
  71. data/lib/rubbycop/cop/layout/end_of_line.rb +52 -0
  72. data/lib/rubbycop/cop/layout/extra_spacing.rb +237 -0
  73. data/lib/rubbycop/cop/layout/first_array_element_line_break.rb +41 -0
  74. data/lib/rubbycop/cop/layout/first_hash_element_line_break.rb +33 -0
  75. data/lib/rubbycop/cop/layout/first_method_argument_line_break.rb +49 -0
  76. data/lib/rubbycop/cop/layout/first_method_parameter_line_break.rb +42 -0
  77. data/lib/rubbycop/cop/layout/first_parameter_indentation.rb +109 -0
  78. data/lib/rubbycop/cop/layout/indent_array.rb +114 -0
  79. data/lib/rubbycop/cop/layout/indent_assignment.rb +42 -0
  80. data/lib/rubbycop/cop/layout/indent_hash.rb +134 -0
  81. data/lib/rubbycop/cop/layout/indent_heredoc.rb +173 -0
  82. data/lib/rubbycop/cop/layout/indentation_consistency.rb +51 -0
  83. data/lib/rubbycop/cop/layout/indentation_width.rb +303 -0
  84. data/lib/rubbycop/cop/layout/initial_indentation.rb +42 -0
  85. data/lib/rubbycop/cop/layout/leading_comment_space.rb +43 -0
  86. data/lib/rubbycop/cop/layout/multiline_array_brace_layout.rb +81 -0
  87. data/lib/rubbycop/cop/layout/multiline_assignment_layout.rb +88 -0
  88. data/lib/rubbycop/cop/layout/multiline_block_layout.rb +134 -0
  89. data/lib/rubbycop/cop/layout/multiline_hash_brace_layout.rb +81 -0
  90. data/lib/rubbycop/cop/layout/multiline_method_call_brace_layout.rb +97 -0
  91. data/lib/rubbycop/cop/layout/multiline_method_call_indentation.rb +215 -0
  92. data/lib/rubbycop/cop/layout/multiline_method_definition_brace_layout.rb +82 -0
  93. data/lib/rubbycop/cop/layout/multiline_operation_indentation.rb +89 -0
  94. data/lib/rubbycop/cop/layout/rescue_ensure_alignment.rb +86 -0
  95. data/lib/rubbycop/cop/layout/space_after_colon.rb +40 -0
  96. data/lib/rubbycop/cop/layout/space_after_comma.rb +21 -0
  97. data/lib/rubbycop/cop/layout/space_after_method_name.rb +37 -0
  98. data/lib/rubbycop/cop/layout/space_after_not.rb +38 -0
  99. data/lib/rubbycop/cop/layout/space_after_semicolon.rb +21 -0
  100. data/lib/rubbycop/cop/layout/space_around_block_parameters.rb +109 -0
  101. data/lib/rubbycop/cop/layout/space_around_equals_in_parameter_default.rb +68 -0
  102. data/lib/rubbycop/cop/layout/space_around_keyword.rb +224 -0
  103. data/lib/rubbycop/cop/layout/space_around_operators.rb +142 -0
  104. data/lib/rubbycop/cop/layout/space_before_block_braces.rb +54 -0
  105. data/lib/rubbycop/cop/layout/space_before_comma.rb +16 -0
  106. data/lib/rubbycop/cop/layout/space_before_comment.rb +27 -0
  107. data/lib/rubbycop/cop/layout/space_before_first_arg.rb +64 -0
  108. data/lib/rubbycop/cop/layout/space_before_semicolon.rb +16 -0
  109. data/lib/rubbycop/cop/layout/space_in_lambda_literal.rb +87 -0
  110. data/lib/rubbycop/cop/layout/space_inside_array_percent_literal.rb +53 -0
  111. data/lib/rubbycop/cop/layout/space_inside_block_braces.rb +158 -0
  112. data/lib/rubbycop/cop/layout/space_inside_brackets.rb +20 -0
  113. data/lib/rubbycop/cop/layout/space_inside_hash_literal_braces.rb +150 -0
  114. data/lib/rubbycop/cop/layout/space_inside_parens.rb +16 -0
  115. data/lib/rubbycop/cop/layout/space_inside_percent_literal_delimiters.rb +64 -0
  116. data/lib/rubbycop/cop/layout/space_inside_range_literal.rb +63 -0
  117. data/lib/rubbycop/cop/layout/space_inside_string_interpolation.rb +65 -0
  118. data/lib/rubbycop/cop/layout/tab.rb +57 -0
  119. data/lib/rubbycop/cop/layout/trailing_blank_lines.rb +78 -0
  120. data/lib/rubbycop/cop/layout/trailing_whitespace.rb +28 -0
  121. data/lib/rubbycop/cop/lint/ambiguous_block_association.rb +66 -0
  122. data/lib/rubbycop/cop/lint/ambiguous_operator.rb +55 -0
  123. data/lib/rubbycop/cop/lint/ambiguous_regexp_literal.rb +43 -0
  124. data/lib/rubbycop/cop/lint/assignment_in_condition.rb +80 -0
  125. data/lib/rubbycop/cop/lint/block_alignment.rb +229 -0
  126. data/lib/rubbycop/cop/lint/circular_argument_reference.rb +83 -0
  127. data/lib/rubbycop/cop/lint/condition_position.rb +52 -0
  128. data/lib/rubbycop/cop/lint/debugger.rb +72 -0
  129. data/lib/rubbycop/cop/lint/def_end_alignment.rb +78 -0
  130. data/lib/rubbycop/cop/lint/deprecated_class_methods.rb +90 -0
  131. data/lib/rubbycop/cop/lint/duplicate_case_condition.rb +53 -0
  132. data/lib/rubbycop/cop/lint/duplicate_methods.rb +151 -0
  133. data/lib/rubbycop/cop/lint/duplicated_key.rb +38 -0
  134. data/lib/rubbycop/cop/lint/each_with_object_argument.rb +39 -0
  135. data/lib/rubbycop/cop/lint/else_layout.rb +65 -0
  136. data/lib/rubbycop/cop/lint/empty_ensure.rb +60 -0
  137. data/lib/rubbycop/cop/lint/empty_expression.rb +42 -0
  138. data/lib/rubbycop/cop/lint/empty_interpolation.rb +36 -0
  139. data/lib/rubbycop/cop/lint/empty_when.rb +38 -0
  140. data/lib/rubbycop/cop/lint/end_alignment.rb +157 -0
  141. data/lib/rubbycop/cop/lint/end_in_method.rb +40 -0
  142. data/lib/rubbycop/cop/lint/ensure_return.rb +43 -0
  143. data/lib/rubbycop/cop/lint/float_out_of_range.rb +35 -0
  144. data/lib/rubbycop/cop/lint/format_parameter_mismatch.rb +182 -0
  145. data/lib/rubbycop/cop/lint/handle_exceptions.rb +56 -0
  146. data/lib/rubbycop/cop/lint/implicit_string_concatenation.rb +95 -0
  147. data/lib/rubbycop/cop/lint/ineffective_access_modifier.rb +143 -0
  148. data/lib/rubbycop/cop/lint/inherit_exception.rb +83 -0
  149. data/lib/rubbycop/cop/lint/invalid_character_literal.rb +41 -0
  150. data/lib/rubbycop/cop/lint/literal_in_condition.rb +127 -0
  151. data/lib/rubbycop/cop/lint/literal_in_interpolation.rb +76 -0
  152. data/lib/rubbycop/cop/lint/loop.rb +63 -0
  153. data/lib/rubbycop/cop/lint/multiple_compare.rb +48 -0
  154. data/lib/rubbycop/cop/lint/nested_method_definition.rb +105 -0
  155. data/lib/rubbycop/cop/lint/next_without_accumulator.rb +50 -0
  156. data/lib/rubbycop/cop/lint/non_local_exit_from_iterator.rb +85 -0
  157. data/lib/rubbycop/cop/lint/parentheses_as_grouped_expression.rb +60 -0
  158. data/lib/rubbycop/cop/lint/percent_string_array.rb +84 -0
  159. data/lib/rubbycop/cop/lint/percent_symbol_array.rb +66 -0
  160. data/lib/rubbycop/cop/lint/rand_one.rb +39 -0
  161. data/lib/rubbycop/cop/lint/require_parentheses.rb +61 -0
  162. data/lib/rubbycop/cop/lint/rescue_exception.rb +45 -0
  163. data/lib/rubbycop/cop/lint/safe_navigation_chain.rb +70 -0
  164. data/lib/rubbycop/cop/lint/shadowed_exception.rb +132 -0
  165. data/lib/rubbycop/cop/lint/shadowing_outer_local_variable.rb +53 -0
  166. data/lib/rubbycop/cop/lint/string_conversion_in_interpolation.rb +58 -0
  167. data/lib/rubbycop/cop/lint/syntax.rb +55 -0
  168. data/lib/rubbycop/cop/lint/underscore_prefixed_variable_name.rb +62 -0
  169. data/lib/rubbycop/cop/lint/unified_integer.rb +42 -0
  170. data/lib/rubbycop/cop/lint/unneeded_disable.rb +231 -0
  171. data/lib/rubbycop/cop/lint/unneeded_splat_expansion.rb +141 -0
  172. data/lib/rubbycop/cop/lint/unreachable_code.rb +52 -0
  173. data/lib/rubbycop/cop/lint/unused_block_argument.rb +145 -0
  174. data/lib/rubbycop/cop/lint/unused_method_argument.rb +61 -0
  175. data/lib/rubbycop/cop/lint/useless_access_modifier.rb +229 -0
  176. data/lib/rubbycop/cop/lint/useless_assignment.rb +132 -0
  177. data/lib/rubbycop/cop/lint/useless_comparison.rb +28 -0
  178. data/lib/rubbycop/cop/lint/useless_else_without_rescue.rb +46 -0
  179. data/lib/rubbycop/cop/lint/useless_setter_call.rb +162 -0
  180. data/lib/rubbycop/cop/lint/void.rb +108 -0
  181. data/lib/rubbycop/cop/message_annotator.rb +116 -0
  182. data/lib/rubbycop/cop/metrics/abc_size.rb +39 -0
  183. data/lib/rubbycop/cop/metrics/block_length.rb +32 -0
  184. data/lib/rubbycop/cop/metrics/block_nesting.rb +64 -0
  185. data/lib/rubbycop/cop/metrics/class_length.rb +24 -0
  186. data/lib/rubbycop/cop/metrics/cyclomatic_complexity.rb +31 -0
  187. data/lib/rubbycop/cop/metrics/line_length.rb +168 -0
  188. data/lib/rubbycop/cop/metrics/method_length.rb +27 -0
  189. data/lib/rubbycop/cop/metrics/module_length.rb +24 -0
  190. data/lib/rubbycop/cop/metrics/parameter_lists.rb +45 -0
  191. data/lib/rubbycop/cop/metrics/perceived_complexity.rb +61 -0
  192. data/lib/rubbycop/cop/mixin/access_modifier_node.rb +41 -0
  193. data/lib/rubbycop/cop/mixin/annotation_comment.rb +36 -0
  194. data/lib/rubbycop/cop/mixin/array_hash_indentation.rb +82 -0
  195. data/lib/rubbycop/cop/mixin/array_min_size.rb +59 -0
  196. data/lib/rubbycop/cop/mixin/array_syntax.rb +15 -0
  197. data/lib/rubbycop/cop/mixin/autocorrect_alignment.rb +149 -0
  198. data/lib/rubbycop/cop/mixin/check_assignment.rb +40 -0
  199. data/lib/rubbycop/cop/mixin/classish_length.rb +36 -0
  200. data/lib/rubbycop/cop/mixin/code_length.rb +32 -0
  201. data/lib/rubbycop/cop/mixin/configurable_enforced_style.rb +97 -0
  202. data/lib/rubbycop/cop/mixin/configurable_formatting.rb +48 -0
  203. data/lib/rubbycop/cop/mixin/configurable_max.rb +19 -0
  204. data/lib/rubbycop/cop/mixin/configurable_naming.rb +16 -0
  205. data/lib/rubbycop/cop/mixin/configurable_numbering.rb +17 -0
  206. data/lib/rubbycop/cop/mixin/def_node.rb +27 -0
  207. data/lib/rubbycop/cop/mixin/documentation_comment.rb +46 -0
  208. data/lib/rubbycop/cop/mixin/duplication.rb +46 -0
  209. data/lib/rubbycop/cop/mixin/empty_lines_around_body.rb +161 -0
  210. data/lib/rubbycop/cop/mixin/end_keyword_alignment.rb +85 -0
  211. data/lib/rubbycop/cop/mixin/enforce_superclass.rb +36 -0
  212. data/lib/rubbycop/cop/mixin/first_element_line_break.rb +41 -0
  213. data/lib/rubbycop/cop/mixin/frozen_string_literal.rb +37 -0
  214. data/lib/rubbycop/cop/mixin/hash_alignment.rb +116 -0
  215. data/lib/rubbycop/cop/mixin/ignored_pattern.rb +27 -0
  216. data/lib/rubbycop/cop/mixin/integer_node.rb +12 -0
  217. data/lib/rubbycop/cop/mixin/match_range.rb +22 -0
  218. data/lib/rubbycop/cop/mixin/method_complexity.rb +30 -0
  219. data/lib/rubbycop/cop/mixin/method_preference.rb +30 -0
  220. data/lib/rubbycop/cop/mixin/min_body_length.rb +19 -0
  221. data/lib/rubbycop/cop/mixin/multiline_expression_indentation.rb +183 -0
  222. data/lib/rubbycop/cop/mixin/multiline_literal_brace_layout.rb +152 -0
  223. data/lib/rubbycop/cop/mixin/negative_conditional.rb +43 -0
  224. data/lib/rubbycop/cop/mixin/on_method_def.rb +44 -0
  225. data/lib/rubbycop/cop/mixin/on_normal_if_unless.rb +14 -0
  226. data/lib/rubbycop/cop/mixin/parentheses.rb +22 -0
  227. data/lib/rubbycop/cop/mixin/parser_diagnostic.rb +34 -0
  228. data/lib/rubbycop/cop/mixin/percent_literal.rb +100 -0
  229. data/lib/rubbycop/cop/mixin/preceding_following_alignment.rb +89 -0
  230. data/lib/rubbycop/cop/mixin/rescue_node.rb +21 -0
  231. data/lib/rubbycop/cop/mixin/safe_assignment.rb +20 -0
  232. data/lib/rubbycop/cop/mixin/safe_mode.rb +22 -0
  233. data/lib/rubbycop/cop/mixin/space_after_punctuation.rb +55 -0
  234. data/lib/rubbycop/cop/mixin/space_before_punctuation.rb +48 -0
  235. data/lib/rubbycop/cop/mixin/space_inside.rb +76 -0
  236. data/lib/rubbycop/cop/mixin/statement_modifier.rb +69 -0
  237. data/lib/rubbycop/cop/mixin/string_help.rb +33 -0
  238. data/lib/rubbycop/cop/mixin/string_literals_help.rb +33 -0
  239. data/lib/rubbycop/cop/mixin/surrounding_space.rb +40 -0
  240. data/lib/rubbycop/cop/mixin/target_rails_version.rb +16 -0
  241. data/lib/rubbycop/cop/mixin/target_ruby_version.rb +16 -0
  242. data/lib/rubbycop/cop/mixin/too_many_lines.rb +39 -0
  243. data/lib/rubbycop/cop/mixin/trailing_comma.rb +161 -0
  244. data/lib/rubbycop/cop/mixin/unused_argument.rb +42 -0
  245. data/lib/rubbycop/cop/offense.rb +188 -0
  246. data/lib/rubbycop/cop/performance/caller.rb +41 -0
  247. data/lib/rubbycop/cop/performance/case_when_splat.rb +176 -0
  248. data/lib/rubbycop/cop/performance/casecmp.rb +107 -0
  249. data/lib/rubbycop/cop/performance/compare_with_block.rb +107 -0
  250. data/lib/rubbycop/cop/performance/count.rb +98 -0
  251. data/lib/rubbycop/cop/performance/detect.rb +107 -0
  252. data/lib/rubbycop/cop/performance/double_start_end_with.rb +102 -0
  253. data/lib/rubbycop/cop/performance/end_with.rb +55 -0
  254. data/lib/rubbycop/cop/performance/fixed_size.rb +56 -0
  255. data/lib/rubbycop/cop/performance/flat_map.rb +73 -0
  256. data/lib/rubbycop/cop/performance/hash_each_methods.rb +84 -0
  257. data/lib/rubbycop/cop/performance/lstrip_rstrip.rb +41 -0
  258. data/lib/rubbycop/cop/performance/range_include.rb +41 -0
  259. data/lib/rubbycop/cop/performance/redundant_block_call.rb +93 -0
  260. data/lib/rubbycop/cop/performance/redundant_match.rb +55 -0
  261. data/lib/rubbycop/cop/performance/redundant_merge.rb +149 -0
  262. data/lib/rubbycop/cop/performance/redundant_sort_by.rb +45 -0
  263. data/lib/rubbycop/cop/performance/regexp_match.rb +215 -0
  264. data/lib/rubbycop/cop/performance/reverse_each.rb +40 -0
  265. data/lib/rubbycop/cop/performance/sample.rb +140 -0
  266. data/lib/rubbycop/cop/performance/size.rb +71 -0
  267. data/lib/rubbycop/cop/performance/start_with.rb +58 -0
  268. data/lib/rubbycop/cop/performance/string_replacement.rb +170 -0
  269. data/lib/rubbycop/cop/performance/times_map.rb +61 -0
  270. data/lib/rubbycop/cop/rails/action_filter.rb +96 -0
  271. data/lib/rubbycop/cop/rails/active_support_aliases.rb +68 -0
  272. data/lib/rubbycop/cop/rails/application_job.rb +32 -0
  273. data/lib/rubbycop/cop/rails/application_record.rb +32 -0
  274. data/lib/rubbycop/cop/rails/blank.rb +138 -0
  275. data/lib/rubbycop/cop/rails/date.rb +127 -0
  276. data/lib/rubbycop/cop/rails/delegate.rb +106 -0
  277. data/lib/rubbycop/cop/rails/delegate_allow_blank.rb +51 -0
  278. data/lib/rubbycop/cop/rails/dynamic_find_by.rb +81 -0
  279. data/lib/rubbycop/cop/rails/enum_uniqueness.rb +43 -0
  280. data/lib/rubbycop/cop/rails/exit.rb +61 -0
  281. data/lib/rubbycop/cop/rails/file_path.rb +75 -0
  282. data/lib/rubbycop/cop/rails/find_by.rb +51 -0
  283. data/lib/rubbycop/cop/rails/find_each.rb +47 -0
  284. data/lib/rubbycop/cop/rails/has_and_belongs_to_many.rb +18 -0
  285. data/lib/rubbycop/cop/rails/http_positional_arguments.rb +106 -0
  286. data/lib/rubbycop/cop/rails/not_null_column.rb +67 -0
  287. data/lib/rubbycop/cop/rails/output.rb +23 -0
  288. data/lib/rubbycop/cop/rails/output_safety.rb +58 -0
  289. data/lib/rubbycop/cop/rails/pluralization_grammar.rb +106 -0
  290. data/lib/rubbycop/cop/rails/present.rb +143 -0
  291. data/lib/rubbycop/cop/rails/read_write_attribute.rb +65 -0
  292. data/lib/rubbycop/cop/rails/relative_date_constant.rb +88 -0
  293. data/lib/rubbycop/cop/rails/request_referer.rb +56 -0
  294. data/lib/rubbycop/cop/rails/reversible_migration.rb +216 -0
  295. data/lib/rubbycop/cop/rails/safe_navigation.rb +91 -0
  296. data/lib/rubbycop/cop/rails/save_bang.rb +160 -0
  297. data/lib/rubbycop/cop/rails/scope_args.rb +29 -0
  298. data/lib/rubbycop/cop/rails/skips_model_validations.rb +63 -0
  299. data/lib/rubbycop/cop/rails/time_zone.rb +197 -0
  300. data/lib/rubbycop/cop/rails/uniq_before_pluck.rb +93 -0
  301. data/lib/rubbycop/cop/rails/validation.rb +64 -0
  302. data/lib/rubbycop/cop/registry.rb +171 -0
  303. data/lib/rubbycop/cop/security/eval.rb +30 -0
  304. data/lib/rubbycop/cop/security/json_load.rb +44 -0
  305. data/lib/rubbycop/cop/security/marshal_load.rb +37 -0
  306. data/lib/rubbycop/cop/security/yaml_load.rb +37 -0
  307. data/lib/rubbycop/cop/severity.rb +76 -0
  308. data/lib/rubbycop/cop/style/accessor_method_name.rb +45 -0
  309. data/lib/rubbycop/cop/style/alias.rb +119 -0
  310. data/lib/rubbycop/cop/style/and_or.rb +125 -0
  311. data/lib/rubbycop/cop/style/array_join.rb +30 -0
  312. data/lib/rubbycop/cop/style/ascii_comments.rb +38 -0
  313. data/lib/rubbycop/cop/style/ascii_identifiers.rb +36 -0
  314. data/lib/rubbycop/cop/style/attr.rb +50 -0
  315. data/lib/rubbycop/cop/style/auto_resource_cleanup.rb +42 -0
  316. data/lib/rubbycop/cop/style/bare_percent_literals.rb +57 -0
  317. data/lib/rubbycop/cop/style/begin_block.rb +16 -0
  318. data/lib/rubbycop/cop/style/block_comments.rb +46 -0
  319. data/lib/rubbycop/cop/style/block_delimiters.rb +228 -0
  320. data/lib/rubbycop/cop/style/braces_around_hash_parameters.rb +138 -0
  321. data/lib/rubbycop/cop/style/case_equality.rb +18 -0
  322. data/lib/rubbycop/cop/style/character_literal.rb +43 -0
  323. data/lib/rubbycop/cop/style/class_and_module_camel_case.rb +29 -0
  324. data/lib/rubbycop/cop/style/class_and_module_children.rb +69 -0
  325. data/lib/rubbycop/cop/style/class_check.rb +40 -0
  326. data/lib/rubbycop/cop/style/class_methods.rb +67 -0
  327. data/lib/rubbycop/cop/style/class_vars.rb +23 -0
  328. data/lib/rubbycop/cop/style/collection_methods.rb +51 -0
  329. data/lib/rubbycop/cop/style/colon_method_call.rb +33 -0
  330. data/lib/rubbycop/cop/style/command_literal.rb +119 -0
  331. data/lib/rubbycop/cop/style/comment_annotation.rb +62 -0
  332. data/lib/rubbycop/cop/style/conditional_assignment.rb +691 -0
  333. data/lib/rubbycop/cop/style/constant_name.rb +29 -0
  334. data/lib/rubbycop/cop/style/copyright.rb +89 -0
  335. data/lib/rubbycop/cop/style/def_with_parentheses.rb +31 -0
  336. data/lib/rubbycop/cop/style/documentation.rb +79 -0
  337. data/lib/rubbycop/cop/style/documentation_method.rb +80 -0
  338. data/lib/rubbycop/cop/style/double_negation.rb +35 -0
  339. data/lib/rubbycop/cop/style/each_for_simple_loop.rb +57 -0
  340. data/lib/rubbycop/cop/style/each_with_object.rb +91 -0
  341. data/lib/rubbycop/cop/style/empty_case_condition.rb +84 -0
  342. data/lib/rubbycop/cop/style/empty_else.rb +138 -0
  343. data/lib/rubbycop/cop/style/empty_literal.rb +108 -0
  344. data/lib/rubbycop/cop/style/empty_method.rb +102 -0
  345. data/lib/rubbycop/cop/style/encoding.rb +92 -0
  346. data/lib/rubbycop/cop/style/end_block.rb +17 -0
  347. data/lib/rubbycop/cop/style/even_odd.rb +56 -0
  348. data/lib/rubbycop/cop/style/file_name.rb +183 -0
  349. data/lib/rubbycop/cop/style/flip_flop.rb +20 -0
  350. data/lib/rubbycop/cop/style/for.rb +50 -0
  351. data/lib/rubbycop/cop/style/format_string.rb +46 -0
  352. data/lib/rubbycop/cop/style/format_string_token.rb +141 -0
  353. data/lib/rubbycop/cop/style/frozen_string_literal_comment.rb +96 -0
  354. data/lib/rubbycop/cop/style/global_vars.rb +70 -0
  355. data/lib/rubbycop/cop/style/guard_clause.rb +90 -0
  356. data/lib/rubbycop/cop/style/hash_syntax.rb +214 -0
  357. data/lib/rubbycop/cop/style/identical_conditional_branches.rb +130 -0
  358. data/lib/rubbycop/cop/style/if_inside_else.rb +45 -0
  359. data/lib/rubbycop/cop/style/if_unless_modifier.rb +80 -0
  360. data/lib/rubbycop/cop/style/if_unless_modifier_of_if_unless.rb +38 -0
  361. data/lib/rubbycop/cop/style/if_with_semicolon.rb +20 -0
  362. data/lib/rubbycop/cop/style/implicit_runtime_error.rb +31 -0
  363. data/lib/rubbycop/cop/style/infinite_loop.rb +91 -0
  364. data/lib/rubbycop/cop/style/inline_comment.rb +32 -0
  365. data/lib/rubbycop/cop/style/inverse_methods.rb +130 -0
  366. data/lib/rubbycop/cop/style/lambda.rb +209 -0
  367. data/lib/rubbycop/cop/style/lambda_call.rb +66 -0
  368. data/lib/rubbycop/cop/style/line_end_concatenation.rb +115 -0
  369. data/lib/rubbycop/cop/style/method_call_with_args_parentheses.rb +107 -0
  370. data/lib/rubbycop/cop/style/method_call_without_args_parentheses.rb +75 -0
  371. data/lib/rubbycop/cop/style/method_called_on_do_end_block.rb +44 -0
  372. data/lib/rubbycop/cop/style/method_def_parentheses.rb +83 -0
  373. data/lib/rubbycop/cop/style/method_missing.rb +81 -0
  374. data/lib/rubbycop/cop/style/method_name.rb +28 -0
  375. data/lib/rubbycop/cop/style/missing_else.rb +100 -0
  376. data/lib/rubbycop/cop/style/mixin_grouping.rb +135 -0
  377. data/lib/rubbycop/cop/style/module_function.rb +64 -0
  378. data/lib/rubbycop/cop/style/multiline_block_chain.rb +42 -0
  379. data/lib/rubbycop/cop/style/multiline_if_modifier.rb +63 -0
  380. data/lib/rubbycop/cop/style/multiline_if_then.rb +47 -0
  381. data/lib/rubbycop/cop/style/multiline_memoization.rb +77 -0
  382. data/lib/rubbycop/cop/style/multiline_ternary_operator.rb +19 -0
  383. data/lib/rubbycop/cop/style/mutable_constant.rb +68 -0
  384. data/lib/rubbycop/cop/style/negated_if.rb +103 -0
  385. data/lib/rubbycop/cop/style/negated_while.rb +32 -0
  386. data/lib/rubbycop/cop/style/nested_modifier.rb +87 -0
  387. data/lib/rubbycop/cop/style/nested_parenthesized_calls.rb +61 -0
  388. data/lib/rubbycop/cop/style/nested_ternary_operator.rb +21 -0
  389. data/lib/rubbycop/cop/style/next.rb +225 -0
  390. data/lib/rubbycop/cop/style/nil_comparison.rb +35 -0
  391. data/lib/rubbycop/cop/style/non_nil_check.rb +121 -0
  392. data/lib/rubbycop/cop/style/not.rb +69 -0
  393. data/lib/rubbycop/cop/style/numeric_literal_prefix.rb +97 -0
  394. data/lib/rubbycop/cop/style/numeric_literals.rb +101 -0
  395. data/lib/rubbycop/cop/style/numeric_predicate.rb +140 -0
  396. data/lib/rubbycop/cop/style/one_line_conditional.rb +75 -0
  397. data/lib/rubbycop/cop/style/op_method.rb +41 -0
  398. data/lib/rubbycop/cop/style/option_hash.rb +58 -0
  399. data/lib/rubbycop/cop/style/optional_arguments.rb +62 -0
  400. data/lib/rubbycop/cop/style/parallel_assignment.rb +287 -0
  401. data/lib/rubbycop/cop/style/parentheses_around_condition.rb +56 -0
  402. data/lib/rubbycop/cop/style/percent_literal_delimiters.rb +100 -0
  403. data/lib/rubbycop/cop/style/percent_q_literals.rb +52 -0
  404. data/lib/rubbycop/cop/style/perl_backrefs.rb +31 -0
  405. data/lib/rubbycop/cop/style/predicate_name.rb +67 -0
  406. data/lib/rubbycop/cop/style/preferred_hash_methods.rb +78 -0
  407. data/lib/rubbycop/cop/style/proc.rb +26 -0
  408. data/lib/rubbycop/cop/style/raise_args.rb +140 -0
  409. data/lib/rubbycop/cop/style/redundant_begin.rb +47 -0
  410. data/lib/rubbycop/cop/style/redundant_exception.rb +55 -0
  411. data/lib/rubbycop/cop/style/redundant_freeze.rb +45 -0
  412. data/lib/rubbycop/cop/style/redundant_parentheses.rb +199 -0
  413. data/lib/rubbycop/cop/style/redundant_return.rb +121 -0
  414. data/lib/rubbycop/cop/style/redundant_self.rb +144 -0
  415. data/lib/rubbycop/cop/style/regexp_literal.rb +114 -0
  416. data/lib/rubbycop/cop/style/rescue_modifier.rb +37 -0
  417. data/lib/rubbycop/cop/style/safe_navigation.rb +145 -0
  418. data/lib/rubbycop/cop/style/self_assignment.rb +93 -0
  419. data/lib/rubbycop/cop/style/semicolon.rb +70 -0
  420. data/lib/rubbycop/cop/style/send.rb +21 -0
  421. data/lib/rubbycop/cop/style/signal_exception.rb +109 -0
  422. data/lib/rubbycop/cop/style/single_line_block_params.rb +68 -0
  423. data/lib/rubbycop/cop/style/single_line_methods.rb +77 -0
  424. data/lib/rubbycop/cop/style/special_global_vars.rb +156 -0
  425. data/lib/rubbycop/cop/style/stabby_lambda_parentheses.rb +113 -0
  426. data/lib/rubbycop/cop/style/string_literals.rb +102 -0
  427. data/lib/rubbycop/cop/style/string_literals_in_interpolation.rb +30 -0
  428. data/lib/rubbycop/cop/style/string_methods.rb +34 -0
  429. data/lib/rubbycop/cop/style/struct_inheritance.rb +32 -0
  430. data/lib/rubbycop/cop/style/symbol_array.rb +109 -0
  431. data/lib/rubbycop/cop/style/symbol_literal.rb +32 -0
  432. data/lib/rubbycop/cop/style/symbol_proc.rb +143 -0
  433. data/lib/rubbycop/cop/style/ternary_parentheses.rb +200 -0
  434. data/lib/rubbycop/cop/style/trailing_comma_in_arguments.rb +64 -0
  435. data/lib/rubbycop/cop/style/trailing_comma_in_literal.rb +56 -0
  436. data/lib/rubbycop/cop/style/trailing_underscore_variable.rb +113 -0
  437. data/lib/rubbycop/cop/style/trivial_accessors.rb +176 -0
  438. data/lib/rubbycop/cop/style/unless_else.rb +39 -0
  439. data/lib/rubbycop/cop/style/unneeded_capital_w.rb +41 -0
  440. data/lib/rubbycop/cop/style/unneeded_interpolation.rb +98 -0
  441. data/lib/rubbycop/cop/style/unneeded_percent_q.rb +96 -0
  442. data/lib/rubbycop/cop/style/variable_interpolation.rb +44 -0
  443. data/lib/rubbycop/cop/style/variable_name.rb +39 -0
  444. data/lib/rubbycop/cop/style/variable_number.rb +78 -0
  445. data/lib/rubbycop/cop/style/when_then.rb +24 -0
  446. data/lib/rubbycop/cop/style/while_until_do.rb +36 -0
  447. data/lib/rubbycop/cop/style/while_until_modifier.rb +41 -0
  448. data/lib/rubbycop/cop/style/word_array.rb +114 -0
  449. data/lib/rubbycop/cop/style/zero_length_predicate.rb +90 -0
  450. data/lib/rubbycop/cop/team.rb +193 -0
  451. data/lib/rubbycop/cop/util.rb +309 -0
  452. data/lib/rubbycop/cop/variable_force.rb +458 -0
  453. data/lib/rubbycop/cop/variable_force/assignment.rb +90 -0
  454. data/lib/rubbycop/cop/variable_force/branch.rb +318 -0
  455. data/lib/rubbycop/cop/variable_force/branchable.rb +21 -0
  456. data/lib/rubbycop/cop/variable_force/reference.rb +49 -0
  457. data/lib/rubbycop/cop/variable_force/scope.rb +107 -0
  458. data/lib/rubbycop/cop/variable_force/variable.rb +103 -0
  459. data/lib/rubbycop/cop/variable_force/variable_table.rb +128 -0
  460. data/lib/rubbycop/error.rb +11 -0
  461. data/lib/rubbycop/formatter/base_formatter.rb +123 -0
  462. data/lib/rubbycop/formatter/clang_style_formatter.rb +54 -0
  463. data/lib/rubbycop/formatter/colorizable.rb +41 -0
  464. data/lib/rubbycop/formatter/disabled_config_formatter.rb +181 -0
  465. data/lib/rubbycop/formatter/disabled_lines_formatter.rb +57 -0
  466. data/lib/rubbycop/formatter/emacs_style_formatter.rb +24 -0
  467. data/lib/rubbycop/formatter/file_list_formatter.rb +19 -0
  468. data/lib/rubbycop/formatter/formatter_set.rb +102 -0
  469. data/lib/rubbycop/formatter/fuubar_style_formatter.rb +80 -0
  470. data/lib/rubbycop/formatter/html_formatter.rb +134 -0
  471. data/lib/rubbycop/formatter/json_formatter.rb +74 -0
  472. data/lib/rubbycop/formatter/offense_count_formatter.rb +55 -0
  473. data/lib/rubbycop/formatter/progress_formatter.rb +63 -0
  474. data/lib/rubbycop/formatter/simple_text_formatter.rb +136 -0
  475. data/lib/rubbycop/formatter/text_util.rb +20 -0
  476. data/lib/rubbycop/formatter/worst_offenders_formatter.rb +60 -0
  477. data/lib/rubbycop/magic_comment.rb +210 -0
  478. data/lib/rubbycop/name_similarity.rb +21 -0
  479. data/lib/rubbycop/node_pattern.rb +543 -0
  480. data/lib/rubbycop/options.rb +355 -0
  481. data/lib/rubbycop/path_util.rb +36 -0
  482. data/lib/rubbycop/platform.rb +11 -0
  483. data/lib/rubbycop/processed_source.rb +151 -0
  484. data/lib/rubbycop/rake_task.rb +86 -0
  485. data/lib/rubbycop/remote_config.rb +78 -0
  486. data/lib/rubbycop/result_cache.rb +176 -0
  487. data/lib/rubbycop/rspec/cop_helper.rb +98 -0
  488. data/lib/rubbycop/rspec/host_environment_simulation_helper.rb +32 -0
  489. data/lib/rubbycop/rspec/shared_contexts.rb +98 -0
  490. data/lib/rubbycop/rspec/shared_examples.rb +92 -0
  491. data/lib/rubbycop/rspec/support.rb +8 -0
  492. data/lib/rubbycop/runner.rb +338 -0
  493. data/lib/rubbycop/string_interpreter.rb +57 -0
  494. data/lib/rubbycop/string_util.rb +156 -0
  495. data/lib/rubbycop/target_finder.rb +201 -0
  496. data/lib/rubbycop/token.rb +25 -0
  497. data/lib/rubbycop/version.rb +19 -0
  498. data/lib/rubbycop/warning.rb +11 -0
  499. metadata +663 -0
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for unneeded usages of splat expansion
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # a = *[1, 2, 3]
13
+ # a = *'a'
14
+ # a = *1
15
+ #
16
+ # begin
17
+ # foo
18
+ # rescue *[StandardError, ApplicationError]
19
+ # bar
20
+ # end
21
+ #
22
+ # case foo
23
+ # when *[1, 2, 3]
24
+ # bar
25
+ # else
26
+ # baz
27
+ # end
28
+ #
29
+ # @example
30
+ #
31
+ # # good
32
+ #
33
+ # c = [1, 2, 3]
34
+ # a = *c
35
+ # a, b = *c
36
+ # a, *b = *c
37
+ # a = *1..10
38
+ # a = ['a']
39
+ #
40
+ # begin
41
+ # foo
42
+ # rescue StandardError, ApplicationError
43
+ # bar
44
+ # end
45
+ #
46
+ # case foo
47
+ # when *[1, 2, 3]
48
+ # bar
49
+ # else
50
+ # baz
51
+ # end
52
+ class UnneededSplatExpansion < Cop
53
+ MSG = 'Unnecessary splat expansion.'.freeze
54
+ ARRAY_PARAM_MSG = 'Pass array contents as separate arguments.'.freeze
55
+ PERCENT_W = '%w'.freeze
56
+ PERCENT_CAPITAL_W = '%W'.freeze
57
+ PERCENT_I = '%i'.freeze
58
+ PERCENT_CAPITAL_I = '%I'.freeze
59
+ ARRAY_NEW_PATTERN = '$(send (const nil :Array) :new ...)'.freeze
60
+ ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn].freeze
61
+
62
+ def_node_matcher :literal_expansion?, <<-PATTERN
63
+ (splat {$({str dstr int float array} ...) (block #{ARRAY_NEW_PATTERN} ...) #{ARRAY_NEW_PATTERN}} ...)
64
+ PATTERN
65
+
66
+ def on_splat(node)
67
+ literal_expansion?(node) do |object|
68
+ if object.send_type?
69
+ return unless ASSIGNMENT_TYPES.include?(node.parent.parent.type)
70
+ end
71
+
72
+ if array_splat?(node) &&
73
+ (method_argument?(node) || part_of_an_array?(node))
74
+ add_offense(node, :expression, ARRAY_PARAM_MSG)
75
+ else
76
+ add_offense(node, :expression)
77
+ end
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def autocorrect(node)
84
+ variable, = *node
85
+ loc = node.loc
86
+
87
+ lambda do |corrector|
88
+ if !variable.array_type?
89
+ corrector.replace(loc.expression, "[#{variable.source}]")
90
+ elsif unneeded_brackets?(node)
91
+ corrector.replace(loc.expression, remove_brackets(variable))
92
+ else
93
+ corrector.remove(loc.operator)
94
+ end
95
+ end
96
+ end
97
+
98
+ def array_splat?(node)
99
+ node.children.first.array_type?
100
+ end
101
+
102
+ def method_argument?(node)
103
+ node.parent.send_type?
104
+ end
105
+
106
+ def part_of_an_array?(node)
107
+ # The parent of a splat expansion is an array that does not have
108
+ # `begin` or `end`
109
+ parent = node.parent
110
+ parent.array_type? && parent.loc.begin && parent.loc.end
111
+ end
112
+
113
+ def unneeded_brackets?(node)
114
+ parent = node.parent
115
+ grandparent = node.parent.parent
116
+
117
+ parent.when_type? || parent.send_type? || part_of_an_array?(node) ||
118
+ (grandparent && grandparent.resbody_type?)
119
+ end
120
+
121
+ def remove_brackets(array)
122
+ array_start = array.loc.begin.source
123
+ elements = *array
124
+ elements = elements.map(&:source)
125
+
126
+ if array_start.start_with?(PERCENT_W)
127
+ "'#{elements.join("', '")}'"
128
+ elsif array_start.start_with?(PERCENT_CAPITAL_W)
129
+ %("#{elements.join('", "')}")
130
+ elsif array_start.start_with?(PERCENT_I)
131
+ ":#{elements.join(', :')}"
132
+ elsif array_start.start_with?(PERCENT_CAPITAL_I)
133
+ %(:"#{elements.join('", :"')}")
134
+ else
135
+ elements.join(', ')
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for unreachable code.
7
+ # The check are based on the presence of flow of control
8
+ # statement in non-final position in *begin*(implicit) blocks.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ #
14
+ # def some_method
15
+ # return
16
+ # do_something
17
+ # end
18
+ #
19
+ # @example
20
+ #
21
+ # # good
22
+ #
23
+ # def some_method
24
+ # do_something
25
+ # end
26
+ class UnreachableCode < Cop
27
+ MSG = 'Unreachable code detected.'.freeze
28
+
29
+ NODE_TYPES = %i[return next break retry redo].freeze
30
+ FLOW_COMMANDS = %i[throw raise fail].freeze
31
+
32
+ def on_begin(node)
33
+ expressions = *node
34
+
35
+ expressions.each_cons(2) do |e1, e2|
36
+ next unless NODE_TYPES.include?(e1.type) || flow_command?(e1)
37
+
38
+ add_offense(e2, :expression)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def flow_command?(node)
45
+ return false unless node.send_type?
46
+
47
+ FLOW_COMMANDS.any? { |c| node.command?(c) }
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for unused block arguments.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # do_something do |used, unused|
13
+ # puts used
14
+ # end
15
+ #
16
+ # do_something do |bar|
17
+ # puts :foo
18
+ # end
19
+ #
20
+ # define_method(:foo) do |bar|
21
+ # puts :baz
22
+ # end
23
+ #
24
+ # @example
25
+ #
26
+ # #good
27
+ #
28
+ # do_something do |used, _unused|
29
+ # puts used
30
+ # end
31
+ #
32
+ # do_something do
33
+ # puts :foo
34
+ # end
35
+ #
36
+ # define_method(:foo) do |_bar|
37
+ # puts :baz
38
+ # end
39
+ class UnusedBlockArgument < Cop
40
+ include UnusedArgument
41
+
42
+ private
43
+
44
+ def check_argument(variable)
45
+ return if allowed_block?(variable) ||
46
+ allowed_keyword_argument?(variable)
47
+
48
+ super
49
+ end
50
+
51
+ def allowed_block?(variable)
52
+ !variable.block_argument? ||
53
+ (ignore_empty_blocks? && empty_block?(variable))
54
+ end
55
+
56
+ def allowed_keyword_argument?(variable)
57
+ variable.keyword_argument? &&
58
+ allow_unused_keyword_arguments?
59
+ end
60
+
61
+ def message(variable)
62
+ message = "Unused #{variable_type(variable)} - `#{variable.name}`."
63
+
64
+ if variable.explicit_block_local_variable?
65
+ message
66
+ else
67
+ augment_message(message, variable)
68
+ end
69
+ end
70
+
71
+ def augment_message(message, variable)
72
+ scope = variable.scope
73
+ all_arguments = scope.variables.each_value.select(&:block_argument?)
74
+
75
+ augmentation = if scope.node.lambda?
76
+ message_for_lambda(variable, all_arguments)
77
+ else
78
+ message_for_normal_block(variable, all_arguments)
79
+ end
80
+
81
+ [message, augmentation].join(' ')
82
+ end
83
+
84
+ def variable_type(variable)
85
+ if variable.explicit_block_local_variable?
86
+ 'block local variable'
87
+ else
88
+ 'block argument'
89
+ end
90
+ end
91
+
92
+ def message_for_normal_block(variable, all_arguments)
93
+ if all_arguments.none?(&:referenced?) &&
94
+ !define_method_call?(variable)
95
+ if all_arguments.count > 1
96
+ "You can omit all the arguments if you don't care about them."
97
+ else
98
+ "You can omit the argument if you don't care about it."
99
+ end
100
+ else
101
+ message_for_underscore_prefix(variable)
102
+ end
103
+ end
104
+
105
+ def message_for_lambda(variable, all_arguments)
106
+ message = message_for_underscore_prefix(variable)
107
+
108
+ if all_arguments.none?(&:referenced?)
109
+ proc_message = 'Also consider using a proc without arguments ' \
110
+ 'instead of a lambda if you want it ' \
111
+ "to accept any arguments but don't care about them."
112
+ end
113
+
114
+ [message, proc_message].compact.join(' ')
115
+ end
116
+
117
+ def message_for_underscore_prefix(variable)
118
+ "If it's necessary, use `_` or `_#{variable.name}` " \
119
+ "as an argument name to indicate that it won't be used."
120
+ end
121
+
122
+ def define_method_call?(variable)
123
+ call, = *variable.scope.node
124
+ _, method, = *call
125
+
126
+ method == :define_method
127
+ end
128
+
129
+ def empty_block?(variable)
130
+ _send, _args, body = *variable.scope.node
131
+
132
+ body.nil?
133
+ end
134
+
135
+ def allow_unused_keyword_arguments?
136
+ cop_config['AllowUnusedKeywordArguments']
137
+ end
138
+
139
+ def ignore_empty_blocks?
140
+ cop_config['IgnoreEmptyBlocks']
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for unused method arguments.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # def some_method(used, unused, _unused_but_allowed)
13
+ # puts used
14
+ # end
15
+ #
16
+ # @example
17
+ #
18
+ # # good
19
+ #
20
+ # def some_method(used, _unused, _unused_but_allowed)
21
+ # puts used
22
+ # end
23
+ class UnusedMethodArgument < Cop
24
+ include UnusedArgument
25
+
26
+ def check_argument(variable)
27
+ return unless variable.method_argument?
28
+ return if variable.keyword_argument? &&
29
+ cop_config['AllowUnusedKeywordArguments']
30
+
31
+ if cop_config['IgnoreEmptyMethods']
32
+ _name, _args, body = *variable.scope.node
33
+ return if body.nil?
34
+ end
35
+
36
+ super
37
+ end
38
+
39
+ def message(variable)
40
+ message = String.new("Unused method argument - `#{variable.name}`.")
41
+
42
+ unless variable.keyword_argument?
43
+ message << " If it's necessary, use `_` or `_#{variable.name}` " \
44
+ "as an argument name to indicate that it won't be used."
45
+ end
46
+
47
+ scope = variable.scope
48
+ all_arguments = scope.variables.each_value.select(&:method_argument?)
49
+
50
+ if all_arguments.none?(&:referenced?)
51
+ message << " You can also write as `#{scope.name}(*)` " \
52
+ 'if you want the method to accept any arguments ' \
53
+ "but don't care about them."
54
+ end
55
+
56
+ message
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,229 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for redundant access modifiers, including those with no
7
+ # code, those which are repeated, and leading `public` modifiers in a
8
+ # class or module body. Conditionally-defined methods are considered as
9
+ # always being defined, and thus access modifiers guarding such methods
10
+ # are not redundant.
11
+ #
12
+ # @example
13
+ #
14
+ # class Foo
15
+ # public # this is redundant (default access is public)
16
+ #
17
+ # def method
18
+ # end
19
+ #
20
+ # private # this is not redundant (a method is defined)
21
+ # def method2
22
+ # end
23
+ #
24
+ # private # this is redundant (no following methods are defined)
25
+ # end
26
+ #
27
+ # @example
28
+ #
29
+ # class Foo
30
+ # # The following is not redundant (conditionally defined methods are
31
+ # # considered as always defining a method)
32
+ # private
33
+ #
34
+ # if condition?
35
+ # def method
36
+ # end
37
+ # end
38
+ #
39
+ # protected # this is not redundant (method is defined)
40
+ #
41
+ # define_method(:method2) do
42
+ # end
43
+ #
44
+ # protected # this is redundant (repeated from previous modifier)
45
+ #
46
+ # [1,2,3].each do |i|
47
+ # define_method("foo#{i}") do
48
+ # end
49
+ # end
50
+ #
51
+ # # The following is redundant (methods defined on the class'
52
+ # # singleton class are not affected by the public modifier)
53
+ # public
54
+ #
55
+ # def self.method3
56
+ # end
57
+ # end
58
+ #
59
+ # @example
60
+ # # Lint/UselessAccessModifier:
61
+ # # ContextCreatingMethods:
62
+ # # - concerning
63
+ # require 'active_support/concern'
64
+ # class Foo
65
+ # concerning :Bar do
66
+ # def some_public_method
67
+ # end
68
+ #
69
+ # private
70
+ #
71
+ # def some_private_method
72
+ # end
73
+ # end
74
+ #
75
+ # # this is not redundant because `concerning` created its own context
76
+ # private
77
+ #
78
+ # def some_other_private_method
79
+ # end
80
+ # end
81
+ #
82
+ # @example
83
+ # # Lint/UselessAccessModifier:
84
+ # # MethodCreatingMethods:
85
+ # # - delegate
86
+ # require 'active_support/core_ext/module/delegation'
87
+ # class Foo
88
+ # # this is not redundant because `delegate` creates methods
89
+ # private
90
+ #
91
+ # delegate :method_a, to: :method_b
92
+ # end
93
+ class UselessAccessModifier < Cop
94
+ MSG = 'Useless `%s` access modifier.'.freeze
95
+
96
+ def on_class(node)
97
+ check_node(node.children[2]) # class body
98
+ end
99
+
100
+ def on_module(node)
101
+ check_node(node.children[1]) # module body
102
+ end
103
+
104
+ def on_block(node)
105
+ return unless eval_call?(node)
106
+
107
+ check_node(node.children[2]) # block body
108
+ end
109
+
110
+ def on_sclass(node)
111
+ check_node(node.children[1]) # singleton class body
112
+ end
113
+
114
+ private
115
+
116
+ def_node_matcher :access_modifier, <<-PATTERN
117
+ (send nil ${:public :protected :private})
118
+ PATTERN
119
+
120
+ def_node_matcher :static_method_definition?, <<-PATTERN
121
+ {def (send nil {:attr :attr_reader :attr_writer :attr_accessor} ...)}
122
+ PATTERN
123
+
124
+ def_node_matcher :dynamic_method_definition?, <<-PATTERN
125
+ {(send nil :define_method ...) (block (send nil :define_method ...) ...)}
126
+ PATTERN
127
+
128
+ def_node_matcher :class_or_instance_eval?, <<-PATTERN
129
+ (block (send _ {:class_eval :instance_eval}) ...)
130
+ PATTERN
131
+
132
+ def_node_matcher :class_or_module_or_struct_new_call?, <<-PATTERN
133
+ (block (send (const nil {:Class :Module :Struct}) :new ...) ...)
134
+ PATTERN
135
+
136
+ def check_node(node)
137
+ return if node.nil?
138
+
139
+ if node.begin_type?
140
+ check_scope(node)
141
+ elsif (vis = access_modifier(node))
142
+ add_offense(node, :expression, format(MSG, vis))
143
+ end
144
+ end
145
+
146
+ def check_scope(node)
147
+ cur_vis, unused = check_child_nodes(node, nil, :public)
148
+
149
+ add_offense(unused, :expression, format(MSG, cur_vis)) if unused
150
+ end
151
+
152
+ def check_child_nodes(node, unused, cur_vis)
153
+ node.child_nodes.each do |child|
154
+ if (new_vis = access_modifier(child))
155
+ cur_vis, unused =
156
+ check_new_visibility(child, unused, new_vis, cur_vis)
157
+ elsif method_definition?(child)
158
+ unused = nil
159
+ elsif start_of_new_scope?(child)
160
+ check_scope(child)
161
+ elsif !child.defs_type?
162
+ cur_vis, unused = check_child_nodes(child, unused, cur_vis)
163
+ end
164
+ end
165
+
166
+ [cur_vis, unused]
167
+ end
168
+
169
+ def check_new_visibility(node, unused, new_vis, cur_vis)
170
+ # does this modifier just repeat the existing visibility?
171
+ if new_vis == cur_vis
172
+ add_offense(node, :expression, format(MSG, cur_vis))
173
+ else
174
+ # was the previous modifier never applied to any defs?
175
+ add_offense(unused, :expression, format(MSG, cur_vis)) if unused
176
+ # once we have already warned about a certain modifier, don't
177
+ # warn again even if it is never applied to any method defs
178
+ unused = node
179
+ end
180
+
181
+ [new_vis, unused]
182
+ end
183
+
184
+ def method_definition?(child)
185
+ static_method_definition?(child) ||
186
+ dynamic_method_definition?(child) ||
187
+ any_method_definition?(child)
188
+ end
189
+
190
+ def any_method_definition?(child)
191
+ cop_config.fetch('MethodCreatingMethods', []).any? do |m|
192
+ matcher_name = "#{m}_method?".to_sym
193
+ unless respond_to?(matcher_name)
194
+ self.class.def_node_matcher matcher_name, <<-PATTERN
195
+ {def (send nil :#{m} ...)}
196
+ PATTERN
197
+ end
198
+
199
+ send(matcher_name, child)
200
+ end
201
+ end
202
+
203
+ def start_of_new_scope?(child)
204
+ child.module_type? || child.class_type? ||
205
+ child.sclass_type? || eval_call?(child)
206
+ end
207
+
208
+ def eval_call?(child)
209
+ class_or_instance_eval?(child) ||
210
+ class_or_module_or_struct_new_call?(child) ||
211
+ any_context_creating_methods?(child)
212
+ end
213
+
214
+ def any_context_creating_methods?(child)
215
+ cop_config.fetch('ContextCreatingMethods', []).any? do |m|
216
+ matcher_name = "#{m}_block?".to_sym
217
+ unless respond_to?(matcher_name)
218
+ self.class.def_node_matcher matcher_name, <<-PATTERN
219
+ (block (send {nil const} {:#{m}} ...) ...)
220
+ PATTERN
221
+ end
222
+
223
+ send(matcher_name, child)
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
229
+ end