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,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for `private` or `protected` access modifiers which are
7
+ # applied to a singleton method. These access modifiers do not make
8
+ # singleton methods private/protected. `private_class_method` can be
9
+ # used for that.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ #
15
+ # class C
16
+ # private
17
+ #
18
+ # def self.method
19
+ # puts 'hi'
20
+ # end
21
+ # end
22
+ #
23
+ # @example
24
+ #
25
+ # # good
26
+ #
27
+ # class C
28
+ # def self.method
29
+ # puts 'hi'
30
+ # end
31
+ #
32
+ # private_class_method :method
33
+ # end
34
+ #
35
+ # @example
36
+ #
37
+ # # good
38
+ #
39
+ # class C
40
+ # class << self
41
+ # private
42
+ #
43
+ # def method
44
+ # puts 'hi'
45
+ # end
46
+ # end
47
+ # end
48
+ class IneffectiveAccessModifier < Cop
49
+ MSG = '`%s` (on line %d) does not make singleton methods %s. ' \
50
+ 'Use %s instead.'.freeze
51
+ ALTERNATIVE_PRIVATE = '`private_class_method` or `private` inside a ' \
52
+ '`class << self` block'.freeze
53
+ ALTERNATIVE_PROTECTED = '`protected` inside a `class << self` ' \
54
+ 'block'.freeze
55
+
56
+ def_node_matcher :access_modifier, <<-PATTERN
57
+ (send nil ${:public :protected :private})
58
+ PATTERN
59
+
60
+ def_node_matcher :private_class_method, <<-PATTERN
61
+ (send nil :private_class_method $...)
62
+ PATTERN
63
+
64
+ def on_class(node)
65
+ check_node(node.children[2]) # class body
66
+ end
67
+
68
+ def on_module(node)
69
+ check_node(node.children[1]) # module body
70
+ end
71
+
72
+ private
73
+
74
+ def clear
75
+ @useless = {}
76
+ @last_access_modifier = nil
77
+ end
78
+
79
+ def check_node(node)
80
+ return unless node && node.begin_type?
81
+
82
+ clear
83
+ check_scope(node)
84
+
85
+ @useless.each do |_name, (defs_node, visibility, modifier)|
86
+ add_offense(defs_node, :keyword,
87
+ format_message(visibility, modifier))
88
+ end
89
+ end
90
+
91
+ def format_message(visibility, modifier)
92
+ alternative = if visibility == :private
93
+ ALTERNATIVE_PRIVATE
94
+ else
95
+ ALTERNATIVE_PROTECTED
96
+ end
97
+ format(MSG, visibility, modifier.location.expression.line, visibility,
98
+ alternative)
99
+ end
100
+
101
+ def check_scope(node, cur_vis = :public)
102
+ node.children.reduce(cur_vis) do |visibility, child|
103
+ check_child_scope(child, visibility)
104
+ end
105
+ end
106
+
107
+ def check_child_scope(node, cur_vis)
108
+ if (new_vis = access_modifier(node))
109
+ cur_vis = change_visibility(node, new_vis)
110
+ elsif node.defs_type?
111
+ mark_method_as_useless(node, cur_vis) if cur_vis != :public
112
+ elsif (methods = private_class_method(node))
113
+ # don't warn about defs nodes which are followed by a call to
114
+ # `private_class_method :name`
115
+ # obviously the programmer knows what they are doing
116
+ revert_method_uselessness(methods)
117
+ elsif node.kwbegin_type?
118
+ cur_vis = check_scope(node, cur_vis)
119
+ end
120
+
121
+ cur_vis
122
+ end
123
+
124
+ def change_visibility(node, new_vis)
125
+ @last_access_modifier = node
126
+ new_vis
127
+ end
128
+
129
+ def mark_method_as_useless(node, cur_vis)
130
+ _, method_name, = *node
131
+ @useless[method_name] = [node, cur_vis, @last_access_modifier]
132
+ end
133
+
134
+ def revert_method_uselessness(methods)
135
+ methods.each do |sym|
136
+ next unless sym.sym_type?
137
+ @useless.delete(sym.children[0])
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop looks for error classes inheriting from `Exception`
7
+ # and its standard library subclasses, excluding subclasses of
8
+ # `StandardError`. It is configurable to suggest using either
9
+ # `RuntimeError` (default) or `StandardError` instead.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ #
15
+ # class C < Exception; end
16
+ #
17
+ # @example
18
+ #
19
+ # # EnforcedStyle: runtime_error (default)
20
+ #
21
+ # # good
22
+ #
23
+ # class C < RuntimeError; end
24
+ #
25
+ # @example
26
+ #
27
+ # # EnforcedStyle: standard_error
28
+ #
29
+ # # good
30
+ #
31
+ # class C < StandardError; end
32
+ class InheritException < Cop
33
+ include ConfigurableEnforcedStyle
34
+
35
+ MSG = 'Inherit from `%s` instead of `%s`.'.freeze
36
+ PREFERRED_BASE_CLASS = {
37
+ runtime_error: 'RuntimeError',
38
+ standard_error: 'StandardError'
39
+ }.freeze
40
+ ILLEGAL_CLASSES = %w[
41
+ Exception
42
+ SystemStackError
43
+ NoMemoryError
44
+ SecurityError
45
+ NotImplementedError
46
+ LoadError
47
+ SyntaxError
48
+ ScriptError
49
+ Interrupt
50
+ SignalException
51
+ SystemExit
52
+ ].freeze
53
+
54
+ def on_class(node)
55
+ _class, base_class, _body = *node
56
+
57
+ return if base_class.nil?
58
+
59
+ check(base_class)
60
+ end
61
+
62
+ private
63
+
64
+ def check(node)
65
+ return unless ILLEGAL_CLASSES.include?(node.const_name)
66
+
67
+ msg = format(MSG, preferred_base_class, node.const_name)
68
+ add_offense(node, :expression, msg)
69
+ end
70
+
71
+ def autocorrect(node)
72
+ lambda do |corrector|
73
+ corrector.replace(node.loc.expression, preferred_base_class)
74
+ end
75
+ end
76
+
77
+ def preferred_base_class
78
+ PREFERRED_BASE_CLASS[style]
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for invalid character literals with a non-escaped
7
+ # whitespace character (e.g. `? `).
8
+ # However, currently it's unclear whether there's a way to emit this
9
+ # warning without syntax errors.
10
+ #
11
+ # $ ruby -w
12
+ # p(? )
13
+ # -:1: warning: invalid character syntax; use ?\s
14
+ # -:1: syntax error, unexpected '?', expecting ')'
15
+ # p(? )
16
+ # ^
17
+ #
18
+ # @example
19
+ #
20
+ # # bad
21
+ #
22
+ # p(? )
23
+ class InvalidCharacterLiteral < Cop
24
+ include ParserDiagnostic
25
+
26
+ private
27
+
28
+ def relevant_diagnostic?(diagnostic)
29
+ diagnostic.reason == :invalid_escape_use
30
+ end
31
+
32
+ def alternative_message(diagnostic)
33
+ diagnostic
34
+ .message
35
+ .capitalize
36
+ .gsub('character syntax', 'character literal')
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for literals used as the conditions or as
7
+ # operands in and/or expressions serving as the conditions of
8
+ # if/while/until.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ #
14
+ # if 20
15
+ # do_something
16
+ # end
17
+ #
18
+ # @example
19
+ #
20
+ # # bad
21
+ #
22
+ # if some_var && true
23
+ # do_something
24
+ # end
25
+ #
26
+ # @example
27
+ #
28
+ # # good
29
+ #
30
+ # if some_var && some_condition
31
+ # do_something
32
+ # end
33
+ class LiteralInCondition < Cop
34
+ MSG = 'Literal `%s` appeared in a condition.'.freeze
35
+
36
+ def on_if(node)
37
+ check_for_literal(node)
38
+ end
39
+
40
+ def on_while(node)
41
+ check_for_literal(node)
42
+ end
43
+
44
+ def on_while_post(node)
45
+ check_for_literal(node)
46
+ end
47
+
48
+ def on_until(node)
49
+ check_for_literal(node)
50
+ end
51
+
52
+ def on_until_post(node)
53
+ check_for_literal(node)
54
+ end
55
+
56
+ def on_case(case_node)
57
+ if case_node.condition
58
+ check_case(case_node)
59
+ else
60
+ case_node.each_when do |when_node|
61
+ next unless when_node.conditions.all?(&:literal?)
62
+
63
+ add_offense(when_node, :expression)
64
+ end
65
+ end
66
+ end
67
+
68
+ def message(node)
69
+ format(MSG, node.source)
70
+ end
71
+
72
+ private
73
+
74
+ def check_for_literal(node)
75
+ if node.condition.literal?
76
+ add_offense(node.condition, :expression)
77
+ else
78
+ check_node(node.condition)
79
+ end
80
+ end
81
+
82
+ def basic_literal?(node)
83
+ if node.array_type?
84
+ primitive_array?(node)
85
+ else
86
+ node.basic_literal?
87
+ end
88
+ end
89
+
90
+ def primitive_array?(node)
91
+ node.children.all? { |n| basic_literal?(n) }
92
+ end
93
+
94
+ def check_node(node)
95
+ return unless node
96
+
97
+ if node.keyword_bang?
98
+ receiver, = *node
99
+
100
+ handle_node(receiver)
101
+ elsif LOGICAL_OPERATOR_NODES.include?(node.type)
102
+ node.each_child_node { |op| handle_node(op) }
103
+ elsif node.begin_type? && node.children.one?
104
+ handle_node(node.children.first)
105
+ end
106
+ end
107
+
108
+ def handle_node(node)
109
+ if node.literal?
110
+ add_offense(node, :expression)
111
+ elsif %i[send and or begin].include?(node.type)
112
+ check_node(node)
113
+ end
114
+ end
115
+
116
+ def check_case(case_node)
117
+ condition = case_node.condition
118
+
119
+ return if condition.array_type? && !primitive_array?(condition)
120
+ return if condition.dstr_type?
121
+
122
+ handle_node(condition)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Lint
6
+ # This cop checks for interpolated literals.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # "result is #{10}"
13
+ #
14
+ # @example
15
+ #
16
+ # # good
17
+ #
18
+ # "result is 10"
19
+ class LiteralInInterpolation < Cop
20
+ MSG = 'Literal interpolation detected.'.freeze
21
+ COMPOSITE = %i[array hash pair irange erange].freeze
22
+
23
+ def on_dstr(node)
24
+ node.each_child_node(:begin) do |begin_node|
25
+ final_node = begin_node.children.last
26
+ next unless final_node
27
+ next if special_keyword?(final_node)
28
+ next unless prints_as_self?(final_node)
29
+
30
+ add_offense(final_node, :expression)
31
+ end
32
+ end
33
+
34
+ def autocorrect(node)
35
+ return if node.dstr_type? # nested, fixed in next iteration
36
+
37
+ value = autocorrected_value(node)
38
+ ->(corrector) { corrector.replace(node.parent.source_range, value) }
39
+ end
40
+
41
+ private
42
+
43
+ def special_keyword?(node)
44
+ # handle strings like __FILE__
45
+ (node.str_type? && !node.loc.respond_to?(:begin)) ||
46
+ node.source_range.is?('__LINE__')
47
+ end
48
+
49
+ def autocorrected_value(node)
50
+ case node.type
51
+ when :str
52
+ node.children.last
53
+ when :sym
54
+ autocorrected_value_for_symbol(node)
55
+ else
56
+ node.source.gsub('"', '\"')
57
+ end
58
+ end
59
+
60
+ def autocorrected_value_for_symbol(node)
61
+ end_pos =
62
+ node.loc.end ? node.loc.end.begin_pos : node.loc.expression.end_pos
63
+
64
+ range_between(node.loc.begin.end_pos, end_pos).source
65
+ end
66
+
67
+ # Does node print its own source when converted to a string?
68
+ def prints_as_self?(node)
69
+ node.basic_literal? ||
70
+ (COMPOSITE.include?(node.type) &&
71
+ node.children.all? { |child| prints_as_self?(child) })
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end