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,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Layout
6
+ # This cop checks whether the multiline assignments have a newline
7
+ # after the assignment operator.
8
+ #
9
+ # @example
10
+ # # bad (with EnforcedStyle set to new_line)
11
+ # foo = if expression
12
+ # 'bar'
13
+ # end
14
+ #
15
+ # # good (with EnforcedStyle set to same_line)
16
+ # foo = if expression
17
+ # 'bar'
18
+ # end
19
+ #
20
+ # # good (with EnforcedStyle set to new_line)
21
+ # foo =
22
+ # if expression
23
+ # 'bar'
24
+ # end
25
+ #
26
+ # # good (with EnforcedStyle set to new_line)
27
+ # foo =
28
+ # begin
29
+ # compute
30
+ # rescue => e
31
+ # nil
32
+ # end
33
+ class MultilineAssignmentLayout < Cop
34
+ include CheckAssignment
35
+ include ConfigurableEnforcedStyle
36
+
37
+ NEW_LINE_OFFENSE = 'Right hand side of multi-line assignment is on ' \
38
+ 'the same line as the assignment operator `=`.'.freeze
39
+
40
+ SAME_LINE_OFFENSE = 'Right hand side of multi-line assignment is not ' \
41
+ 'on the same line as the assignment operator `=`.'.freeze
42
+
43
+ def check_assignment(node, rhs)
44
+ return unless rhs
45
+ return unless supported_types.include?(rhs.type)
46
+ return if rhs.loc.first_line == rhs.loc.last_line
47
+
48
+ case style
49
+ when :new_line
50
+ check_new_line_offense(node, rhs)
51
+ when :same_line
52
+ check_same_line_offense(node, rhs)
53
+ end
54
+ end
55
+
56
+ def check_new_line_offense(node, rhs)
57
+ return unless node.loc.operator.line == rhs.loc.line
58
+
59
+ add_offense(node, :expression, NEW_LINE_OFFENSE)
60
+ end
61
+
62
+ def check_same_line_offense(node, rhs)
63
+ return unless node.loc.operator.line != rhs.loc.line
64
+
65
+ add_offense(node, :expression, SAME_LINE_OFFENSE)
66
+ end
67
+
68
+ def autocorrect(node)
69
+ case style
70
+ when :new_line
71
+ ->(corrector) { corrector.insert_after(node.loc.operator, "\n") }
72
+ when :same_line
73
+ range = range_between(node.loc.operator.end_pos,
74
+ extract_rhs(node).source_range.begin_pos)
75
+
76
+ ->(corrector) { corrector.replace(range, ' ') }
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def supported_types
83
+ @supported_types ||= cop_config['SupportedTypes'].map(&:to_sym)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Layout
6
+ # This cop checks whether the multiline do end blocks have a newline
7
+ # after the start of the block. Additionally, it checks whether the block
8
+ # arguments, if any, are on the same line as the start of the block.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # blah do |i| foo(i)
13
+ # bar(i)
14
+ # end
15
+ #
16
+ # # bad
17
+ # blah do
18
+ # |i| foo(i)
19
+ # bar(i)
20
+ # end
21
+ #
22
+ # # good
23
+ # blah do |i|
24
+ # foo(i)
25
+ # bar(i)
26
+ # end
27
+ #
28
+ # # bad
29
+ # blah { |i| foo(i)
30
+ # bar(i)
31
+ # }
32
+ #
33
+ # # good
34
+ # blah { |i|
35
+ # foo(i)
36
+ # bar(i)
37
+ # }
38
+ class MultilineBlockLayout < Cop
39
+ MSG = 'Block body expression is on the same line as ' \
40
+ 'the block start.'.freeze
41
+ ARG_MSG = 'Block argument expression is not on the same line as the ' \
42
+ 'block start.'.freeze
43
+
44
+ def on_block(node)
45
+ return if oneliner?(node)
46
+
47
+ # A block node has three children: the block start,
48
+ # the arguments, and the expression. We care if the block start
49
+ # with arguments and the expression start on the same line.
50
+ _block_start, args, last_expression = node.children
51
+ do_loc = node.loc.begin # Actually it's either do or {.
52
+
53
+ if args_on_different_line?(do_loc.line, args)
54
+ add_offense_for_expression(node, args, ARG_MSG)
55
+ end
56
+
57
+ return unless last_expression
58
+ expression_loc = last_expression.loc
59
+ return unless do_loc.line == expression_loc.line
60
+ add_offense_for_expression(node, last_expression, MSG)
61
+ end
62
+
63
+ def oneliner?(node)
64
+ node.loc.begin.line == node.loc.end.line
65
+ end
66
+
67
+ def args_on_different_line?(do_line, args)
68
+ return false if args.children.empty?
69
+
70
+ do_line != args.loc.last_line
71
+ end
72
+
73
+ def add_offense_for_expression(node, expr, msg)
74
+ expression = expr.source_range
75
+ range = range_between(expression.begin_pos, expression.end_pos)
76
+
77
+ add_offense(node, range, msg)
78
+ end
79
+
80
+ def autocorrect(node)
81
+ lambda do |corrector|
82
+ _method, args, block_body = *node
83
+ unless arguments_on_different_line?(node, args)
84
+ autocorrect_arguments(corrector, node, args)
85
+ expr_before_body = args.source_range.end
86
+ end
87
+
88
+ return unless block_body
89
+
90
+ expr_before_body ||= node.loc.begin
91
+ if expr_before_body.line == block_body.loc.line
92
+ autocorrect_body(corrector, node, block_body)
93
+ end
94
+ end
95
+ end
96
+
97
+ def arguments_on_different_line?(node, args)
98
+ args.children.empty? || args.loc.last_line == node.loc.line
99
+ end
100
+
101
+ def autocorrect_arguments(corrector, node, args)
102
+ end_pos =
103
+ range_with_surrounding_space(args.source_range, :right, false)
104
+ .end_pos
105
+ range = range_between(node.loc.begin.end.begin_pos, end_pos)
106
+ corrector.replace(range, " |#{block_arg_string(args)}|")
107
+ end
108
+
109
+ def autocorrect_body(corrector, node, block_body)
110
+ first_node = if block_body.begin_type?
111
+ block_body.children.first
112
+ else
113
+ block_body
114
+ end
115
+
116
+ block_start_col = node.source_range.column
117
+
118
+ corrector.insert_before(first_node.source_range,
119
+ "\n #{' ' * block_start_col}")
120
+ end
121
+
122
+ def block_arg_string(args)
123
+ args.children.map do |arg|
124
+ if arg.mlhs_type?
125
+ "(#{block_arg_string(arg)})"
126
+ else
127
+ arg.source
128
+ end
129
+ end.join(', ')
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Layout
6
+ # This cop checks that the closing brace in a hash literal is either
7
+ # on the same line as the last hash element, or a new line.
8
+ #
9
+ # When using the `symmetrical` (default) style:
10
+ #
11
+ # If a hash's opening brace is on the same line as the first element
12
+ # of the hash, then the closing brace should be on the same line as
13
+ # the last element of the hash.
14
+ #
15
+ # If a hash's opening brace is on the line above the first element
16
+ # of the hash, then the closing brace should be on the line below
17
+ # the last element of the hash.
18
+ #
19
+ # When using the `new_line` style:
20
+ #
21
+ # The closing brace of a multi-line hash literal must be on the line
22
+ # after the last element of the hash.
23
+ #
24
+ # When using the `same_line` style:
25
+ #
26
+ # The closing brace of a multi-line hash literal must be on the same
27
+ # line as the last element of the hash.
28
+ #
29
+ # @example
30
+ #
31
+ # # symmetrical: bad
32
+ # # new_line: good
33
+ # # same_line: bad
34
+ # { a: 1,
35
+ # b: 2
36
+ # }
37
+ #
38
+ # # symmetrical: bad
39
+ # # new_line: bad
40
+ # # same_line: good
41
+ # {
42
+ # a: 1,
43
+ # b: 2 }
44
+ #
45
+ # # symmetrical: good
46
+ # # new_line: bad
47
+ # # same_line: good
48
+ # { a: 1,
49
+ # b: 2 }
50
+ #
51
+ # # symmetrical: good
52
+ # # new_line: good
53
+ # # same_line: bad
54
+ # {
55
+ # a: 1,
56
+ # b: 2
57
+ # }
58
+ class MultilineHashBraceLayout < Cop
59
+ include MultilineLiteralBraceLayout
60
+
61
+ SAME_LINE_MESSAGE = 'Closing hash brace must be on the same line as ' \
62
+ 'the last hash element when opening brace is on the same line as ' \
63
+ 'the first hash element.'.freeze
64
+
65
+ NEW_LINE_MESSAGE = 'Closing hash brace must be on the line after ' \
66
+ 'the last hash element when opening brace is on a separate line ' \
67
+ 'from the first hash element.'.freeze
68
+
69
+ ALWAYS_NEW_LINE_MESSAGE = 'Closing hash brace must be on the line ' \
70
+ 'after the last hash element.'.freeze
71
+
72
+ ALWAYS_SAME_LINE_MESSAGE = 'Closing hash brace must be on the same ' \
73
+ 'line as the last hash element.'.freeze
74
+
75
+ def on_hash(node)
76
+ check_brace_layout(node)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Layout
6
+ # This cop checks that the closing brace in a method call is either
7
+ # on the same line as the last method argument, or a new line.
8
+ #
9
+ # When using the `symmetrical` (default) style:
10
+ #
11
+ # If a method call's opening brace is on the same line as the first
12
+ # argument of the call, then the closing brace should be on the same
13
+ # line as the last argument of the call.
14
+ #
15
+ # If an method call's opening brace is on the line above the first
16
+ # argument of the call, then the closing brace should be on the line
17
+ # below the last argument of the call.
18
+ #
19
+ # When using the `new_line` style:
20
+ #
21
+ # The closing brace of a multi-line method call must be on the line
22
+ # after the last argument of the call.
23
+ #
24
+ # When using the `same_line` style:
25
+ #
26
+ # The closing brace of a multi-line method call must be on the same
27
+ # line as the last argument of the call.
28
+ #
29
+ # @example
30
+ #
31
+ # # symmetrical: bad
32
+ # # new_line: good
33
+ # # same_line: bad
34
+ # foo(a,
35
+ # b
36
+ # )
37
+ #
38
+ # # symmetrical: bad
39
+ # # new_line: bad
40
+ # # same_line: good
41
+ # foo(
42
+ # a,
43
+ # b)
44
+ #
45
+ # # symmetrical: good
46
+ # # new_line: bad
47
+ # # same_line: good
48
+ # foo(a,
49
+ # b)
50
+ #
51
+ # # symmetrical: good
52
+ # # new_line: good
53
+ # # same_line: bad
54
+ # foo(
55
+ # a,
56
+ # b
57
+ # )
58
+ class MultilineMethodCallBraceLayout < Cop
59
+ include MultilineLiteralBraceLayout
60
+
61
+ SAME_LINE_MESSAGE = 'Closing method call brace must be on the ' \
62
+ 'same line as the last argument when opening brace is on the same ' \
63
+ 'line as the first argument.'.freeze
64
+
65
+ NEW_LINE_MESSAGE = 'Closing method call brace must be on the ' \
66
+ 'line after the last argument when opening brace is on a separate ' \
67
+ 'line from the first argument.'.freeze
68
+
69
+ ALWAYS_NEW_LINE_MESSAGE = 'Closing method call brace must be on ' \
70
+ 'the line after the last argument.'.freeze
71
+
72
+ ALWAYS_SAME_LINE_MESSAGE = 'Closing method call brace must be on ' \
73
+ 'the same line as the last argument.'.freeze
74
+
75
+ def on_send(node)
76
+ check_brace_layout(node)
77
+ end
78
+
79
+ private
80
+
81
+ def children(node)
82
+ node.arguments
83
+ end
84
+
85
+ def ignored_literal?(node)
86
+ single_line_ignoring_receiver?(node) || super
87
+ end
88
+
89
+ def single_line_ignoring_receiver?(node)
90
+ return false unless node.loc.begin && node.loc.end
91
+
92
+ node.loc.begin.line == node.loc.end.line
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,215 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubbyCop
4
+ module Cop
5
+ module Layout
6
+ # This cop checks the indentation of the method name part in method calls
7
+ # that span more than one line.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # while myvariable
12
+ # .b
13
+ # # do something
14
+ # end
15
+ #
16
+ # # good, EnforcedStyle: aligned
17
+ # while myvariable
18
+ # .b
19
+ # # do something
20
+ # end
21
+ #
22
+ # # good, EnforcedStyle: aligned
23
+ # Thing.a
24
+ # .b
25
+ # .c
26
+ #
27
+ # # good, EnforcedStyle: indented,
28
+ # IndentationWidth: 2
29
+ # while myvariable
30
+ # .b
31
+ #
32
+ # # do something
33
+ # end
34
+ #
35
+ # # good, EnforcedStyle: indented_relative_to_receiver,
36
+ # IndentationWidth: 2
37
+ # while myvariable
38
+ # .a
39
+ # .b
40
+ #
41
+ # # do something
42
+ # end
43
+ #
44
+ # # good, EnforcedStyle: indented_relative_to_receiver,
45
+ # IndentationWidth: 2
46
+ # myvariable = Thing
47
+ # .a
48
+ # .b
49
+ # .c
50
+ class MultilineMethodCallIndentation < Cop
51
+ include ConfigurableEnforcedStyle
52
+ include AutocorrectAlignment
53
+ include MultilineExpressionIndentation
54
+
55
+ def validate_config
56
+ return unless style == :aligned && cop_config['IndentationWidth']
57
+
58
+ raise ValidationError,
59
+ 'The `Layout/MultilineMethodCallIndentation`' \
60
+ ' cop only accepts an `IndentationWidth` ' \
61
+ 'configuration parameter when ' \
62
+ '`EnforcedStyle` is `indented`.'
63
+ end
64
+
65
+ private
66
+
67
+ def relevant_node?(send_node)
68
+ send_node.loc.dot # Only check method calls with dot operator
69
+ end
70
+
71
+ def offending_range(node, lhs, rhs, given_style)
72
+ return false unless begins_its_line?(rhs)
73
+ return false if not_for_this_cop?(node)
74
+
75
+ @base = alignment_base(node, rhs, given_style)
76
+ correct_column = if @base
77
+ @base.column + extra_indentation(given_style)
78
+ else
79
+ indentation(lhs) + correct_indentation(node)
80
+ end
81
+ @column_delta = correct_column - rhs.column
82
+ rhs if @column_delta.nonzero?
83
+ end
84
+
85
+ def extra_indentation(given_style)
86
+ if given_style == :indented_relative_to_receiver
87
+ configured_indentation_width
88
+ else
89
+ 0
90
+ end
91
+ end
92
+
93
+ def message(node, lhs, rhs)
94
+ if should_indent_relative_to_receiver?
95
+ relative_to_receiver_message(rhs)
96
+ elsif should_align_with_base?
97
+ align_with_base_message(rhs)
98
+ else
99
+ no_base_message(lhs, rhs, node)
100
+ end
101
+ end
102
+
103
+ def should_indent_relative_to_receiver?
104
+ @base && style == :indented_relative_to_receiver
105
+ end
106
+
107
+ def should_align_with_base?
108
+ @base && style != :indented_relative_to_receiver
109
+ end
110
+
111
+ def relative_to_receiver_message(rhs)
112
+ "Indent `#{rhs.source}` #{configured_indentation_width} spaces " \
113
+ "more than `#{base_source}` on line #{@base.line}."
114
+ end
115
+
116
+ def align_with_base_message(rhs)
117
+ "Align `#{rhs.source}` with `#{base_source}` on line #{@base.line}."
118
+ end
119
+
120
+ def base_source
121
+ @base.source[/[^\n]*/]
122
+ end
123
+
124
+ def no_base_message(lhs, rhs, node)
125
+ used_indentation = rhs.column - indentation(lhs)
126
+ what = operation_description(node, rhs)
127
+
128
+ "Use #{correct_indentation(node)} (not #{used_indentation}) " \
129
+ "spaces for indenting #{what} spanning multiple lines."
130
+ end
131
+
132
+ def alignment_base(node, rhs, given_style)
133
+ case given_style
134
+ when :aligned
135
+ semantic_alignment_base(node, rhs) ||
136
+ syntactic_alignment_base(node, rhs)
137
+ when :indented
138
+ nil
139
+ when :indented_relative_to_receiver
140
+ receiver_alignment_base(node)
141
+ end
142
+ end
143
+
144
+ def syntactic_alignment_base(lhs, rhs)
145
+ # a if b
146
+ # .c
147
+ n = kw_node_with_special_indentation(lhs)
148
+ if n
149
+ case n.type
150
+ when :for then _, expression, = *n
151
+ when :return then expression, = *n
152
+ when *MODIFIER_NODES then expression, = *n
153
+ end
154
+ return expression.source_range
155
+ end
156
+
157
+ # a = b
158
+ # .c
159
+ n = part_of_assignment_rhs(lhs, rhs)
160
+ return assignment_rhs(n).source_range if n
161
+
162
+ # a + b
163
+ # .c
164
+ n = operation_rhs(lhs)
165
+ return n.source_range if n
166
+ end
167
+
168
+ # a.b
169
+ # .c
170
+ def semantic_alignment_base(node, rhs)
171
+ return unless rhs.source.start_with?('.')
172
+
173
+ node = semantic_alignment_node(node)
174
+ return unless node
175
+
176
+ node.loc.dot.join(node.loc.selector)
177
+ end
178
+
179
+ # a
180
+ # .b
181
+ # .c
182
+ def receiver_alignment_base(node)
183
+ node = node.receiver while node.receiver
184
+ node = node.parent
185
+ node = node.parent until node.loc.dot
186
+
187
+ node.receiver.source_range if node
188
+ end
189
+
190
+ def semantic_alignment_node(node)
191
+ return if argument_in_method_call(node, :with_parentheses)
192
+
193
+ # descend to root of method chain
194
+ node = node.receiver while node.receiver
195
+ # ascend to first call which has a dot
196
+ node = node.parent
197
+ node = node.parent until node.loc.dot
198
+
199
+ return if node.loc.dot.line != node.loc.line
200
+ node
201
+ end
202
+
203
+ def operation_rhs(node)
204
+ receiver, = *node
205
+ receiver.each_ancestor(:send) do |a|
206
+ _, method, args = *a
207
+ return args if operator?(method) && args &&
208
+ within_node?(receiver, args)
209
+ end
210
+ nil
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end