rubocop 0.78.0 → 1.13.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 (735) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +69 -39
  4. data/assets/output.html.erb +1 -1
  5. data/config/default.yml +1034 -139
  6. data/config/obsoletion.yml +200 -0
  7. data/exe/rubocop +2 -4
  8. data/lib/rubocop.rb +139 -66
  9. data/lib/rubocop/ast_aliases.rb +8 -0
  10. data/lib/rubocop/cached_data.rb +4 -4
  11. data/lib/rubocop/cli.rb +19 -13
  12. data/lib/rubocop/cli/command.rb +1 -0
  13. data/lib/rubocop/cli/command/auto_genenerate_config.rb +46 -19
  14. data/lib/rubocop/cli/command/base.rb +2 -0
  15. data/lib/rubocop/cli/command/execute_runner.rb +36 -12
  16. data/lib/rubocop/cli/command/init_dotfile.rb +3 -4
  17. data/lib/rubocop/cli/command/show_cops.rb +14 -13
  18. data/lib/rubocop/cli/command/suggest_extensions.rb +81 -0
  19. data/lib/rubocop/cli/command/version.rb +3 -2
  20. data/lib/rubocop/cli/environment.rb +1 -0
  21. data/lib/rubocop/comment_config.rb +54 -98
  22. data/lib/rubocop/config.rb +76 -34
  23. data/lib/rubocop/config_loader.rb +118 -114
  24. data/lib/rubocop/config_loader_resolver.rb +99 -28
  25. data/lib/rubocop/config_obsoletion.rb +67 -239
  26. data/lib/rubocop/config_obsoletion/changed_enforced_styles.rb +33 -0
  27. data/lib/rubocop/config_obsoletion/changed_parameter.rb +21 -0
  28. data/lib/rubocop/config_obsoletion/cop_rule.rb +33 -0
  29. data/lib/rubocop/config_obsoletion/extracted_cop.rb +44 -0
  30. data/lib/rubocop/config_obsoletion/parameter_rule.rb +44 -0
  31. data/lib/rubocop/config_obsoletion/removed_cop.rb +41 -0
  32. data/lib/rubocop/config_obsoletion/renamed_cop.rb +34 -0
  33. data/lib/rubocop/config_obsoletion/rule.rb +41 -0
  34. data/lib/rubocop/config_obsoletion/split_cop.rb +27 -0
  35. data/lib/rubocop/config_regeneration.rb +33 -0
  36. data/lib/rubocop/config_store.rb +31 -7
  37. data/lib/rubocop/config_validator.rb +89 -103
  38. data/lib/rubocop/cop/autocorrect_logic.rb +41 -39
  39. data/lib/rubocop/cop/badge.rb +16 -32
  40. data/lib/rubocop/cop/base.rb +450 -0
  41. data/lib/rubocop/cop/bundler/duplicated_gem.rb +30 -6
  42. data/lib/rubocop/cop/bundler/gem_comment.rb +117 -8
  43. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +13 -20
  44. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -4
  45. data/lib/rubocop/cop/commissioner.rb +98 -74
  46. data/lib/rubocop/cop/cop.rb +84 -234
  47. data/lib/rubocop/cop/corrector.rb +63 -117
  48. data/lib/rubocop/cop/correctors/alignment_corrector.rb +13 -23
  49. data/lib/rubocop/cop/correctors/condition_corrector.rb +3 -6
  50. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +2 -4
  51. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +9 -10
  52. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -2
  53. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +4 -4
  54. data/lib/rubocop/cop/correctors/line_break_corrector.rb +9 -12
  55. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +35 -6
  56. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -3
  57. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -8
  58. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -21
  59. data/lib/rubocop/cop/correctors/punctuation_corrector.rb +8 -10
  60. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -3
  61. data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
  62. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +15 -18
  63. data/lib/rubocop/cop/documentation.rb +22 -0
  64. data/lib/rubocop/cop/exclude_limit.rb +26 -0
  65. data/lib/rubocop/cop/force.rb +2 -1
  66. data/lib/rubocop/cop/gemspec/date_assignment.rb +57 -0
  67. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +6 -5
  68. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +4 -8
  69. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +48 -20
  70. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +4 -2
  71. data/lib/rubocop/cop/generator.rb +14 -25
  72. data/lib/rubocop/cop/generator/configuration_injector.rb +5 -6
  73. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -5
  74. data/lib/rubocop/cop/ignored_node.rb +1 -3
  75. data/lib/rubocop/cop/internal_affairs.rb +7 -1
  76. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +68 -0
  77. data/lib/rubocop/cop/internal_affairs/example_description.rb +92 -0
  78. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +8 -17
  79. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +4 -4
  80. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +151 -0
  81. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +11 -14
  82. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +12 -10
  83. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +62 -0
  84. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +65 -0
  85. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +12 -7
  86. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +11 -8
  87. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +148 -0
  88. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +6 -6
  89. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +12 -10
  90. data/lib/rubocop/cop/layout/argument_alignment.rb +8 -9
  91. data/lib/rubocop/cop/layout/array_alignment.rb +58 -13
  92. data/lib/rubocop/cop/layout/assignment_indentation.rb +8 -7
  93. data/lib/rubocop/cop/layout/begin_end_alignment.rb +74 -0
  94. data/lib/rubocop/cop/layout/block_alignment.rb +35 -43
  95. data/lib/rubocop/cop/layout/block_end_newline.rb +9 -11
  96. data/lib/rubocop/cop/layout/case_indentation.rb +22 -28
  97. data/lib/rubocop/cop/layout/class_structure.rb +58 -74
  98. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +4 -6
  99. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +18 -30
  100. data/lib/rubocop/cop/layout/comment_indentation.rb +21 -25
  101. data/lib/rubocop/cop/layout/condition_position.rb +16 -8
  102. data/lib/rubocop/cop/layout/def_end_alignment.rb +9 -10
  103. data/lib/rubocop/cop/layout/dot_position.rb +20 -21
  104. data/lib/rubocop/cop/layout/else_alignment.rb +28 -6
  105. data/lib/rubocop/cop/layout/empty_comment.rb +29 -29
  106. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +39 -22
  107. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +13 -13
  108. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +136 -0
  109. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +140 -39
  110. data/lib/rubocop/cop/layout/empty_lines.rb +7 -12
  111. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +29 -38
  112. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +13 -9
  113. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +118 -0
  114. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +2 -5
  115. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -5
  116. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -5
  117. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -14
  118. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +2 -5
  119. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +2 -5
  120. data/lib/rubocop/cop/layout/end_alignment.rb +18 -24
  121. data/lib/rubocop/cop/layout/end_of_line.rb +8 -8
  122. data/lib/rubocop/cop/layout/extra_spacing.rb +23 -42
  123. data/lib/rubocop/cop/layout/first_argument_indentation.rb +40 -13
  124. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -18
  125. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +4 -8
  126. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +25 -21
  127. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +3 -7
  128. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -13
  129. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +3 -7
  130. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +8 -7
  131. data/lib/rubocop/cop/layout/hash_alignment.rb +37 -40
  132. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +46 -30
  133. data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -117
  134. data/lib/rubocop/cop/layout/indentation_consistency.rb +9 -6
  135. data/lib/rubocop/cop/layout/indentation_style.rb +110 -0
  136. data/lib/rubocop/cop/layout/indentation_width.rb +22 -14
  137. data/lib/rubocop/cop/layout/initial_indentation.rb +7 -11
  138. data/lib/rubocop/cop/layout/leading_comment_space.rb +46 -13
  139. data/lib/rubocop/cop/layout/leading_empty_lines.rb +6 -11
  140. data/lib/rubocop/cop/layout/line_length.rb +61 -42
  141. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +2 -5
  142. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +3 -7
  143. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +36 -14
  144. data/lib/rubocop/cop/layout/multiline_block_layout.rb +51 -38
  145. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +2 -9
  146. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +3 -7
  147. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +6 -13
  148. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -5
  149. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +30 -19
  150. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +2 -5
  151. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +23 -9
  152. data/lib/rubocop/cop/layout/parameter_alignment.rb +6 -5
  153. data/lib/rubocop/cop/layout/redundant_line_break.rb +125 -0
  154. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +37 -30
  155. data/lib/rubocop/cop/layout/space_after_colon.rb +10 -8
  156. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -5
  157. data/lib/rubocop/cop/layout/space_after_method_name.rb +7 -10
  158. data/lib/rubocop/cop/layout/space_after_not.rb +9 -11
  159. data/lib/rubocop/cop/layout/space_after_semicolon.rb +2 -5
  160. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +45 -52
  161. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +19 -23
  162. data/lib/rubocop/cop/layout/space_around_keyword.rb +22 -26
  163. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +98 -0
  164. data/lib/rubocop/cop/layout/space_around_operators.rb +59 -25
  165. data/lib/rubocop/cop/layout/space_before_block_braces.rb +41 -25
  166. data/lib/rubocop/cop/layout/space_before_brackets.rb +65 -0
  167. data/lib/rubocop/cop/layout/space_before_comma.rb +3 -5
  168. data/lib/rubocop/cop/layout/space_before_comment.rb +8 -9
  169. data/lib/rubocop/cop/layout/space_before_first_arg.rb +17 -15
  170. data/lib/rubocop/cop/layout/space_before_semicolon.rb +2 -5
  171. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +11 -21
  172. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +30 -39
  173. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +5 -15
  174. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +34 -39
  175. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +22 -48
  176. data/lib/rubocop/cop/layout/space_inside_parens.rb +39 -22
  177. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +5 -10
  178. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +9 -18
  179. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +18 -29
  180. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +12 -13
  181. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +10 -15
  182. data/lib/rubocop/cop/layout/trailing_whitespace.rb +42 -18
  183. data/lib/rubocop/cop/legacy/corrections_proxy.rb +43 -0
  184. data/lib/rubocop/cop/legacy/corrector.rb +27 -0
  185. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +54 -0
  186. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -9
  187. data/lib/rubocop/cop/lint/ambiguous_operator.rb +53 -5
  188. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +36 -6
  189. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  190. data/lib/rubocop/cop/lint/big_decimal_new.rb +10 -10
  191. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +55 -0
  192. data/lib/rubocop/cop/lint/boolean_symbol.rb +24 -4
  193. data/lib/rubocop/cop/lint/circular_argument_reference.rb +1 -1
  194. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +100 -0
  195. data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
  196. data/lib/rubocop/cop/lint/debugger.rb +61 -21
  197. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +9 -14
  198. data/lib/rubocop/cop/lint/deprecated_constants.rb +80 -0
  199. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +148 -0
  200. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +8 -2
  201. data/lib/rubocop/cop/lint/duplicate_branch.rb +154 -0
  202. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +3 -13
  203. data/lib/rubocop/cop/lint/duplicate_elsif_condition.rb +39 -0
  204. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -4
  205. data/lib/rubocop/cop/lint/duplicate_methods.rb +12 -16
  206. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +77 -0
  207. data/lib/rubocop/cop/lint/duplicate_require.rb +47 -0
  208. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +47 -0
  209. data/lib/rubocop/cop/lint/each_with_object_argument.rb +3 -1
  210. data/lib/rubocop/cop/lint/else_layout.rb +29 -5
  211. data/lib/rubocop/cop/lint/empty_block.rb +82 -0
  212. data/lib/rubocop/cop/lint/empty_class.rb +93 -0
  213. data/lib/rubocop/cop/lint/empty_conditional_body.rb +67 -0
  214. data/lib/rubocop/cop/lint/empty_ensure.rb +5 -7
  215. data/lib/rubocop/cop/lint/empty_expression.rb +2 -2
  216. data/lib/rubocop/cop/lint/empty_file.rb +48 -0
  217. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -7
  218. data/lib/rubocop/cop/lint/empty_when.rb +31 -8
  219. data/lib/rubocop/cop/lint/ensure_return.rb +29 -16
  220. data/lib/rubocop/cop/lint/erb_new_arguments.rb +19 -21
  221. data/lib/rubocop/cop/lint/flip_flop.rb +9 -3
  222. data/lib/rubocop/cop/lint/float_comparison.rb +93 -0
  223. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -3
  224. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +45 -10
  225. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +38 -0
  226. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +14 -16
  227. data/lib/rubocop/cop/lint/identity_comparison.rb +51 -0
  228. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +7 -7
  229. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +14 -20
  230. data/lib/rubocop/cop/lint/inherit_exception.rb +14 -9
  231. data/lib/rubocop/cop/lint/interpolation_check.rb +20 -7
  232. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +44 -0
  233. data/lib/rubocop/cop/lint/literal_as_condition.rb +24 -15
  234. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +44 -15
  235. data/lib/rubocop/cop/lint/loop.rb +31 -9
  236. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +9 -12
  237. data/lib/rubocop/cop/lint/missing_super.rb +101 -0
  238. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +36 -0
  239. data/lib/rubocop/cop/lint/multiple_comparison.rb +15 -15
  240. data/lib/rubocop/cop/lint/nested_method_definition.rb +21 -25
  241. data/lib/rubocop/cop/lint/nested_percent_literal.rb +17 -5
  242. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -1
  243. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +58 -0
  244. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +95 -15
  245. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +12 -9
  246. data/lib/rubocop/cop/lint/number_conversion.rb +97 -23
  247. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +47 -0
  248. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +39 -0
  249. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +12 -15
  250. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +96 -0
  251. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +31 -12
  252. data/lib/rubocop/cop/lint/percent_string_array.rb +6 -11
  253. data/lib/rubocop/cop/lint/percent_symbol_array.rb +12 -13
  254. data/lib/rubocop/cop/lint/raise_exception.rb +87 -0
  255. data/lib/rubocop/cop/lint/rand_one.rb +5 -4
  256. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +71 -75
  257. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +51 -37
  258. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +50 -0
  259. data/lib/rubocop/cop/lint/redundant_require_statement.rb +9 -10
  260. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +77 -0
  261. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +72 -35
  262. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +8 -15
  263. data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -18
  264. data/lib/rubocop/cop/lint/redundant_with_object.rb +13 -18
  265. data/lib/rubocop/cop/lint/regexp_as_condition.rb +4 -2
  266. data/lib/rubocop/cop/lint/require_parentheses.rb +4 -6
  267. data/lib/rubocop/cop/lint/rescue_exception.rb +3 -4
  268. data/lib/rubocop/cop/lint/rescue_type.rb +10 -16
  269. data/lib/rubocop/cop/lint/return_in_void_context.rb +3 -6
  270. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +6 -9
  271. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +15 -17
  272. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +12 -4
  273. data/lib/rubocop/cop/lint/script_permission.rb +10 -7
  274. data/lib/rubocop/cop/lint/self_assignment.rb +78 -0
  275. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +11 -19
  276. data/lib/rubocop/cop/lint/shadowed_argument.rb +8 -14
  277. data/lib/rubocop/cop/lint/shadowed_exception.rb +18 -30
  278. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +21 -7
  279. data/lib/rubocop/cop/lint/struct_new_override.rb +59 -0
  280. data/lib/rubocop/cop/lint/suppressed_exception.rb +55 -18
  281. data/lib/rubocop/cop/lint/symbol_conversion.rb +188 -0
  282. data/lib/rubocop/cop/lint/syntax.rb +11 -30
  283. data/lib/rubocop/cop/lint/to_enum_arguments.rb +89 -0
  284. data/lib/rubocop/cop/lint/to_json.rb +21 -13
  285. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +34 -0
  286. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +55 -0
  287. data/lib/rubocop/cop/lint/triple_quotes.rb +71 -0
  288. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +5 -7
  289. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +85 -0
  290. data/lib/rubocop/cop/lint/unified_integer.rb +5 -8
  291. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +204 -0
  292. data/lib/rubocop/cop/lint/unreachable_code.rb +5 -7
  293. data/lib/rubocop/cop/lint/unreachable_loop.rb +186 -0
  294. data/lib/rubocop/cop/lint/unused_block_argument.rb +12 -11
  295. data/lib/rubocop/cop/lint/unused_method_argument.rb +42 -11
  296. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +5 -2
  297. data/lib/rubocop/cop/lint/uri_regexp.rb +12 -47
  298. data/lib/rubocop/cop/lint/useless_access_modifier.rb +38 -22
  299. data/lib/rubocop/cop/lint/useless_assignment.rb +9 -13
  300. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +7 -11
  301. data/lib/rubocop/cop/lint/useless_method_definition.rb +68 -0
  302. data/lib/rubocop/cop/lint/useless_setter_call.rb +15 -9
  303. data/lib/rubocop/cop/lint/useless_times.rb +109 -0
  304. data/lib/rubocop/cop/lint/void.rb +7 -18
  305. data/lib/rubocop/cop/message_annotator.rb +5 -4
  306. data/lib/rubocop/cop/metrics/abc_size.rb +26 -2
  307. data/lib/rubocop/cop/metrics/block_length.rb +40 -10
  308. data/lib/rubocop/cop/metrics/block_nesting.rb +5 -10
  309. data/lib/rubocop/cop/metrics/class_length.rb +40 -11
  310. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +38 -6
  311. data/lib/rubocop/cop/metrics/method_length.rb +32 -4
  312. data/lib/rubocop/cop/metrics/module_length.rb +29 -9
  313. data/lib/rubocop/cop/metrics/parameter_lists.rb +74 -11
  314. data/lib/rubocop/cop/metrics/perceived_complexity.rb +7 -9
  315. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +76 -15
  316. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +160 -0
  317. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
  318. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +143 -0
  319. data/lib/rubocop/cop/metrics/utils/repeated_csend_discount.rb +42 -0
  320. data/lib/rubocop/cop/migration/department_name.rb +51 -16
  321. data/lib/rubocop/cop/mixin/alignment.rb +18 -11
  322. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +18 -0
  323. data/lib/rubocop/cop/mixin/allowed_methods.rb +21 -0
  324. data/lib/rubocop/cop/mixin/annotation_comment.rb +5 -0
  325. data/lib/rubocop/cop/mixin/array_min_size.rb +2 -4
  326. data/lib/rubocop/cop/mixin/auto_corrector.rb +12 -0
  327. data/lib/rubocop/cop/mixin/check_line_breakable.rb +26 -18
  328. data/lib/rubocop/cop/mixin/code_length.rb +29 -8
  329. data/lib/rubocop/cop/mixin/comments_help.rb +42 -0
  330. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +7 -5
  331. data/lib/rubocop/cop/mixin/configurable_formatting.rb +4 -11
  332. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -0
  333. data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
  334. data/lib/rubocop/cop/mixin/configurable_numbering.rb +4 -3
  335. data/lib/rubocop/cop/mixin/def_node.rb +3 -5
  336. data/lib/rubocop/cop/mixin/documentation_comment.rb +4 -7
  337. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +14 -14
  338. data/lib/rubocop/cop/mixin/empty_parameter.rb +2 -1
  339. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +16 -2
  340. data/lib/rubocop/cop/mixin/enforce_superclass.rb +16 -8
  341. data/lib/rubocop/cop/mixin/first_element_line_break.rb +3 -3
  342. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +12 -9
  343. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +3 -6
  344. data/lib/rubocop/cop/mixin/hash_transform_method.rb +183 -0
  345. data/lib/rubocop/cop/mixin/ignored_methods.rb +36 -3
  346. data/lib/rubocop/cop/mixin/ignored_pattern.rb +1 -1
  347. data/lib/rubocop/cop/mixin/interpolation.rb +1 -3
  348. data/lib/rubocop/cop/mixin/line_length_help.rb +17 -15
  349. data/lib/rubocop/cop/mixin/match_range.rb +2 -5
  350. data/lib/rubocop/cop/mixin/method_complexity.rb +26 -6
  351. data/lib/rubocop/cop/mixin/method_preference.rb +1 -2
  352. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +4 -3
  353. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +1 -1
  354. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +13 -42
  355. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +14 -14
  356. data/lib/rubocop/cop/mixin/negative_conditional.rb +6 -4
  357. data/lib/rubocop/cop/mixin/nil_methods.rb +3 -5
  358. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +7 -5
  359. data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
  360. data/lib/rubocop/cop/mixin/percent_array.rb +14 -9
  361. data/lib/rubocop/cop/mixin/percent_literal.rb +0 -6
  362. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -12
  363. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +6 -9
  364. data/lib/rubocop/cop/mixin/range_help.rb +24 -13
  365. data/lib/rubocop/cop/mixin/rational_literal.rb +1 -0
  366. data/lib/rubocop/cop/mixin/rescue_node.rb +13 -7
  367. data/lib/rubocop/cop/mixin/safe_assignment.rb +6 -2
  368. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +6 -7
  369. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +5 -5
  370. data/lib/rubocop/cop/mixin/statement_modifier.rb +45 -22
  371. data/lib/rubocop/cop/mixin/string_help.rb +4 -1
  372. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  373. data/lib/rubocop/cop/mixin/surrounding_space.rb +15 -31
  374. data/lib/rubocop/cop/mixin/target_ruby_version.rb +5 -1
  375. data/lib/rubocop/cop/mixin/trailing_body.rb +1 -2
  376. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -27
  377. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +25 -32
  378. data/lib/rubocop/cop/mixin/unused_argument.rb +5 -9
  379. data/lib/rubocop/cop/mixin/visibility_help.rb +37 -0
  380. data/lib/rubocop/cop/naming/accessor_method_name.rb +19 -3
  381. data/lib/rubocop/cop/naming/ascii_identifiers.rb +29 -8
  382. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -7
  383. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  384. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +13 -3
  385. data/lib/rubocop/cop/naming/constant_name.rb +5 -2
  386. data/lib/rubocop/cop/naming/file_name.rb +36 -34
  387. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +12 -6
  388. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +4 -4
  389. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +132 -24
  390. data/lib/rubocop/cop/naming/method_name.rb +31 -3
  391. data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
  392. data/lib/rubocop/cop/naming/predicate_name.rb +10 -13
  393. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +59 -15
  394. data/lib/rubocop/cop/naming/variable_name.rb +3 -1
  395. data/lib/rubocop/cop/naming/variable_number.rb +94 -9
  396. data/lib/rubocop/cop/offense.rb +35 -12
  397. data/lib/rubocop/cop/registry.rb +100 -24
  398. data/lib/rubocop/cop/security/eval.rb +4 -2
  399. data/lib/rubocop/cop/security/json_load.rb +8 -8
  400. data/lib/rubocop/cop/security/marshal_load.rb +4 -4
  401. data/lib/rubocop/cop/security/open.rb +15 -11
  402. data/lib/rubocop/cop/security/yaml_load.rb +8 -6
  403. data/lib/rubocop/cop/severity.rb +4 -14
  404. data/lib/rubocop/cop/style/access_modifier_declarations.rb +37 -13
  405. data/lib/rubocop/cop/style/accessor_grouping.rb +150 -0
  406. data/lib/rubocop/cop/style/alias.rb +46 -45
  407. data/lib/rubocop/cop/style/and_or.rb +30 -23
  408. data/lib/rubocop/cop/style/arguments_forwarding.rb +143 -0
  409. data/lib/rubocop/cop/style/array_coercion.rb +69 -0
  410. data/lib/rubocop/cop/style/array_join.rb +9 -9
  411. data/lib/rubocop/cop/style/ascii_comments.rb +6 -7
  412. data/lib/rubocop/cop/style/attr.rb +15 -15
  413. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +9 -12
  414. data/lib/rubocop/cop/style/bare_percent_literals.rb +12 -14
  415. data/lib/rubocop/cop/style/begin_block.rb +2 -2
  416. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +125 -0
  417. data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +60 -0
  418. data/lib/rubocop/cop/style/block_comments.rb +14 -18
  419. data/lib/rubocop/cop/style/block_delimiters.rb +77 -26
  420. data/lib/rubocop/cop/style/case_equality.rb +55 -4
  421. data/lib/rubocop/cop/style/case_like_if.rb +258 -0
  422. data/lib/rubocop/cop/style/character_literal.rb +12 -15
  423. data/lib/rubocop/cop/style/class_and_module_children.rb +28 -21
  424. data/lib/rubocop/cop/style/class_check.rb +6 -11
  425. data/lib/rubocop/cop/style/class_equality_comparison.rb +67 -0
  426. data/lib/rubocop/cop/style/class_methods.rb +8 -14
  427. data/lib/rubocop/cop/style/class_methods_definitions.rb +157 -0
  428. data/lib/rubocop/cop/style/class_vars.rb +23 -7
  429. data/lib/rubocop/cop/style/collection_compact.rb +91 -0
  430. data/lib/rubocop/cop/style/collection_methods.rb +24 -15
  431. data/lib/rubocop/cop/style/colon_method_call.rb +7 -9
  432. data/lib/rubocop/cop/style/colon_method_definition.rb +6 -6
  433. data/lib/rubocop/cop/style/combinable_loops.rb +92 -0
  434. data/lib/rubocop/cop/style/command_literal.rb +22 -28
  435. data/lib/rubocop/cop/style/comment_annotation.rb +24 -21
  436. data/lib/rubocop/cop/style/commented_keyword.rb +34 -21
  437. data/lib/rubocop/cop/style/conditional_assignment.rb +75 -91
  438. data/lib/rubocop/cop/style/constant_visibility.rb +31 -2
  439. data/lib/rubocop/cop/style/copyright.rb +21 -24
  440. data/lib/rubocop/cop/style/date_time.rb +16 -5
  441. data/lib/rubocop/cop/style/def_with_parentheses.rb +9 -12
  442. data/lib/rubocop/cop/style/dir.rb +11 -12
  443. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +87 -0
  444. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +169 -0
  445. data/lib/rubocop/cop/style/documentation.rb +92 -18
  446. data/lib/rubocop/cop/style/documentation_method.rb +2 -1
  447. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +12 -15
  448. data/lib/rubocop/cop/style/double_negation.rb +50 -6
  449. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -10
  450. data/lib/rubocop/cop/style/each_with_object.rb +17 -19
  451. data/lib/rubocop/cop/style/empty_block_parameter.rb +9 -10
  452. data/lib/rubocop/cop/style/empty_case_condition.rb +22 -26
  453. data/lib/rubocop/cop/style/empty_else.rb +14 -22
  454. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +9 -10
  455. data/lib/rubocop/cop/style/empty_literal.rb +39 -31
  456. data/lib/rubocop/cop/style/empty_method.rb +12 -23
  457. data/lib/rubocop/cop/style/encoding.rb +6 -10
  458. data/lib/rubocop/cop/style/end_block.rb +7 -4
  459. data/lib/rubocop/cop/style/endless_method.rb +101 -0
  460. data/lib/rubocop/cop/style/eval_with_location.rb +143 -54
  461. data/lib/rubocop/cop/style/even_odd.rb +9 -11
  462. data/lib/rubocop/cop/style/expand_path_arguments.rb +27 -25
  463. data/lib/rubocop/cop/style/explicit_block_argument.rb +114 -0
  464. data/lib/rubocop/cop/style/exponential_notation.rb +116 -0
  465. data/lib/rubocop/cop/style/float_division.rb +60 -11
  466. data/lib/rubocop/cop/style/for.rb +7 -13
  467. data/lib/rubocop/cop/style/format_string.rb +30 -24
  468. data/lib/rubocop/cop/style/format_string_token.rb +78 -22
  469. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +83 -38
  470. data/lib/rubocop/cop/style/global_std_stream.rb +66 -0
  471. data/lib/rubocop/cop/style/global_vars.rb +2 -2
  472. data/lib/rubocop/cop/style/guard_clause.rb +32 -13
  473. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +88 -0
  474. data/lib/rubocop/cop/style/hash_conversion.rb +133 -0
  475. data/lib/rubocop/cop/style/hash_each_methods.rb +86 -0
  476. data/lib/rubocop/cop/style/hash_except.rb +96 -0
  477. data/lib/rubocop/cop/style/hash_like_case.rb +77 -0
  478. data/lib/rubocop/cop/style/hash_syntax.rb +50 -45
  479. data/lib/rubocop/cop/style/hash_transform_keys.rb +95 -0
  480. data/lib/rubocop/cop/style/hash_transform_values.rb +92 -0
  481. data/lib/rubocop/cop/style/identical_conditional_branches.rb +10 -7
  482. data/lib/rubocop/cop/style/if_inside_else.rb +50 -2
  483. data/lib/rubocop/cop/style/if_unless_modifier.rb +76 -46
  484. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +11 -3
  485. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +122 -0
  486. data/lib/rubocop/cop/style/if_with_semicolon.rb +51 -3
  487. data/lib/rubocop/cop/style/implicit_runtime_error.rb +3 -1
  488. data/lib/rubocop/cop/style/infinite_loop.rb +27 -26
  489. data/lib/rubocop/cop/style/inline_comment.rb +4 -4
  490. data/lib/rubocop/cop/style/inverse_methods.rb +34 -42
  491. data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
  492. data/lib/rubocop/cop/style/keyword_parameters_order.rb +75 -0
  493. data/lib/rubocop/cop/style/lambda.rb +11 -17
  494. data/lib/rubocop/cop/style/lambda_call.rb +18 -35
  495. data/lib/rubocop/cop/style/line_end_concatenation.rb +21 -25
  496. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +58 -207
  497. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +189 -0
  498. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +44 -0
  499. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +19 -12
  500. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +14 -7
  501. data/lib/rubocop/cop/style/method_def_parentheses.rb +18 -24
  502. data/lib/rubocop/cop/style/min_max.rb +10 -14
  503. data/lib/rubocop/cop/style/missing_else.rb +13 -25
  504. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +11 -5
  505. data/lib/rubocop/cop/style/mixin_grouping.rb +27 -40
  506. data/lib/rubocop/cop/style/mixin_usage.rb +12 -30
  507. data/lib/rubocop/cop/style/module_function.rb +70 -25
  508. data/lib/rubocop/cop/style/multiline_block_chain.rb +13 -5
  509. data/lib/rubocop/cop/style/multiline_if_modifier.rb +4 -11
  510. data/lib/rubocop/cop/style/multiline_if_then.rb +5 -11
  511. data/lib/rubocop/cop/style/multiline_memoization.rb +15 -13
  512. data/lib/rubocop/cop/style/multiline_method_signature.rb +33 -3
  513. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +32 -11
  514. data/lib/rubocop/cop/style/multiline_when_then.rb +31 -11
  515. data/lib/rubocop/cop/style/multiple_comparison.rb +76 -11
  516. data/lib/rubocop/cop/style/mutable_constant.rb +41 -33
  517. data/lib/rubocop/cop/style/negated_if.rb +10 -11
  518. data/lib/rubocop/cop/style/negated_if_else_condition.rb +120 -0
  519. data/lib/rubocop/cop/style/negated_unless.rb +10 -11
  520. data/lib/rubocop/cop/style/negated_while.rb +7 -15
  521. data/lib/rubocop/cop/style/nested_modifier.rb +10 -17
  522. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +23 -20
  523. data/lib/rubocop/cop/style/nested_ternary_operator.rb +30 -4
  524. data/lib/rubocop/cop/style/next.rb +18 -27
  525. data/lib/rubocop/cop/style/nil_comparison.rb +19 -11
  526. data/lib/rubocop/cop/style/nil_lambda.rb +53 -0
  527. data/lib/rubocop/cop/style/non_nil_check.rb +56 -34
  528. data/lib/rubocop/cop/style/not.rb +20 -26
  529. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +6 -11
  530. data/lib/rubocop/cop/style/numeric_literals.rb +19 -27
  531. data/lib/rubocop/cop/style/numeric_predicate.rb +17 -24
  532. data/lib/rubocop/cop/style/one_line_conditional.rb +75 -29
  533. data/lib/rubocop/cop/style/option_hash.rb +3 -4
  534. data/lib/rubocop/cop/style/optional_arguments.rb +4 -7
  535. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +53 -0
  536. data/lib/rubocop/cop/style/or_assignment.rb +14 -12
  537. data/lib/rubocop/cop/style/parallel_assignment.rb +27 -24
  538. data/lib/rubocop/cop/style/parentheses_around_condition.rb +7 -6
  539. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +22 -30
  540. data/lib/rubocop/cop/style/percent_q_literals.rb +9 -12
  541. data/lib/rubocop/cop/style/perl_backrefs.rb +84 -16
  542. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -18
  543. data/lib/rubocop/cop/style/proc.rb +8 -8
  544. data/lib/rubocop/cop/style/raise_args.rb +39 -37
  545. data/lib/rubocop/cop/style/random_with_offset.rb +30 -35
  546. data/lib/rubocop/cop/style/redundant_argument.rb +85 -0
  547. data/lib/rubocop/cop/style/redundant_assignment.rb +106 -0
  548. data/lib/rubocop/cop/style/redundant_begin.rb +79 -13
  549. data/lib/rubocop/cop/style/redundant_capital_w.rb +7 -11
  550. data/lib/rubocop/cop/style/redundant_condition.rb +43 -18
  551. data/lib/rubocop/cop/style/redundant_conditional.rb +14 -15
  552. data/lib/rubocop/cop/style/redundant_exception.rb +22 -17
  553. data/lib/rubocop/cop/style/redundant_fetch_block.rb +115 -0
  554. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +52 -0
  555. data/lib/rubocop/cop/style/redundant_freeze.rb +16 -14
  556. data/lib/rubocop/cop/style/redundant_interpolation.rb +32 -27
  557. data/lib/rubocop/cop/style/redundant_parentheses.rb +51 -38
  558. data/lib/rubocop/cop/style/redundant_percent_q.rb +14 -17
  559. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +104 -0
  560. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +118 -0
  561. data/lib/rubocop/cop/style/redundant_return.rb +29 -29
  562. data/lib/rubocop/cop/style/redundant_self.rb +27 -29
  563. data/lib/rubocop/cop/style/redundant_self_assignment.rb +118 -0
  564. data/lib/rubocop/cop/style/redundant_sort.rb +32 -37
  565. data/lib/rubocop/cop/style/redundant_sort_by.rb +6 -9
  566. data/lib/rubocop/cop/style/regexp_literal.rb +14 -29
  567. data/lib/rubocop/cop/style/rescue_modifier.rb +39 -12
  568. data/lib/rubocop/cop/style/rescue_standard_error.rb +25 -23
  569. data/lib/rubocop/cop/style/return_nil.rb +13 -8
  570. data/lib/rubocop/cop/style/safe_navigation.rb +44 -39
  571. data/lib/rubocop/cop/style/sample.rb +14 -15
  572. data/lib/rubocop/cop/style/self_assignment.rb +26 -22
  573. data/lib/rubocop/cop/style/semicolon.rb +10 -10
  574. data/lib/rubocop/cop/style/send.rb +5 -7
  575. data/lib/rubocop/cop/style/signal_exception.rb +32 -27
  576. data/lib/rubocop/cop/style/single_argument_dig.rb +55 -0
  577. data/lib/rubocop/cop/style/single_line_block_params.rb +34 -12
  578. data/lib/rubocop/cop/style/single_line_methods.rb +65 -18
  579. data/lib/rubocop/cop/style/slicing_with_range.rb +38 -0
  580. data/lib/rubocop/cop/style/sole_nested_conditional.rb +167 -0
  581. data/lib/rubocop/cop/style/special_global_vars.rb +18 -51
  582. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +18 -25
  583. data/lib/rubocop/cop/style/static_class.rb +97 -0
  584. data/lib/rubocop/cop/style/stderr_puts.rb +9 -13
  585. data/lib/rubocop/cop/style/string_chars.rb +39 -0
  586. data/lib/rubocop/cop/style/string_concatenation.rb +142 -0
  587. data/lib/rubocop/cop/style/string_hash_keys.rb +8 -7
  588. data/lib/rubocop/cop/style/string_literals.rb +16 -13
  589. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
  590. data/lib/rubocop/cop/style/string_methods.rb +7 -17
  591. data/lib/rubocop/cop/style/strip.rb +10 -14
  592. data/lib/rubocop/cop/style/struct_inheritance.rb +33 -4
  593. data/lib/rubocop/cop/style/swap_values.rb +108 -0
  594. data/lib/rubocop/cop/style/symbol_array.rb +13 -24
  595. data/lib/rubocop/cop/style/symbol_literal.rb +5 -9
  596. data/lib/rubocop/cop/style/symbol_proc.rb +50 -32
  597. data/lib/rubocop/cop/style/ternary_parentheses.rb +30 -35
  598. data/lib/rubocop/cop/style/trailing_body_on_class.rb +3 -6
  599. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +10 -9
  600. data/lib/rubocop/cop/style/trailing_body_on_module.rb +3 -6
  601. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +37 -27
  602. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +43 -5
  603. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +86 -0
  604. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +46 -5
  605. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +12 -38
  606. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +16 -31
  607. data/lib/rubocop/cop/style/trivial_accessors.rb +36 -40
  608. data/lib/rubocop/cop/style/unless_else.rb +7 -11
  609. data/lib/rubocop/cop/style/unless_logical_operators.rb +105 -0
  610. data/lib/rubocop/cop/style/unpack_first.rb +5 -11
  611. data/lib/rubocop/cop/style/variable_interpolation.rb +8 -11
  612. data/lib/rubocop/cop/style/when_then.rb +5 -9
  613. data/lib/rubocop/cop/style/while_until_do.rb +6 -16
  614. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -24
  615. data/lib/rubocop/cop/style/word_array.rb +6 -25
  616. data/lib/rubocop/cop/style/yoda_condition.rb +33 -19
  617. data/lib/rubocop/cop/style/zero_length_predicate.rb +25 -23
  618. data/lib/rubocop/cop/team.rb +147 -84
  619. data/lib/rubocop/cop/util.rb +43 -27
  620. data/lib/rubocop/cop/utils/format_string.rb +22 -9
  621. data/lib/rubocop/cop/variable_force.rb +15 -27
  622. data/lib/rubocop/cop/variable_force/assignment.rb +2 -2
  623. data/lib/rubocop/cop/variable_force/branch.rb +3 -9
  624. data/lib/rubocop/cop/variable_force/reference.rb +1 -3
  625. data/lib/rubocop/cop/variable_force/scope.rb +6 -9
  626. data/lib/rubocop/cop/variable_force/variable.rb +9 -12
  627. data/lib/rubocop/cops_documentation_generator.rb +270 -0
  628. data/lib/rubocop/core_ext/string.rb +2 -2
  629. data/lib/rubocop/directive_comment.rb +92 -0
  630. data/lib/rubocop/error.rb +1 -0
  631. data/lib/rubocop/ext/processed_source.rb +18 -0
  632. data/lib/rubocop/ext/regexp_node.rb +87 -0
  633. data/lib/rubocop/ext/regexp_parser.rb +92 -0
  634. data/lib/rubocop/file_finder.rb +12 -13
  635. data/lib/rubocop/formatter/auto_gen_config_formatter.rb +2 -1
  636. data/lib/rubocop/formatter/base_formatter.rb +0 -4
  637. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -3
  638. data/lib/rubocop/formatter/disabled_config_formatter.rb +39 -30
  639. data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
  640. data/lib/rubocop/formatter/formatter_set.rb +6 -6
  641. data/lib/rubocop/formatter/git_hub_actions_formatter.rb +44 -0
  642. data/lib/rubocop/formatter/html_formatter.rb +6 -10
  643. data/lib/rubocop/formatter/json_formatter.rb +1 -5
  644. data/lib/rubocop/formatter/junit_formatter.rb +78 -0
  645. data/lib/rubocop/formatter/offense_count_formatter.rb +2 -2
  646. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  647. data/lib/rubocop/formatter/progress_formatter.rb +3 -4
  648. data/lib/rubocop/formatter/quiet_formatter.rb +1 -1
  649. data/lib/rubocop/formatter/simple_text_formatter.rb +40 -7
  650. data/lib/rubocop/formatter/tap_formatter.rb +7 -3
  651. data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -2
  652. data/lib/rubocop/lockfile.rb +40 -0
  653. data/lib/rubocop/magic_comment.rb +33 -4
  654. data/lib/rubocop/name_similarity.rb +18 -10
  655. data/lib/rubocop/options.rb +124 -77
  656. data/lib/rubocop/path_util.rb +20 -22
  657. data/lib/rubocop/platform.rb +1 -1
  658. data/lib/rubocop/rake_task.rb +12 -11
  659. data/lib/rubocop/remote_config.rb +6 -10
  660. data/lib/rubocop/result_cache.rb +50 -31
  661. data/lib/rubocop/rspec/cop_helper.rb +11 -35
  662. data/lib/rubocop/rspec/expect_offense.rb +129 -40
  663. data/lib/rubocop/rspec/shared_contexts.rb +78 -35
  664. data/lib/rubocop/runner.rb +112 -75
  665. data/lib/rubocop/string_interpreter.rb +3 -0
  666. data/lib/rubocop/target_finder.rb +53 -50
  667. data/lib/rubocop/target_ruby.rb +264 -0
  668. data/lib/rubocop/util.rb +16 -0
  669. data/lib/rubocop/version.rb +71 -7
  670. data/lib/rubocop/yaml_duplication_checker.rb +1 -0
  671. metadata +208 -94
  672. data/bin/console +0 -10
  673. data/bin/setup +0 -7
  674. data/lib/rubocop/ast/builder.rb +0 -82
  675. data/lib/rubocop/ast/node.rb +0 -644
  676. data/lib/rubocop/ast/node/alias_node.rb +0 -24
  677. data/lib/rubocop/ast/node/and_node.rb +0 -29
  678. data/lib/rubocop/ast/node/args_node.rb +0 -29
  679. data/lib/rubocop/ast/node/array_node.rb +0 -57
  680. data/lib/rubocop/ast/node/block_node.rb +0 -117
  681. data/lib/rubocop/ast/node/break_node.rb +0 -17
  682. data/lib/rubocop/ast/node/case_node.rb +0 -56
  683. data/lib/rubocop/ast/node/class_node.rb +0 -31
  684. data/lib/rubocop/ast/node/def_node.rb +0 -71
  685. data/lib/rubocop/ast/node/defined_node.rb +0 -17
  686. data/lib/rubocop/ast/node/ensure_node.rb +0 -17
  687. data/lib/rubocop/ast/node/float_node.rb +0 -12
  688. data/lib/rubocop/ast/node/for_node.rb +0 -53
  689. data/lib/rubocop/ast/node/hash_node.rb +0 -109
  690. data/lib/rubocop/ast/node/if_node.rb +0 -175
  691. data/lib/rubocop/ast/node/int_node.rb +0 -12
  692. data/lib/rubocop/ast/node/keyword_splat_node.rb +0 -45
  693. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +0 -16
  694. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +0 -43
  695. data/lib/rubocop/ast/node/mixin/collection_node.rb +0 -15
  696. data/lib/rubocop/ast/node/mixin/conditional_node.rb +0 -45
  697. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +0 -125
  698. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +0 -261
  699. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +0 -114
  700. data/lib/rubocop/ast/node/mixin/modifier_node.rb +0 -17
  701. data/lib/rubocop/ast/node/mixin/numeric_node.rb +0 -21
  702. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +0 -61
  703. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +0 -35
  704. data/lib/rubocop/ast/node/module_node.rb +0 -24
  705. data/lib/rubocop/ast/node/or_node.rb +0 -29
  706. data/lib/rubocop/ast/node/pair_node.rb +0 -63
  707. data/lib/rubocop/ast/node/range_node.rb +0 -18
  708. data/lib/rubocop/ast/node/regexp_node.rb +0 -35
  709. data/lib/rubocop/ast/node/resbody_node.rb +0 -24
  710. data/lib/rubocop/ast/node/retry_node.rb +0 -17
  711. data/lib/rubocop/ast/node/return_node.rb +0 -24
  712. data/lib/rubocop/ast/node/self_class_node.rb +0 -24
  713. data/lib/rubocop/ast/node/send_node.rb +0 -13
  714. data/lib/rubocop/ast/node/str_node.rb +0 -16
  715. data/lib/rubocop/ast/node/super_node.rb +0 -21
  716. data/lib/rubocop/ast/node/symbol_node.rb +0 -12
  717. data/lib/rubocop/ast/node/until_node.rb +0 -35
  718. data/lib/rubocop/ast/node/when_node.rb +0 -53
  719. data/lib/rubocop/ast/node/while_node.rb +0 -35
  720. data/lib/rubocop/ast/node/yield_node.rb +0 -21
  721. data/lib/rubocop/ast/sexp.rb +0 -16
  722. data/lib/rubocop/ast/traversal.rb +0 -183
  723. data/lib/rubocop/cop/layout/tab.rb +0 -75
  724. data/lib/rubocop/cop/lint/end_in_method.rb +0 -40
  725. data/lib/rubocop/cop/lint/useless_comparison.rb +0 -28
  726. data/lib/rubocop/cop/mixin/classish_length.rb +0 -37
  727. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +0 -37
  728. data/lib/rubocop/cop/mixin/too_many_lines.rb +0 -35
  729. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
  730. data/lib/rubocop/cop/style/method_missing_super.rb +0 -34
  731. data/lib/rubocop/formatter/disabled_lines_formatter.rb +0 -57
  732. data/lib/rubocop/node_pattern.rb +0 -801
  733. data/lib/rubocop/processed_source.rb +0 -216
  734. data/lib/rubocop/string_util.rb +0 -14
  735. data/lib/rubocop/token.rb +0 -114
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Style
6
- # This cop checks for the presence of `method_missing` without
7
- # falling back on `super`.
8
- #
9
- # @example
10
- # #bad
11
- # def method_missing(name, *args)
12
- # # ...
13
- # end
14
- #
15
- # #good
16
- #
17
- # def method_missing(name, *args)
18
- # # ...
19
- # super
20
- # end
21
- class MethodMissingSuper < Cop
22
- MSG = 'When using `method_missing`, fall back on `super`.'
23
-
24
- def on_def(node)
25
- return unless node.method?(:method_missing)
26
- return if node.descendants.any?(&:zsuper_type?)
27
-
28
- add_offense(node)
29
- end
30
- alias on_defs on_def
31
- end
32
- end
33
- end
34
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Formatter
5
- # A basic formatter that displays the lines disabled
6
- # inline comments.
7
- class DisabledLinesFormatter < BaseFormatter
8
- include PathUtil
9
- include Colorizable
10
-
11
- attr_reader :cop_disabled_line_ranges
12
-
13
- def started(_target_files)
14
- @cop_disabled_line_ranges = {}
15
- end
16
-
17
- def file_started(file, options)
18
- return unless options[:cop_disabled_line_ranges]
19
-
20
- @cop_disabled_line_ranges[file] =
21
- options[:cop_disabled_line_ranges]
22
- end
23
-
24
- def finished(_inspected_files)
25
- cops_disabled_in_comments_summary
26
- end
27
-
28
- private
29
-
30
- def cops_disabled_in_comments_summary
31
- summary = "\nCops disabled line ranges:\n\n"
32
-
33
- @cop_disabled_line_ranges.each do |file, disabled_cops|
34
- disabled_cops.each do |cop, line_ranges|
35
- line_ranges.each do |line_range|
36
- file = cyan(smart_path(file))
37
- summary += "#{file}:#{line_range}: #{cop}\n"
38
- end
39
- end
40
- end
41
-
42
- output.puts summary
43
- end
44
-
45
- def smart_path(path)
46
- # Ideally, we calculate this relative to the project root.
47
- base_dir = Dir.pwd
48
-
49
- if path.start_with? base_dir
50
- relative_path(path, base_dir)
51
- else
52
- path
53
- end
54
- end
55
- end
56
- end
57
- end
@@ -1,801 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'delegate'
4
- require 'erb'
5
-
6
- # rubocop:disable Metrics/ClassLength, Metrics/CyclomaticComplexity
7
- module RuboCop
8
- # This class performs a pattern-matching operation on an AST node.
9
- #
10
- # Initialize a new `NodePattern` with `NodePattern.new(pattern_string)`, then
11
- # pass an AST node to `NodePattern#match`. Alternatively, use one of the class
12
- # macros in `NodePattern::Macros` to define your own pattern-matching method.
13
- #
14
- # If the match fails, `nil` will be returned. If the match succeeds, the
15
- # return value depends on whether a block was provided to `#match`, and
16
- # whether the pattern contained any "captures" (values which are extracted
17
- # from a matching AST.)
18
- #
19
- # - With block: #match yields the captures (if any) and passes the return
20
- # value of the block through.
21
- # - With no block, but one capture: the capture is returned.
22
- # - With no block, but multiple captures: captures are returned as an array.
23
- # - With no block and no captures: #match returns `true`.
24
- #
25
- # ## Pattern string format examples
26
- #
27
- # ':sym' # matches a literal symbol
28
- # '1' # matches a literal integer
29
- # 'nil' # matches a literal nil
30
- # 'send' # matches (send ...)
31
- # '(send)' # matches (send)
32
- # '(send ...)' # matches (send ...)
33
- # '(op-asgn)' # node types with hyphenated names also work
34
- # '{send class}' # matches (send ...) or (class ...)
35
- # '({send class})' # matches (send) or (class)
36
- # '(send const)' # matches (send (const ...))
37
- # '(send _ :new)' # matches (send <anything> :new)
38
- # '(send $_ :new)' # as above, but whatever matches the $_ is captured
39
- # '(send $_ $_)' # you can use as many captures as you want
40
- # '(send !const ...)' # ! negates the next part of the pattern
41
- # '$(send const ...)' # arbitrary matching can be performed on a capture
42
- # '(send _recv _msg)' # wildcards can be named (for readability)
43
- # '(send ... :new)' # you can match against the last children
44
- # '(array <str sym>)' # you can match children in any order. This
45
- # # would match `['x', :y]` as well as `[:y, 'x']
46
- # '(_ <str sym ...>)' # will match if arguments have at least a `str` and
47
- # # a `sym` node, but can have more.
48
- # '(array <$str $_>)' # captures are in the order of the pattern,
49
- # # irrespective of the actual order of the children
50
- # '(array int*)' # will match an array of 0 or more integers
51
- # '(array int ?)' # will match 0 or 1 integer.
52
- # # Note: Space needed to distinguish from int?
53
- # '(array int+)' # will match an array of 1 or more integers
54
- # '(array (int $_)+)' # as above and will capture the numbers in an array
55
- # '(send $...)' # capture all the children as an array
56
- # '(send $... int)' # capture all children but the last as an array
57
- # '(send _x :+ _x)' # unification is performed on named wildcards
58
- # # (like Prolog variables...)
59
- # # (#== is used to see if values unify)
60
- # '(int odd?)' # words which end with a ? are predicate methods,
61
- # # are are called on the target to see if it matches
62
- # # any Ruby method which the matched object supports
63
- # # can be used
64
- # # if a truthy value is returned, the match succeeds
65
- # '(int [!1 !2])' # [] contains multiple patterns, ALL of which must
66
- # # match in that position
67
- # # in other words, while {} is pattern union (logical
68
- # # OR), [] is intersection (logical AND)
69
- # '(send %1 _)' # % stands for a parameter which must be supplied to
70
- # # #match at matching time
71
- # # it will be compared to the corresponding value in
72
- # # the AST using #==
73
- # # a bare '%' is the same as '%1'
74
- # # the number of extra parameters passed to #match
75
- # # must equal the highest % value in the pattern
76
- # # for consistency, %0 is the 'root node' which is
77
- # # passed as the 1st argument to #match, where the
78
- # # matching process starts
79
- # '^^send' # each ^ ascends one level in the AST
80
- # # so this matches against the grandparent node
81
- # '#method' # we call this a 'funcall'; it calls a method in the
82
- # # context where a pattern-matching method is defined
83
- # # if that returns a truthy value, the match succeeds
84
- # 'equal?(%1)' # predicates can be given 1 or more extra args
85
- # '#method(%0, 1)' # funcalls can also be given 1 or more extra args
86
- #
87
- # You can nest arbitrarily deep:
88
- #
89
- # # matches node parsed from 'Const = Class.new' or 'Const = Module.new':
90
- # '(casgn nil? :Const (send (const nil? {:Class :Module}) :new))'
91
- # # matches a node parsed from an 'if', with a '==' comparison,
92
- # # and no 'else' branch:
93
- # '(if (send _ :== _) _ nil?)'
94
- #
95
- # Note that patterns like 'send' are implemented by calling `#send_type?` on
96
- # the node being matched, 'const' by `#const_type?`, 'int' by `#int_type?`,
97
- # and so on. Therefore, if you add methods which are named like
98
- # `#prefix_type?` to the AST node class, then 'prefix' will become usable as
99
- # a pattern.
100
- #
101
- # Also note that if you need a "guard clause" to protect against possible nils
102
- # in a certain place in the AST, you can do it like this: `[!nil <pattern>]`
103
- #
104
- # The compiler code is very simple; don't be afraid to read through it!
105
- class NodePattern
106
- # @private
107
- Invalid = Class.new(StandardError)
108
-
109
- # @private
110
- # Builds Ruby code which implements a pattern
111
- class Compiler
112
- SYMBOL = %r{:(?:[\w+@*/?!<>=~|%^-]+|\[\]=?)}.freeze
113
- IDENTIFIER = /[a-zA-Z_][a-zA-Z0-9_-]*/.freeze
114
- META = Regexp.union(
115
- %w"( ) { } [ ] $< < > $... $ ! ^ ... + * ?"
116
- ).freeze
117
- NUMBER = /-?\d+(?:\.\d+)?/.freeze
118
- STRING = /".+?"/.freeze
119
- METHOD_NAME = /\#?#{IDENTIFIER}[\!\?]?\(?/.freeze
120
- PARAM_NUMBER = /%\d*/.freeze
121
-
122
- SEPARATORS = /[\s]+/.freeze
123
- TOKENS = Regexp.union(META, PARAM_NUMBER, NUMBER,
124
- METHOD_NAME, SYMBOL, STRING)
125
-
126
- TOKEN = /\G(?:#{SEPARATORS}|#{TOKENS}|.)/.freeze
127
-
128
- NODE = /\A#{IDENTIFIER}\Z/.freeze
129
- PREDICATE = /\A#{IDENTIFIER}\?\(?\Z/.freeze
130
- WILDCARD = /\A_(?:#{IDENTIFIER})?\Z/.freeze
131
-
132
- FUNCALL = /\A\##{METHOD_NAME}/.freeze
133
- LITERAL = /\A(?:#{SYMBOL}|#{NUMBER}|#{STRING})\Z/.freeze
134
- PARAM = /\A#{PARAM_NUMBER}\Z/.freeze
135
- CLOSING = /\A(?:\)|\}|\])\Z/.freeze
136
-
137
- REST = '...'
138
- CAPTURED_REST = '$...'
139
-
140
- attr_reader :match_code, :tokens, :captures
141
-
142
- SEQ_HEAD_INDEX = -1
143
-
144
- # Placeholders while compiling, see with_..._context methods
145
- CUR_PLACEHOLDER = '@@@cur'
146
- CUR_NODE = "#{CUR_PLACEHOLDER} node@@@"
147
- CUR_ELEMENT = "#{CUR_PLACEHOLDER} element@@@"
148
- SEQ_HEAD_GUARD = '@@@seq guard head@@@'
149
-
150
- line = __LINE__
151
- ANY_ORDER_TEMPLATE = ERB.new <<~RUBY.gsub("-%>\n", '%>')
152
- <% if capture_rest %>(<%= capture_rest %> = []) && <% end -%>
153
- <% if capture_all %>(<%= capture_all %> = <% end -%>
154
- <%= CUR_NODE %>.children[<%= range %>]<% if capture_all %>)<% end -%>
155
- .each_with_object({}) { |<%= child %>, <%= matched %>|
156
- case
157
- <% patterns.each_with_index do |pattern, i| -%>
158
- when !<%= matched %>[<%= i %>] && <%=
159
- with_context(pattern, child, use_temp_node: false)
160
- %> then <%= matched %>[<%= i %>] = true
161
- <% end -%>
162
- <% if !rest %> else break({})
163
- <% elsif capture_rest %> else <%= capture_rest %> << <%= child %>
164
- <% end -%>
165
- end
166
- }.size == <%= patterns.size -%>
167
- RUBY
168
- ANY_ORDER_TEMPLATE.location = [__FILE__, line + 1]
169
-
170
- line = __LINE__
171
- REPEATED_TEMPLATE = ERB.new <<~RUBY.gsub("-%>\n", '%>')
172
- <% if captured %>(<%= accumulate %> = Array.new) && <% end %>
173
- <%= CUR_NODE %>.children[<%= range %>].all? do |<%= child %>|
174
- <%= with_context(expr, child, use_temp_node: false) %><% if captured %>&&
175
- <%= accumulate %>.push(<%= captured %>)<% end %>
176
- end <% if captured %>&&
177
- (<%= captured %> = if <%= accumulate %>.empty?
178
- <%= captured %>.map{[]} # Transpose hack won't work for empty case
179
- else
180
- <%= accumulate %>.transpose
181
- end) <% end -%>
182
- RUBY
183
- REPEATED_TEMPLATE.location = [__FILE__, line + 1]
184
-
185
- def initialize(str, node_var = 'node0')
186
- @string = str
187
- @root = node_var
188
-
189
- @temps = 0 # avoid name clashes between temp variables
190
- @captures = 0 # number of captures seen
191
- @unify = {} # named wildcard -> temp variable number
192
- @params = 0 # highest % (param) number seen
193
- run(node_var)
194
- end
195
-
196
- def run(node_var)
197
- @tokens = Compiler.tokens(@string)
198
-
199
- @match_code = with_context(compile_expr, node_var, use_temp_node: false)
200
- @match_code.prepend("(captures = Array.new(#{@captures})) && ") \
201
- if @captures.positive?
202
-
203
- fail_due_to('unbalanced pattern') unless tokens.empty?
204
- end
205
-
206
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
207
- def compile_expr(token = tokens.shift)
208
- # read a single pattern-matching expression from the token stream,
209
- # return Ruby code which performs the corresponding matching operation
210
- #
211
- # the 'pattern-matching' expression may be a composite which
212
- # contains an arbitrary number of sub-expressions, but that composite
213
- # must all have precedence higher or equal to that of `&&`
214
- #
215
- # Expressions may use placeholders like:
216
- # CUR_NODE: Ruby code that evaluates to an AST node
217
- # CUR_ELEMENT: Either the node or the type if in first element of
218
- # a sequence (aka seq_head, e.g. "(seq_head first_node_arg ...")
219
- case token
220
- when '(' then compile_seq
221
- when '{' then compile_union
222
- when '[' then compile_intersect
223
- when '!' then compile_negation
224
- when '$' then compile_capture
225
- when '^' then compile_ascend
226
- when WILDCARD then compile_wildcard(token[1..-1])
227
- when FUNCALL then compile_funcall(token)
228
- when LITERAL then compile_literal(token)
229
- when PREDICATE then compile_predicate(token)
230
- when NODE then compile_nodetype(token)
231
- when PARAM then compile_param(token[1..-1])
232
- when CLOSING then fail_due_to("#{token} in invalid position")
233
- when nil then fail_due_to('pattern ended prematurely')
234
- else fail_due_to("invalid token #{token.inspect}")
235
- end
236
- end
237
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
238
-
239
- def tokens_until(stop, what)
240
- return to_enum __method__, stop, what unless block_given?
241
-
242
- fail_due_to("empty #{what}") if tokens.first == stop && what
243
- yield until tokens.first == stop
244
- tokens.shift
245
- end
246
-
247
- def compile_seq
248
- terms = tokens_until(')', 'sequence').map { variadic_seq_term }
249
- Sequence.new(self, *terms).compile
250
- end
251
-
252
- def compile_guard_clause
253
- "#{CUR_NODE}.is_a?(RuboCop::AST::Node)"
254
- end
255
-
256
- def variadic_seq_term
257
- token = tokens.shift
258
- case token
259
- when CAPTURED_REST then compile_captured_ellipsis
260
- when REST then compile_ellipsis
261
- when '$<' then compile_any_order(next_capture)
262
- when '<' then compile_any_order
263
- else compile_repeated_expr(token)
264
- end
265
- end
266
-
267
- def compile_repeated_expr(token)
268
- before = @captures
269
- expr = compile_expr(token)
270
- min, max = parse_repetition_token
271
- return [1, expr] if min.nil?
272
-
273
- if @captures != before
274
- captured = "captures[#{before}...#{@captures}]"
275
- accumulate = next_temp_variable(:accumulate)
276
- end
277
- arity = min..max || Float::INFINITY
278
-
279
- [arity, repeated_generator(expr, captured, accumulate)]
280
- end
281
-
282
- def repeated_generator(expr, captured, accumulate)
283
- with_temp_variables do |child|
284
- lambda do |range|
285
- if range.begin == SEQ_HEAD_INDEX
286
- fail_due_to 'repeated pattern at beginning of sequence'
287
- end
288
- REPEATED_TEMPLATE.result(binding)
289
- end
290
- end
291
- end
292
-
293
- def parse_repetition_token
294
- case tokens.first
295
- when '*' then min = 0
296
- when '+' then min = 1
297
- when '?' then min = 0
298
- max = 1
299
- else return
300
- end
301
- tokens.shift
302
- [min, max]
303
- end
304
-
305
- # @private
306
- # Builds Ruby code for a sequence
307
- # (head *first_terms variadic_term *last_terms)
308
- class Sequence < SimpleDelegator
309
- def initialize(compiler, *arity_term_list)
310
- @arities, @terms = arity_term_list.transpose
311
-
312
- super(compiler)
313
- @variadic_index = @arities.find_index { |a| a.is_a?(Range) }
314
- fail_due_to 'multiple variable patterns in same sequence' \
315
- if @variadic_index && !@arities.one? { |a| a.is_a?(Range) }
316
- end
317
-
318
- def compile
319
- [
320
- compile_guard_clause,
321
- compile_child_nb_guard,
322
- compile_seq_head,
323
- *compile_first_terms,
324
- compile_variadic_term,
325
- *compile_last_terms
326
- ].compact.join(" &&\n") << SEQ_HEAD_GUARD
327
- end
328
-
329
- private
330
-
331
- def first_terms_arity
332
- first_terms_range { |r| @arities[r].inject(0, :+) } || 0
333
- end
334
-
335
- def last_terms_arity
336
- last_terms_range { |r| @arities[r].inject(0, :+) } || 0
337
- end
338
-
339
- def variadic_term_min_arity
340
- @variadic_index ? @arities[@variadic_index].begin : 0
341
- end
342
-
343
- def first_terms_range
344
- yield 1..(@variadic_index || @terms.size) - 1 if seq_head?
345
- end
346
-
347
- def last_terms_range
348
- yield @variadic_index + 1...@terms.size if @variadic_index
349
- end
350
-
351
- def seq_head?
352
- @variadic_index != 0
353
- end
354
-
355
- def compile_child_nb_guard
356
- fixed = first_terms_arity + last_terms_arity
357
- min = fixed + variadic_term_min_arity
358
- op = if @variadic_index
359
- max_variadic = @arities[@variadic_index].end
360
- if max_variadic != Float::INFINITY
361
- range = min..fixed + max_variadic
362
- return "(#{range}).cover?(#{CUR_NODE}.children.size)"
363
- end
364
- '>='
365
- else
366
- '=='
367
- end
368
- "#{CUR_NODE}.children.size #{op} #{min}"
369
- end
370
-
371
- def term(index, range)
372
- t = @terms[index]
373
- if t.respond_to? :call
374
- t.call(range)
375
- else
376
- with_child_context(t, range.begin)
377
- end
378
- end
379
-
380
- def compile_seq_head
381
- return unless seq_head?
382
-
383
- fail_due_to 'sequences cannot start with <' \
384
- if @terms[0].respond_to? :call
385
-
386
- with_seq_head_context(@terms[0])
387
- end
388
-
389
- def compile_first_terms
390
- first_terms_range { |range| compile_terms(range, 0) }
391
- end
392
-
393
- def compile_last_terms
394
- last_terms_range { |r| compile_terms(r, -last_terms_arity) }
395
- end
396
-
397
- def compile_terms(index_range, start)
398
- index_range.map do |i|
399
- current = start
400
- start += @arities.fetch(i)
401
- term(i, current..start - 1)
402
- end
403
- end
404
-
405
- def compile_variadic_term
406
- variadic_arity { |arity| term(@variadic_index, arity) }
407
- end
408
-
409
- def variadic_arity
410
- return unless @variadic_index
411
-
412
- first = @variadic_index.positive? ? first_terms_arity : SEQ_HEAD_INDEX
413
- yield first..-last_terms_arity - 1
414
- end
415
- end
416
- private_constant :Sequence
417
-
418
- def compile_captured_ellipsis
419
- capture = next_capture
420
- block = lambda { |range|
421
- # Consider ($...) like (_ $...):
422
- range = 0..range.end if range.begin == SEQ_HEAD_INDEX
423
- "(#{capture} = #{CUR_NODE}.children[#{range}])"
424
- }
425
- [0..Float::INFINITY, block]
426
- end
427
-
428
- def compile_ellipsis
429
- [0..Float::INFINITY, 'true']
430
- end
431
-
432
- # rubocop:disable Metrics/AbcSize
433
- # rubocop:disable Metrics/MethodLength
434
- def compile_any_order(capture_all = nil)
435
- rest = capture_rest = nil
436
- patterns = []
437
- with_temp_variables do |child, matched|
438
- tokens_until('>', 'any child') do
439
- fail_due_to 'ellipsis must be at the end of <>' if rest
440
- token = tokens.shift
441
- case token
442
- when CAPTURED_REST then rest = capture_rest = next_capture
443
- when REST then rest = true
444
- else patterns << compile_expr(token)
445
- end
446
- end
447
- [rest ? patterns.size..Float::INFINITY : patterns.size,
448
- ->(range) { ANY_ORDER_TEMPLATE.result(binding) }]
449
- end
450
- end
451
- # rubocop:enable Metrics/MethodLength
452
- # rubocop:enable Metrics/AbcSize
453
-
454
- def insure_same_captures(enum, what)
455
- return to_enum __method__, enum, what unless block_given?
456
-
457
- captures_before = captures_after = nil
458
- enum.each do
459
- captures_before ||= @captures
460
- @captures = captures_before
461
- yield
462
- captures_after ||= @captures
463
- if captures_after != @captures
464
- fail_due_to("each #{what} must have same # of captures")
465
- end
466
- end
467
- end
468
-
469
- def compile_union
470
- # we need to ensure that each branch of the {} contains the same
471
- # number of captures (since only one branch of the {} can actually
472
- # match, the same variables are used to hold the captures for each
473
- # branch)
474
- enum = tokens_until('}', 'union')
475
- terms = insure_same_captures(enum, 'branch of {}')
476
- .map { compile_expr }
477
-
478
- "(#{terms.join(' || ')})"
479
- end
480
-
481
- def compile_intersect
482
- tokens_until(']', 'intersection')
483
- .map { compile_expr }
484
- .join(' && ')
485
- end
486
-
487
- def compile_capture
488
- "(#{next_capture} = #{CUR_ELEMENT}; #{compile_expr})"
489
- end
490
-
491
- def compile_negation
492
- "!(#{compile_expr})"
493
- end
494
-
495
- def compile_ascend
496
- with_context("#{CUR_NODE} && #{compile_expr}", "#{CUR_NODE}.parent")
497
- end
498
-
499
- def compile_wildcard(name)
500
- if name.empty?
501
- 'true'
502
- elsif @unify.key?(name)
503
- # we have already seen a wildcard with this name before
504
- # so the value it matched the first time will already be stored
505
- # in a temp. check if this value matches the one stored in the temp
506
- "#{CUR_ELEMENT} == temp#{@unify[name]}"
507
- else
508
- n = @unify[name] = next_temp_value
509
- # double assign to temp#{n} to avoid "assigned but unused variable"
510
- "(temp#{n} = #{CUR_ELEMENT}; " \
511
- "temp#{n} = temp#{n}; true)"
512
- end
513
- end
514
-
515
- def compile_literal(literal)
516
- "#{CUR_ELEMENT} == #{literal}"
517
- end
518
-
519
- def compile_predicate(predicate)
520
- if predicate.end_with?('(') # is there an arglist?
521
- args = compile_args(tokens)
522
- predicate = predicate[0..-2] # drop the trailing (
523
- "#{CUR_ELEMENT}.#{predicate}(#{args.join(',')})"
524
- else
525
- "#{CUR_ELEMENT}.#{predicate}"
526
- end
527
- end
528
-
529
- def compile_funcall(method)
530
- # call a method in the context which this pattern-matching
531
- # code is used in. pass target value as an argument
532
- method = method[1..-1] # drop the leading #
533
- if method.end_with?('(') # is there an arglist?
534
- args = compile_args(tokens)
535
- method = method[0..-2] # drop the trailing (
536
- "#{method}(#{CUR_ELEMENT},#{args.join(',')})"
537
- else
538
- "#{method}(#{CUR_ELEMENT})"
539
- end
540
- end
541
-
542
- def compile_nodetype(type)
543
- "#{compile_guard_clause} && #{CUR_NODE}.#{type.tr('-', '_')}_type?"
544
- end
545
-
546
- def compile_param(number)
547
- "#{CUR_ELEMENT} == #{get_param(number)}"
548
- end
549
-
550
- def compile_args(tokens)
551
- index = tokens.find_index { |token| token == ')' }
552
-
553
- tokens.slice!(0..index).each_with_object([]) do |token, args|
554
- next if [')', ','].include?(token)
555
-
556
- args << compile_arg(token)
557
- end
558
- end
559
-
560
- def compile_arg(token)
561
- case token
562
- when WILDCARD then
563
- name = token[1..-1]
564
- number = @unify[name] || fail_due_to('invalid in arglist: ' + token)
565
- "temp#{number}"
566
- when LITERAL then token
567
- when PARAM then get_param(token[1..-1])
568
- when CLOSING then fail_due_to("#{token} in invalid position")
569
- when nil then fail_due_to('pattern ended prematurely')
570
- else fail_due_to("invalid token in arglist: #{token.inspect}")
571
- end
572
- end
573
-
574
- def next_capture
575
- index = @captures
576
- @captures += 1
577
- "captures[#{index}]"
578
- end
579
-
580
- def get_param(number)
581
- number = number.empty? ? 1 : Integer(number)
582
- @params = number if number > @params
583
- number.zero? ? @root : "param#{number}"
584
- end
585
-
586
- def emit_yield_capture(when_no_capture = '')
587
- yield_val = if @captures.zero?
588
- when_no_capture
589
- elsif @captures == 1
590
- 'captures[0]' # Circumvent https://github.com/jruby/jruby/issues/5710
591
- else
592
- '*captures'
593
- end
594
- "yield(#{yield_val})"
595
- end
596
-
597
- def emit_retval
598
- if @captures.zero?
599
- 'true'
600
- elsif @captures == 1
601
- 'captures[0]'
602
- else
603
- 'captures'
604
- end
605
- end
606
-
607
- def emit_param_list
608
- (1..@params).map { |n| "param#{n}" }.join(',')
609
- end
610
-
611
- def emit_trailing_params
612
- params = emit_param_list
613
- params.empty? ? '' : ",#{params}"
614
- end
615
-
616
- def emit_method_code
617
- <<~RUBY
618
- return unless #{@match_code}
619
- block_given? ? #{emit_yield_capture} : (return #{emit_retval})
620
- RUBY
621
- end
622
-
623
- def fail_due_to(message)
624
- raise Invalid, "Couldn't compile due to #{message}. Pattern: #{@string}"
625
- end
626
-
627
- def with_temp_node(cur_node)
628
- with_temp_variables do |node|
629
- yield "(#{node} = #{cur_node})", node
630
- end
631
- .gsub("\n", "\n ") # Nicer indent for debugging
632
- end
633
-
634
- def with_temp_variables(&block)
635
- names = block.parameters.map { |_, name| next_temp_variable(name) }
636
- yield(*names)
637
- end
638
-
639
- def next_temp_variable(name)
640
- "#{name}#{next_temp_value}"
641
- end
642
-
643
- def next_temp_value
644
- @temps += 1
645
- end
646
-
647
- def auto_use_temp_node?(code)
648
- code.scan(CUR_PLACEHOLDER).count > 1
649
- end
650
-
651
- # with_<...>_context methods are used whenever the context,
652
- # i.e the current node or the current element can be determined.
653
-
654
- def with_child_context(code, child_index)
655
- with_context(code, "#{CUR_NODE}.children[#{child_index}]")
656
- end
657
-
658
- def with_context(code, cur_node,
659
- use_temp_node: auto_use_temp_node?(code))
660
- if use_temp_node
661
- with_temp_node(cur_node) do |init, temp_var|
662
- substitute_cur_node(code, temp_var, first_cur_node: init)
663
- end
664
- else
665
- substitute_cur_node(code, cur_node)
666
- end
667
- end
668
-
669
- def with_seq_head_context(code)
670
- if code.include?(SEQ_HEAD_GUARD)
671
- fail_due_to('parentheses at sequence head')
672
- end
673
-
674
- code.gsub CUR_ELEMENT, "#{CUR_NODE}.type"
675
- end
676
-
677
- def substitute_cur_node(code, cur_node, first_cur_node: cur_node)
678
- iter = 0
679
- code
680
- .gsub(CUR_ELEMENT, CUR_NODE)
681
- .gsub(CUR_NODE) do
682
- iter += 1
683
- iter == 1 ? first_cur_node : cur_node
684
- end
685
- .gsub(SEQ_HEAD_GUARD, '')
686
- end
687
-
688
- def self.tokens(pattern)
689
- pattern.scan(TOKEN).reject { |token| token =~ /\A#{SEPARATORS}\Z/ }
690
- end
691
- end
692
- private_constant :Compiler
693
-
694
- # Helpers for defining methods based on a pattern string
695
- module Macros
696
- # Define a method which applies a pattern to an AST node
697
- #
698
- # The new method will return nil if the node does not match
699
- # If the node matches, and a block is provided, the new method will
700
- # yield to the block (passing any captures as block arguments).
701
- # If the node matches, and no block is provided, the new method will
702
- # return the captures, or `true` if there were none.
703
- def def_node_matcher(method_name, pattern_str)
704
- compiler = Compiler.new(pattern_str, 'node')
705
- src = "def #{method_name}(node = self" \
706
- "#{compiler.emit_trailing_params});" \
707
- "#{compiler.emit_method_code};end"
708
-
709
- location = caller_locations(1, 1).first
710
- class_eval(src, location.path, location.lineno)
711
- end
712
-
713
- # Define a method which recurses over the descendants of an AST node,
714
- # checking whether any of them match the provided pattern
715
- #
716
- # If the method name ends with '?', the new method will return `true`
717
- # as soon as it finds a descendant which matches. Otherwise, it will
718
- # yield all descendants which match.
719
- def def_node_search(method_name, pattern_str)
720
- compiler = Compiler.new(pattern_str, 'node')
721
- called_from = caller(1..1).first.split(':')
722
-
723
- if method_name.to_s.end_with?('?')
724
- node_search_first(method_name, compiler, called_from)
725
- else
726
- node_search_all(method_name, compiler, called_from)
727
- end
728
- end
729
-
730
- def node_search_first(method_name, compiler, called_from)
731
- node_search(method_name, compiler, 'return true', '', called_from)
732
- end
733
-
734
- def node_search_all(method_name, compiler, called_from)
735
- yield_code = compiler.emit_yield_capture('node')
736
- prelude = "return enum_for(:#{method_name}, node0" \
737
- "#{compiler.emit_trailing_params}) unless block_given?"
738
-
739
- node_search(method_name, compiler, yield_code, prelude, called_from)
740
- end
741
-
742
- def node_search(method_name, compiler, on_match, prelude, called_from)
743
- src = node_search_body(method_name, compiler.emit_trailing_params,
744
- prelude, compiler.match_code, on_match)
745
- filename, lineno = *called_from
746
- class_eval(src, filename, lineno.to_i)
747
- end
748
-
749
- def node_search_body(method_name, trailing_params, prelude, match_code,
750
- on_match)
751
- <<~RUBY
752
- def #{method_name}(node0#{trailing_params})
753
- #{prelude}
754
- node0.each_node do |node|
755
- if #{match_code}
756
- #{on_match}
757
- end
758
- end
759
- nil
760
- end
761
- RUBY
762
- end
763
- end
764
-
765
- attr_reader :pattern
766
-
767
- def initialize(str)
768
- @pattern = str
769
- compiler = Compiler.new(str)
770
- src = "def match(node0#{compiler.emit_trailing_params});" \
771
- "#{compiler.emit_method_code}end"
772
- instance_eval(src, __FILE__, __LINE__ + 1)
773
- end
774
-
775
- def match(*args)
776
- # If we're here, it's because the singleton method has not been defined,
777
- # either because we've been dup'ed or serialized through YAML
778
- initialize(pattern)
779
- match(*args)
780
- end
781
-
782
- def marshal_load(pattern)
783
- initialize pattern
784
- end
785
-
786
- def marshal_dump
787
- pattern
788
- end
789
-
790
- def ==(other)
791
- other.is_a?(NodePattern) &&
792
- Compiler.tokens(other.pattern) == Compiler.tokens(pattern)
793
- end
794
- alias eql? ==
795
-
796
- def to_s
797
- "#<#{self.class} #{pattern}>"
798
- end
799
- end
800
- end
801
- # rubocop:enable Metrics/ClassLength, Metrics/CyclomaticComplexity