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,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # A node extension for `kwsplat` nodes. This will be used in place of a
6
+ # plain node when the builder constructs the AST, making its methods
7
+ # available to all `kwsplat` nodes within RubbyCop.
8
+ class KeywordSplatNode < Node
9
+ include HashElementNode
10
+
11
+ DOUBLE_SPLAT = '**'.freeze
12
+
13
+ # This is used for duck typing with `pair` nodes which also appear as
14
+ # `hash` elements.
15
+ #
16
+ # @return [false]
17
+ def hash_rocket?
18
+ false
19
+ end
20
+
21
+ # This is used for duck typing with `pair` nodes which also appear as
22
+ # `hash` elements.
23
+ #
24
+ # @return [false]
25
+ def colon?
26
+ false
27
+ end
28
+
29
+ # Returns the operator for the `kwsplat` as a string.
30
+ #
31
+ # @return [String] the double splat operator
32
+ def operator
33
+ DOUBLE_SPLAT
34
+ end
35
+
36
+ # Custom destructuring method. This is used to normalize the branches
37
+ # for `pair` and `kwsplat` nodes, to add duck typing to `hash` elements.
38
+ #
39
+ # @return [Array<KeywordSplatNode>] the different parts of the `kwsplat`
40
+ def node_parts
41
+ [self, self]
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # Common functionality for nodes that are binary operations:
6
+ # `or`, `and` ...
7
+ module BinaryOperatorNode
8
+ # Returns the left hand side node of the binary operation.
9
+ #
10
+ # @return [Node] the left hand side of the binary operation
11
+ def lhs
12
+ node_parts[0]
13
+ end
14
+
15
+ # Returns the right hand side node of the binary operation.
16
+ #
17
+ # @return [Node] the right hand side of the binary operation
18
+ def rhs
19
+ node_parts[1]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # Common functionality for nodes that have conditions:
6
+ # `if`, `while`, `until`, `case`.
7
+ # This currently doesn't include `when` nodes, because they have multiple
8
+ # conditions, and need to be checked for that.
9
+ module ConditionalNode
10
+ # Checks whether the condition of the node is written on a single line.
11
+ #
12
+ # @return [Boolean] whether the condition is on a single line
13
+ def single_line_condition?
14
+ loc.keyword.line == condition.source_range.line
15
+ end
16
+
17
+ # Checks whether the condition of the node is written on more than
18
+ # one line.
19
+ #
20
+ # @return [Boolean] whether the condition is on more than one line
21
+ def multiline_condition?
22
+ !single_line_condition?
23
+ end
24
+
25
+ # Returns the condition of the node. This works together with each node's
26
+ # custom destructuring method to select the correct part of the node.
27
+ #
28
+ # @return [Node, nil] the condition of the node
29
+ def condition
30
+ node_parts[0]
31
+ end
32
+
33
+ # Returns the body associated with the condition. This works together with
34
+ # each node's custom destructuring method to select the correct part of
35
+ # the node.
36
+ #
37
+ # @note For `if` nodes, this is the truthy branch.
38
+ #
39
+ # @return [Node, nil] the body of the node
40
+ def body
41
+ node_parts[1]
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # Common functionality for nodes that can be used as hash elements:
6
+ # `pair`, `kwsplat`
7
+ module HashElementNode
8
+ # Returns the key of this `hash` element.
9
+ #
10
+ # @note For keyword splats, this returns the whole node
11
+ #
12
+ # @return [Node] the key of the hash element
13
+ def key
14
+ node_parts[0]
15
+ end
16
+
17
+ # Returns the value of this `hash` element.
18
+ #
19
+ # @note For keyword splats, this returns the whole node
20
+ #
21
+ # @return [Node] the value of the hash element
22
+ def value
23
+ node_parts[1]
24
+ end
25
+
26
+ # Checks whether this `hash` element is on the same line as `other`.
27
+ #
28
+ # @note A multiline element is considered to be on the same line if it
29
+ # shares any of its lines with `other`
30
+ #
31
+ # @return [Boolean] whether this element is on the same line as `other`
32
+ def same_line?(other)
33
+ loc.last_line == other.loc.line || loc.line == other.loc.last_line
34
+ end
35
+
36
+ # Returns the delta between this pair's key and the argument pair's.
37
+ #
38
+ # @note Keys on the same line always return a delta of 0
39
+ # @note Keyword splats always return a delta of 0 for right alignment
40
+ #
41
+ # @param [Symbol] alignment whether to check the left or right side
42
+ # @return [Integer] the delta between the two keys
43
+ def key_delta(other, alignment = :left)
44
+ HashElementDelta.new(self, other).key_delta(alignment)
45
+ end
46
+
47
+ # Returns the delta between this element's value and the argument's.
48
+ #
49
+ # @note Keyword splats always return a delta of 0
50
+ #
51
+ # @return [Integer] the delta between the two values
52
+ def value_delta(other)
53
+ HashElementDelta.new(self, other).value_delta
54
+ end
55
+
56
+ # Returns the delta between this element's delimiter and the argument's.
57
+ #
58
+ # @note Pairs with different delimiter styles return a delta of 0
59
+ #
60
+ # @return [Integer] the delta between the two delimiters
61
+ def delimiter_delta(other)
62
+ HashElementDelta.new(self, other).delimiter_delta
63
+ end
64
+
65
+ # A helper class for comparing the positions of different parts of a
66
+ # `pair` node.
67
+ class HashElementDelta
68
+ def initialize(first, second)
69
+ @first = first
70
+ @second = second
71
+
72
+ raise ArgumentError unless valid_argument_types?
73
+ end
74
+
75
+ def key_delta(alignment = :left)
76
+ return 0 if first.same_line?(second)
77
+ return 0 if keyword_splat? && alignment == :right
78
+
79
+ delta(first.key.loc, second.key.loc, alignment)
80
+ end
81
+
82
+ def value_delta
83
+ return 0 if first.same_line?(second)
84
+ return 0 if keyword_splat?
85
+
86
+ delta(first.value.loc, second.value.loc)
87
+ end
88
+
89
+ def delimiter_delta
90
+ return 0 if first.same_line?(second)
91
+ return 0 if first.delimiter != second.delimiter
92
+
93
+ delta(first.loc.operator, second.loc.operator)
94
+ end
95
+
96
+ private
97
+
98
+ attr_reader :first, :second
99
+
100
+ def valid_argument_types?
101
+ [first, second].all? do |argument|
102
+ argument.pair_type? || argument.kwsplat_type?
103
+ end
104
+ end
105
+
106
+ def delta(first, second, alignment = :left)
107
+ case alignment
108
+ when :left
109
+ first.column - second.column
110
+ when :right
111
+ first.last_column - second.last_column
112
+ else
113
+ 0
114
+ end
115
+ end
116
+
117
+ def keyword_splat?
118
+ [first, second].any?(&:kwsplat_type?)
119
+ end
120
+ end
121
+
122
+ private_constant :HashElementDelta
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # Common functionality for nodes that can be used as modifiers:
6
+ # `if`, `while`, `until`
7
+ module ModifierNode
8
+ # Checks whether the node is in a modifier form, i.e. a condition
9
+ # trailing behind an expression.
10
+ #
11
+ # @return [Boolean] whether the node is a modifier
12
+ def modifier_form?
13
+ loc.end.nil?
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # Common functionality for nodes that are predicates:
6
+ # `or`, `and` ...
7
+ module PredicateOperatorNode
8
+ LOGICAL_AND = '&&'.freeze
9
+ SEMANTIC_AND = 'and'.freeze
10
+ LOGICAL_OR = '||'.freeze
11
+ SEMANTIC_OR = 'or'.freeze
12
+
13
+ # Returns the operator as a string.
14
+ #
15
+ # @return [String] the operator
16
+ def operator
17
+ loc.operator.source
18
+ end
19
+
20
+ # Checks whether this is a logical operator.
21
+ #
22
+ # @return [Boolean] whether this is a logical operator
23
+ def logical_operator?
24
+ operator == LOGICAL_AND || operator == LOGICAL_OR
25
+ end
26
+
27
+ # Checks whether this is a semantic operator.
28
+ #
29
+ # @return [Boolean] whether this is a semantic operator
30
+ def semantic_operator?
31
+ operator == SEMANTIC_AND || operator == SEMANTIC_OR
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # A node extension for `or` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `or` nodes within RubbyCop.
8
+ class OrNode < Node
9
+ include BinaryOperatorNode
10
+ include PredicateOperatorNode
11
+
12
+ # Returns the alternate operator of the `or` as a string.
13
+ # Returns `or` for `||` and vice versa.
14
+ #
15
+ # @return [String] the alternate of the `or` operator
16
+ def alternate_operator
17
+ logical_operator? ? SEMANTIC_OR : LOGICAL_OR
18
+ end
19
+
20
+ # Returns the inverse keyword of the `or` node as a string.
21
+ # Returns `and` for `or` and `&&` for `||`.
22
+ #
23
+ # @return [String] the inverse of the `or` operator
24
+ def inverse_operator
25
+ logical_operator? ? LOGICAL_AND : SEMANTIC_AND
26
+ end
27
+
28
+ # Custom destructuring method. This can be used to normalize
29
+ # destructuring for different variations of the node.
30
+ #
31
+ # @return [Array<Node>] the different parts of the `or` predicate
32
+ def node_parts
33
+ to_a
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # A node extension for `pair` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `pair` nodes within RubbyCop.
8
+ class PairNode < Node
9
+ include HashElementNode
10
+
11
+ HASH_ROCKET = '=>'.freeze
12
+ SPACED_HASH_ROCKET = ' => '.freeze
13
+ COLON = ':'.freeze
14
+ SPACED_COLON = ': '.freeze
15
+
16
+ # Checks whether the `pair` uses a hash rocket delimiter.
17
+ #
18
+ # @return [Boolean] whether this `pair` uses a hash rocket delimiter
19
+ def hash_rocket?
20
+ loc.operator.is?(HASH_ROCKET)
21
+ end
22
+
23
+ # Checks whether the `pair` uses a colon delimiter.
24
+ #
25
+ # @return [Boolean] whether this `pair` uses a colon delimiter
26
+ def colon?
27
+ loc.operator.is?(COLON)
28
+ end
29
+
30
+ # Returns the delimiter of the `pair` as a string. Returns `=>` for a
31
+ # colon delimited `pair`, and `:` for a hash rocket delimited `pair`.
32
+ #
33
+ # @param [Boolean] with_spacing whether to include spacing
34
+ # @return [String] the delimiter of the `pair`
35
+ def delimiter(with_spacing = false)
36
+ if with_spacing
37
+ hash_rocket? ? SPACED_HASH_ROCKET : SPACED_COLON
38
+ else
39
+ hash_rocket? ? HASH_ROCKET : COLON
40
+ end
41
+ end
42
+
43
+ # Returns the inverse delimiter of the `pair` as a string.
44
+ #
45
+ # @param [Boolean] with_spacing whether to include spacing
46
+ # @return [String] the inverse delimiter of the `pair`
47
+ def inverse_delimiter(with_spacing = false)
48
+ if with_spacing
49
+ hash_rocket? ? SPACED_COLON : SPACED_HASH_ROCKET
50
+ else
51
+ hash_rocket? ? COLON : HASH_ROCKET
52
+ end
53
+ end
54
+
55
+ # Custom destructuring method. This is used to normalize the branches
56
+ # for `pair` and `kwsplat` nodes, to add duck typing to `hash` elements.
57
+ #
58
+ # @return [Array<Node>] the different parts of the `pair`
59
+ def node_parts
60
+ to_a
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # A node extension for `resbody` nodes. This will be used in place of a
6
+ # plain node when the builder constructs the AST, making its methods
7
+ # available to all `resbody` nodes within RubbyCop.
8
+ class ResbodyNode < Node
9
+ # Returns the body of the `rescue` clause.
10
+ #
11
+ # @return [Node, nil] The body of the `resbody`.
12
+ def body
13
+ node_parts[2]
14
+ end
15
+
16
+ # Custom destructuring method. This can be used to normalize
17
+ # destructuring for different variations of the node.
18
+ #
19
+ # @return [Array<Node>] the different parts of the `resbody` statement
20
+ def node_parts
21
+ to_a
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,209 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module AST
5
+ # A node extension for `send` nodes. This will be used in place of a plain
6
+ # node when the builder constructs the AST, making its methods available
7
+ # to all `send` nodes within RubbyCop.
8
+ class SendNode < Node
9
+ # The receiving node of the method invocation.
10
+ #
11
+ # @return [Node, nil] the receiver of the invoked method or `nil`
12
+ def receiver
13
+ node_parts[0]
14
+ end
15
+
16
+ # The name of the invoked method called as a string.
17
+ #
18
+ # @return [Symbol] the name of the invoked method
19
+ def method_name
20
+ node_parts[1]
21
+ end
22
+
23
+ # Checks whether the method name matches the argument.
24
+ #
25
+ # @param [Symbol, String] name the method name to check for
26
+ # @return [Boolean] whether the method name matches the argument
27
+ def method?(name)
28
+ method_name == name.to_sym
29
+ end
30
+
31
+ # Checks whether the method is a macro method. A macro method is defined
32
+ # as a method that sits in a class- or module body and has an implicit
33
+ # receiver.
34
+ #
35
+ # @note This does not include DSLs that use nested blocks, like RSpec
36
+ #
37
+ # @return [Boolean] whether the method is a macro method
38
+ def macro?
39
+ !receiver && macro_scope?
40
+ end
41
+
42
+ # Checks whether the method name matches the argument and has an
43
+ # implicit receiver.
44
+ #
45
+ # @param [Symbol, String] name the method name to check for
46
+ # @return [Boolean] whether the method name matches the argument
47
+ def command?(name)
48
+ !receiver && method?(name)
49
+ end
50
+
51
+ # An array containing the arguments of the method invocation.
52
+ #
53
+ # @return [Array<Node>] the arguments of the method invocation or `nil`
54
+ def arguments
55
+ node_parts[2..-1]
56
+ end
57
+
58
+ # A shorthand for getting the first argument of the method invocation.
59
+ # Equivalent to `arguments.first`.
60
+ #
61
+ # @return [Node, nil] the first argument of the method invocation,
62
+ # or `nil` if there are no arguments
63
+ def first_argument
64
+ arguments[0]
65
+ end
66
+
67
+ # A shorthand for getting the last argument of the method invocation.
68
+ # Equivalent to `arguments.last`.
69
+ #
70
+ # @return [Node, nil] the last argument of the method invocation,
71
+ # or `nil` if there are no arguments
72
+ def last_argument
73
+ arguments[-1]
74
+ end
75
+
76
+ # Checks whether this method was invoked with arguments.
77
+ #
78
+ # @return [Boolean] whether this method was invoked with arguments
79
+ def arguments?
80
+ !arguments.empty?
81
+ end
82
+
83
+ # Checks whether this method invocation's arguments are wrapped in
84
+ # parentheses.
85
+ #
86
+ # @return [Boolean] whether this method invocation's arguments are
87
+ # wrapped in parentheses
88
+ def parenthesized?
89
+ loc.end && loc.end.is?(')')
90
+ end
91
+
92
+ # Checks whether the invoked method is a setter method.
93
+ #
94
+ # @return [Boolean] whether the invoked method is a setter
95
+ def setter_method?
96
+ loc.operator
97
+ end
98
+
99
+ # Checks whether the invoked method is an operator method.
100
+ #
101
+ # @return [Boolean] whether the invoked method is an operator
102
+ def operator_method?
103
+ RubbyCop::Cop::Util::OPERATOR_METHODS.include?(method_name)
104
+ end
105
+
106
+ # Checks whether the invoked method is a comparison method.
107
+ #
108
+ # @return [Boolean] whether the involed method is a comparison
109
+ def comparison_method?
110
+ COMPARISON_OPERATORS.include?(method_name)
111
+ end
112
+
113
+ # Checks whether the invoked method is an assignment method.
114
+ #
115
+ # @return [Boolean] whether the invoked method is an assignment.
116
+ def assignment_method?
117
+ !comparison_method? && method_name.to_s.end_with?('=')
118
+ end
119
+
120
+ # Checks whether the method call uses a dot to connect the receiver and
121
+ # the method name.
122
+ #
123
+ # This is useful for comparison operators, which can be called either
124
+ # with or without a dot, i.e. `foo == bar` or `foo.== bar`.
125
+ #
126
+ # @return [Boolean] whether the method was called with a connecting dot
127
+ def dot?
128
+ loc.dot && loc.dot.is?('.')
129
+ end
130
+
131
+ # Checks whether the method call uses a double colon to connect the
132
+ # receiver and the method name.
133
+ #
134
+ # @return [Boolean] whether the method was called with a connecting dot
135
+ def double_colon?
136
+ loc.dot && loc.dot.is?('::')
137
+ end
138
+
139
+ # Checks whether the receiver of this method invocation is `self`.
140
+ #
141
+ # @return [Boolean] whether the receiver of this method invocation
142
+ # is `self`
143
+ def self_receiver?
144
+ receiver && receiver.self_type?
145
+ end
146
+
147
+ # Checks whether the method call is of the implicit form of `#call`,
148
+ # e.g. `foo.(bar)`.
149
+ #
150
+ # @return [Boolean] whether the method is an implicit form of `#call`
151
+ def implicit_call?
152
+ method_name == :call && !loc.selector
153
+ end
154
+
155
+ # Checks whether the invoked method is a predicate method.
156
+ #
157
+ # @return [Boolean] whether the invoked method is a predicate method
158
+ def predicate_method?
159
+ method_name.to_s.end_with?('?')
160
+ end
161
+
162
+ # Checks whether the invoked method is a bang method.
163
+ #
164
+ # @return [Boolean] whether the invoked method is a bang method
165
+ def bang_method?
166
+ method_name.to_s.end_with?('!')
167
+ end
168
+
169
+ # Checks whether the invoked method is a camel case method,
170
+ # e.g. `Integer()`.
171
+ #
172
+ # @return [Boolean] whether the invoked method is a camel case method
173
+ def camel_case_method?
174
+ method_name.to_s =~ /\A[A-Z]/
175
+ end
176
+
177
+ # Whether the last argument of the method invocation is a block pass,
178
+ # i.e. `&block`.
179
+ #
180
+ # @return [Boolean] whether the invoked method is a block pass
181
+ def block_argument?
182
+ arguments? && last_argument.block_pass_type?
183
+ end
184
+
185
+ # Checks whether any argument of the method invocation is a splat
186
+ # argument, i.e. `*splat`.
187
+ #
188
+ # @return [Boolean] whether the invoked method is a splat argument
189
+ def splat_argument?
190
+ arguments? && arguments.any?(&:splat_type?)
191
+ end
192
+
193
+ # Custom destructuring method. This can be used to normalize
194
+ # destructuring for different variations of the node.
195
+ #
196
+ # @return [Array] the different parts of the `send` node
197
+ def node_parts
198
+ to_a
199
+ end
200
+
201
+ private
202
+
203
+ def_matcher :macro_scope?, <<-PATTERN
204
+ {^({class module} ...)
205
+ ^^({class module} ... (begin ...))}
206
+ PATTERN
207
+ end
208
+ end
209
+ end