rubocop 0.52.1 → 0.53.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 (292) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +118 -46
  5. data/config/disabled.yml +8 -8
  6. data/config/enabled.yml +84 -28
  7. data/lib/rubocop.rb +28 -8
  8. data/lib/rubocop/ast/builder.rb +35 -37
  9. data/lib/rubocop/ast/node.rb +16 -1
  10. data/lib/rubocop/ast/node/and_node.rb +0 -8
  11. data/lib/rubocop/ast/node/block_node.rb +1 -9
  12. data/lib/rubocop/ast/node/case_node.rb +0 -8
  13. data/lib/rubocop/ast/node/ensure_node.rb +0 -8
  14. data/lib/rubocop/ast/node/for_node.rb +0 -8
  15. data/lib/rubocop/ast/node/or_node.rb +0 -8
  16. data/lib/rubocop/ast/node/pair_node.rb +0 -8
  17. data/lib/rubocop/ast/node/resbody_node.rb +0 -8
  18. data/lib/rubocop/ast/node/send_node.rb +0 -8
  19. data/lib/rubocop/ast/node/symbol_node.rb +0 -8
  20. data/lib/rubocop/ast/node/until_node.rb +0 -8
  21. data/lib/rubocop/ast/node/when_node.rb +0 -8
  22. data/lib/rubocop/ast/node/while_node.rb +0 -8
  23. data/lib/rubocop/cli.rb +17 -7
  24. data/lib/rubocop/comment_config.rb +24 -3
  25. data/lib/rubocop/config.rb +75 -6
  26. data/lib/rubocop/config_loader.rb +18 -28
  27. data/lib/rubocop/config_loader_resolver.rb +61 -9
  28. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +4 -2
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/commissioner.rb +2 -2
  32. data/lib/rubocop/cop/cop.rb +4 -0
  33. data/lib/rubocop/cop/corrector.rb +11 -1
  34. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  35. data/lib/rubocop/cop/correctors/line_break_corrector.rb +59 -0
  36. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -1
  37. data/lib/rubocop/cop/correctors/space_corrector.rb +13 -0
  38. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -1
  40. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  41. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -5
  42. data/lib/rubocop/cop/generator.rb +29 -8
  43. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +2 -0
  44. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -0
  45. data/lib/rubocop/cop/layout/align_hash.rb +106 -37
  46. data/lib/rubocop/cop/{lint → layout}/block_alignment.rb +8 -5
  47. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -17
  48. data/lib/rubocop/cop/layout/case_indentation.rb +1 -0
  49. data/lib/rubocop/cop/layout/class_structure.rb +6 -7
  50. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  51. data/lib/rubocop/cop/{lint → layout}/condition_position.rb +3 -3
  52. data/lib/rubocop/cop/{lint → layout}/def_end_alignment.rb +2 -1
  53. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  54. data/lib/rubocop/cop/layout/empty_comment.rb +140 -0
  55. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -0
  56. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -0
  57. data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
  58. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -5
  59. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +20 -10
  60. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +20 -0
  61. data/lib/rubocop/cop/{lint → layout}/end_alignment.rb +37 -6
  62. data/lib/rubocop/cop/layout/end_of_line.rb +1 -0
  63. data/lib/rubocop/cop/layout/extra_spacing.rb +30 -37
  64. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -0
  65. data/lib/rubocop/cop/layout/indent_heredoc.rb +38 -2
  66. data/lib/rubocop/cop/layout/indentation_consistency.rb +105 -1
  67. data/lib/rubocop/cop/layout/indentation_width.rb +4 -3
  68. data/lib/rubocop/cop/layout/initial_indentation.rb +15 -1
  69. data/lib/rubocop/cop/layout/leading_comment_space.rb +4 -2
  70. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -0
  71. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  72. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +62 -29
  73. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  74. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +74 -33
  75. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +16 -2
  76. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -1
  77. data/lib/rubocop/cop/layout/space_after_method_name.rb +2 -0
  78. data/lib/rubocop/cop/layout/space_after_not.rb +2 -0
  79. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -0
  80. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +15 -2
  81. data/lib/rubocop/cop/layout/space_around_operators.rb +15 -13
  82. data/lib/rubocop/cop/layout/space_before_block_braces.rb +13 -1
  83. data/lib/rubocop/cop/layout/space_before_comment.rb +6 -4
  84. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -0
  85. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  86. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +30 -45
  87. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -2
  88. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +48 -18
  89. data/lib/rubocop/cop/layout/space_inside_parens.rb +8 -7
  90. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +57 -11
  91. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +1 -0
  92. data/lib/rubocop/cop/layout/tab.rb +42 -16
  93. data/lib/rubocop/cop/layout/trailing_blank_lines.rb +46 -13
  94. data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -0
  95. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +5 -3
  96. data/lib/rubocop/cop/lint/big_decimal_new.rb +44 -0
  97. data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -2
  98. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -2
  99. data/lib/rubocop/cop/lint/debugger.rb +2 -2
  100. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +5 -4
  101. data/lib/rubocop/cop/lint/duplicate_methods.rb +20 -9
  102. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -3
  103. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +16 -10
  104. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +5 -4
  105. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  106. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  107. data/lib/rubocop/cop/lint/literal_as_condition.rb +2 -2
  108. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +2 -0
  109. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +7 -5
  110. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  111. data/lib/rubocop/cop/lint/number_conversion.rb +59 -0
  112. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +86 -0
  113. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -0
  114. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -2
  115. data/lib/rubocop/cop/lint/rand_one.rb +2 -2
  116. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -0
  117. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -0
  118. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -0
  119. data/lib/rubocop/cop/lint/rescue_type.rb +6 -3
  120. data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -2
  121. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -21
  122. data/lib/rubocop/cop/lint/script_permission.rb +30 -10
  123. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
  124. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -0
  125. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
  126. data/lib/rubocop/cop/lint/unified_integer.rb +2 -2
  127. data/lib/rubocop/cop/lint/{unneeded_disable.rb → unneeded_cop_disable_directive.rb} +13 -7
  128. data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +97 -0
  129. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -0
  130. data/lib/rubocop/cop/lint/unreachable_code.rb +3 -3
  131. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +11 -10
  132. data/lib/rubocop/cop/lint/useless_access_modifier.rb +7 -5
  133. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -2
  134. data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
  135. data/lib/rubocop/cop/lint/void.rb +49 -10
  136. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  137. data/lib/rubocop/cop/metrics/line_length.rb +5 -2
  138. data/lib/rubocop/cop/mixin/alignment.rb +4 -0
  139. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -1
  140. data/lib/rubocop/cop/mixin/def_node.rb +4 -0
  141. data/lib/rubocop/cop/mixin/documentation_comment.rb +11 -3
  142. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -2
  143. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +20 -1
  144. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  145. data/lib/rubocop/cop/mixin/hash_alignment.rb +2 -2
  146. data/lib/rubocop/cop/mixin/match_range.rb +2 -0
  147. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +6 -0
  148. data/lib/rubocop/cop/mixin/nil_methods.rb +19 -0
  149. data/lib/rubocop/cop/mixin/percent_literal.rb +57 -9
  150. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -5
  151. data/lib/rubocop/cop/mixin/range_help.rb +102 -0
  152. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -1
  153. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +8 -7
  154. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +11 -9
  155. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -10
  156. data/lib/rubocop/cop/mixin/surrounding_space.rb +38 -8
  157. data/lib/rubocop/cop/mixin/trailing_body.rb +26 -0
  158. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  159. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +104 -0
  160. data/lib/rubocop/cop/naming/ascii_identifiers.rb +3 -1
  161. data/lib/rubocop/cop/naming/file_name.rb +5 -10
  162. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +76 -0
  163. data/lib/rubocop/cop/naming/uncommunicative_block_param_name.rb +48 -0
  164. data/lib/rubocop/cop/naming/uncommunicative_method_param_name.rb +57 -0
  165. data/lib/rubocop/cop/offense.rb +3 -2
  166. data/lib/rubocop/cop/performance/case_when_splat.rb +1 -0
  167. data/lib/rubocop/cop/performance/casecmp.rb +17 -8
  168. data/lib/rubocop/cop/performance/compare_with_block.rb +2 -0
  169. data/lib/rubocop/cop/performance/count.rb +1 -0
  170. data/lib/rubocop/cop/performance/fixed_size.rb +41 -0
  171. data/lib/rubocop/cop/performance/flat_map.rb +2 -0
  172. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -0
  173. data/lib/rubocop/cop/performance/redundant_merge.rb +1 -1
  174. data/lib/rubocop/cop/performance/redundant_sort_by.rb +2 -0
  175. data/lib/rubocop/cop/performance/regexp_match.rb +4 -0
  176. data/lib/rubocop/cop/performance/reverse_each.rb +2 -0
  177. data/lib/rubocop/cop/performance/string_replacement.rb +2 -0
  178. data/lib/rubocop/cop/rails/active_record_aliases.rb +46 -0
  179. data/lib/rubocop/cop/rails/blank.rb +3 -3
  180. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +6 -0
  181. data/lib/rubocop/cop/rails/delegate.rb +6 -6
  182. data/lib/rubocop/cop/rails/file_path.rb +7 -1
  183. data/lib/rubocop/cop/rails/find_by.rb +2 -0
  184. data/lib/rubocop/cop/rails/http_positional_arguments.rb +17 -5
  185. data/lib/rubocop/cop/rails/inverse_of.rb +21 -2
  186. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +45 -9
  187. data/lib/rubocop/cop/rails/presence.rb +8 -2
  188. data/lib/rubocop/cop/rails/present.rb +5 -5
  189. data/lib/rubocop/cop/rails/read_write_attribute.rb +4 -3
  190. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -0
  191. data/lib/rubocop/cop/rails/relative_date_constant.rb +4 -3
  192. data/lib/rubocop/cop/rails/request_referer.rb +3 -2
  193. data/lib/rubocop/cop/rails/reversible_migration.rb +9 -8
  194. data/lib/rubocop/cop/rails/safe_navigation.rb +3 -2
  195. data/lib/rubocop/cop/rails/save_bang.rb +11 -12
  196. data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
  197. data/lib/rubocop/cop/rails/time_zone.rb +38 -16
  198. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +26 -16
  199. data/lib/rubocop/cop/rails/validation.rb +30 -2
  200. data/lib/rubocop/cop/security/open.rb +48 -0
  201. data/lib/rubocop/cop/style/and_or.rb +1 -0
  202. data/lib/rubocop/cop/style/ascii_comments.rb +3 -1
  203. data/lib/rubocop/cop/style/attr.rb +2 -0
  204. data/lib/rubocop/cop/style/block_comments.rb +3 -1
  205. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +2 -5
  206. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
  207. data/lib/rubocop/cop/style/class_vars.rb +23 -0
  208. data/lib/rubocop/cop/style/colon_method_call.rb +1 -2
  209. data/lib/rubocop/cop/style/comment_annotation.rb +6 -4
  210. data/lib/rubocop/cop/style/commented_keyword.rb +3 -1
  211. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  212. data/lib/rubocop/cop/style/copyright.rb +3 -1
  213. data/lib/rubocop/cop/style/each_with_object.rb +15 -1
  214. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -0
  215. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -0
  216. data/lib/rubocop/cop/style/empty_else.rb +9 -5
  217. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -0
  218. data/lib/rubocop/cop/style/empty_line_after_guard_clause.rb +80 -0
  219. data/lib/rubocop/cop/style/empty_literal.rb +1 -0
  220. data/lib/rubocop/cop/style/encoding.rb +2 -0
  221. data/lib/rubocop/cop/style/expand_path_arguments.rb +194 -0
  222. data/lib/rubocop/cop/style/for.rb +33 -0
  223. data/lib/rubocop/cop/style/format_string.rb +1 -1
  224. data/lib/rubocop/cop/style/format_string_token.rb +4 -5
  225. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
  226. data/lib/rubocop/cop/style/hash_syntax.rb +1 -0
  227. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
  228. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  229. data/lib/rubocop/cop/style/lambda.rb +1 -1
  230. data/lib/rubocop/cop/style/line_end_concatenation.rb +2 -0
  231. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -0
  232. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -0
  233. data/lib/rubocop/cop/style/missing_else.rb +72 -7
  234. data/lib/rubocop/cop/style/mixin_usage.rb +3 -5
  235. data/lib/rubocop/cop/style/module_function.rb +10 -0
  236. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -0
  237. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -0
  238. data/lib/rubocop/cop/style/nested_modifier.rb +2 -0
  239. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -0
  240. data/lib/rubocop/cop/style/next.rb +1 -0
  241. data/lib/rubocop/cop/style/not.rb +2 -0
  242. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  243. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  244. data/lib/rubocop/cop/style/redundant_exception.rb +8 -3
  245. data/lib/rubocop/cop/style/redundant_return.rb +37 -3
  246. data/lib/rubocop/cop/style/redundant_self.rb +1 -1
  247. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -0
  248. data/lib/rubocop/cop/style/safe_navigation.rb +74 -32
  249. data/lib/rubocop/cop/style/semicolon.rb +3 -1
  250. data/lib/rubocop/cop/style/single_line_methods.rb +14 -23
  251. data/lib/rubocop/cop/style/stderr_puts.rb +2 -0
  252. data/lib/rubocop/cop/style/string_hash_keys.rb +12 -0
  253. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  254. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +1 -1
  255. data/lib/rubocop/cop/style/symbol_array.rb +29 -0
  256. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  257. data/lib/rubocop/cop/style/trailing_body_on_class.rb +43 -0
  258. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +7 -54
  259. data/lib/rubocop/cop/style/trailing_body_on_module.rb +43 -0
  260. data/lib/rubocop/cop/style/{trailing_comma_in_literal.rb → trailing_comma_in_array_literal.rb} +2 -20
  261. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +56 -0
  262. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +17 -20
  263. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -0
  264. data/lib/rubocop/cop/style/unless_else.rb +2 -0
  265. data/lib/rubocop/cop/style/word_array.rb +0 -1
  266. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  267. data/lib/rubocop/cop/team.rb +5 -5
  268. data/lib/rubocop/cop/util.rb +23 -188
  269. data/lib/rubocop/cop/variable_force.rb +1 -1
  270. data/lib/rubocop/file_finder.rb +45 -0
  271. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -14
  272. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  273. data/lib/rubocop/formatter/html_formatter.rb +12 -5
  274. data/lib/rubocop/formatter/json_formatter.rb +1 -1
  275. data/lib/rubocop/node_pattern.rb +8 -5
  276. data/lib/rubocop/options.rb +40 -33
  277. data/lib/rubocop/path_util.rb +5 -8
  278. data/lib/rubocop/processed_source.rb +53 -0
  279. data/lib/rubocop/remote_config.rb +1 -1
  280. data/lib/rubocop/result_cache.rb +1 -1
  281. data/lib/rubocop/rspec/cop_helper.rb +0 -4
  282. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -4
  283. data/lib/rubocop/rspec/shared_contexts.rb +3 -1
  284. data/lib/rubocop/rspec/shared_examples.rb +23 -25
  285. data/lib/rubocop/rspec/support.rb +5 -0
  286. data/lib/rubocop/runner.rb +3 -2
  287. data/lib/rubocop/string_util.rb +10 -9
  288. data/lib/rubocop/target_finder.rb +4 -1
  289. data/lib/rubocop/token.rb +26 -16
  290. data/lib/rubocop/version.rb +6 -4
  291. metadata +31 -17
  292. data/lib/rubocop/cop/performance/hash_each_methods.rb +0 -129
@@ -24,45 +24,41 @@ module RuboCop
24
24
  # x&.foo&.bar
25
25
  # x&.foo || bar
26
26
  class SafeNavigationChain < Cop
27
+ include NilMethods
27
28
  extend TargetRubyVersion
28
29
 
29
30
  MSG = 'Do not chain ordinary method call' \
30
31
  ' after safe navigation operator.'.freeze
31
32
 
32
33
  def_node_matcher :bad_method?, <<-PATTERN
33
- (send (csend ...) $_ ...)
34
+ (send $(csend ...) $_ ...)
34
35
  PATTERN
35
36
 
36
37
  minimum_target_ruby_version 2.3
37
38
 
38
39
  def on_send(node)
39
- bad_method?(node) do |method|
40
+ bad_method?(node) do |safe_nav, method|
40
41
  return if nil_methods.include?(method)
41
42
 
42
- loc = node.loc.dot || :selector
43
-
44
- add_offense(node, location: loc)
45
- end
46
- end
47
-
48
- def autocorrect(node)
49
- dot = node.loc.dot
50
-
51
- return unless dot
52
-
53
- lambda do |corrector|
54
- corrector.insert_before(dot, '&')
43
+ method_chain = method_chain(node)
44
+ location =
45
+ Parser::Source::Range.new(node.loc.expression.source_buffer,
46
+ safe_nav.loc.expression.end_pos,
47
+ method_chain.loc.expression.end_pos)
48
+ add_offense(node, location: location)
55
49
  end
56
50
  end
57
51
 
58
52
  private
59
53
 
60
- def nil_methods
61
- nil.methods + whitelist
62
- end
63
-
64
- def whitelist
65
- cop_config['Whitelist'].map(&:to_sym)
54
+ def method_chain(node)
55
+ chain = node
56
+ while chain.send_type?
57
+ chain = chain.parent if chain.parent &&
58
+ %i[send csend].include?(chain.parent.type)
59
+ break
60
+ end
61
+ chain
66
62
  end
67
63
  end
68
64
  end
@@ -5,14 +5,39 @@ module RuboCop
5
5
  module Lint
6
6
  # This cop checks if a file which has a shebang line as
7
7
  # its first line is granted execute permission.
8
+ #
9
+ # @example
10
+ # # bad
11
+ #
12
+ # # A file which has a shebang line as its first line is not
13
+ # # granted execute permission.
14
+ #
15
+ # #!/usr/bin/env ruby
16
+ # puts 'hello, world'
17
+ #
18
+ # # good
19
+ #
20
+ # # A file which has a shebang line as its first line is
21
+ # # granted execute permission.
22
+ #
23
+ # #!/usr/bin/env ruby
24
+ # puts 'hello, world'
25
+ #
26
+ # # good
27
+ #
28
+ # # A file which has not a shebang line as its first line is not
29
+ # # granted execute permission.
30
+ #
31
+ # puts 'hello, world'
32
+ #
8
33
  class ScriptPermission < Cop
9
- MSG = "Script file %s doesn't have execute permission.".freeze
34
+ MSG = "Script file %<file>s doesn't have execute permission.".freeze
10
35
  SHEBANG = '#!'.freeze
11
36
 
12
37
  def investigate(processed_source)
13
38
  return if @options.key?(:stdin)
14
39
  return if Platform.windows?
15
- return unless start_with_shebang?(processed_source)
40
+ return unless processed_source.start_with?(SHEBANG)
16
41
  return if executable?(processed_source)
17
42
  comment = processed_source.comments[0]
18
43
  message = format_message_from(processed_source)
@@ -27,21 +52,16 @@ module RuboCop
27
52
 
28
53
  private
29
54
 
30
- def start_with_shebang?(processed_source)
31
- return false if processed_source[0].nil?
32
- processed_source[0].start_with?(SHEBANG)
33
- end
34
-
35
55
  def executable?(processed_source)
36
56
  # Returns true if stat is executable or if the operating system
37
57
  # doesn't distinguish executable files from nonexecutable files.
38
58
  # See at: https://github.com/ruby/ruby/blob/ruby_2_4/file.c#L5362
39
- File.stat(processed_source.buffer.name).executable?
59
+ File.stat(processed_source.file_path).executable?
40
60
  end
41
61
 
42
62
  def format_message_from(processed_source)
43
- basename = File.basename(processed_source.buffer.name)
44
- format(MSG, basename)
63
+ basename = File.basename(processed_source.file_path)
64
+ format(MSG, file: basename)
45
65
  end
46
66
  end
47
67
  end
@@ -37,8 +37,8 @@ module RuboCop
37
37
  # puts foo
38
38
  # end
39
39
  class ShadowedArgument < Cop
40
- MSG = 'Argument `%s` was shadowed by a local variable before it was ' \
41
- 'used.'.freeze
40
+ MSG = 'Argument `%<argument>s` was shadowed by a local variable ' \
41
+ 'before it was used.'.freeze
42
42
 
43
43
  def_node_search :uses_var?, '(lvar %)'
44
44
 
@@ -58,7 +58,7 @@ module RuboCop
58
58
  return unless argument.method_argument? || argument.block_argument?
59
59
 
60
60
  shadowing_assignment(argument) do |node|
61
- message = format(MSG, argument.name)
61
+ message = format(MSG, argument: argument.name)
62
62
 
63
63
  add_offense(node, message: message)
64
64
  end
@@ -45,6 +45,7 @@ module RuboCop
45
45
  #
46
46
  class ShadowedException < Cop
47
47
  include RescueNode
48
+ include RangeHelp
48
49
 
49
50
  MSG = 'Do not shadow rescued Exceptions.'.freeze
50
51
 
@@ -32,7 +32,7 @@ module RuboCop
32
32
  # end
33
33
  # end
34
34
  class ShadowingOuterLocalVariable < Cop
35
- MSG = 'Shadowing outer local variable - `%s`.'.freeze
35
+ MSG = 'Shadowing outer local variable - `%<variable>s`.'.freeze
36
36
 
37
37
  def join_force?(force_class)
38
38
  force_class == VariableForce
@@ -44,7 +44,7 @@ module RuboCop
44
44
  outer_local_variable = variable_table.find_variable(variable.name)
45
45
  return unless outer_local_variable
46
46
 
47
- message = format(MSG, variable.name)
47
+ message = format(MSG, variable: variable.name)
48
48
  add_offense(variable.declaration_node, message: message)
49
49
  end
50
50
  end
@@ -18,7 +18,7 @@ module RuboCop
18
18
  #
19
19
  # 1.is_a?(Integer)
20
20
  class UnifiedInteger < Cop
21
- MSG = 'Use `Integer` instead of `%s`.'.freeze
21
+ MSG = 'Use `Integer` instead of `%<klass>s`.'.freeze
22
22
 
23
23
  def_node_matcher :fixnum_or_bignum_const, <<-PATTERN
24
24
  (:const {nil? (:cbase)} ${:Fixnum :Bignum})
@@ -29,7 +29,7 @@ module RuboCop
29
29
 
30
30
  return unless klass
31
31
 
32
- add_offense(node, message: format(MSG, klass))
32
+ add_offense(node, message: format(MSG, klass: klass))
33
33
  end
34
34
 
35
35
  def autocorrect(node)
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # The Lint/UnneededDisable cop needs to be disabled so as to be able to provide
4
- # a (bad) example of an unneeded disable.
5
- # rubocop:disable Lint/UnneededDisable
3
+ # The Lint/UnneededCopDisableDirective cop needs to be disabled so as
4
+ # to be able to provide a (bad) example of an unneeded disable.
5
+ # rubocop:disable Lint/UnneededCopDisableDirective
6
6
  module RuboCop
7
7
  module Cop
8
8
  module Lint
@@ -25,10 +25,11 @@ module RuboCop
25
25
  #
26
26
  # # good
27
27
  # x += 1
28
- class UnneededDisable < Cop
28
+ class UnneededCopDisableDirective < Cop
29
29
  include NameSimilarity
30
+ include RangeHelp
30
31
 
31
- COP_NAME = 'Lint/UnneededDisable'.freeze
32
+ COP_NAME = 'Lint/UnneededCopDisableDirective'.freeze
32
33
 
33
34
  def check(offenses, cop_disabled_line_ranges, comments)
34
35
  unneeded_cops = Hash.new { |h, k| h[k] = Set.new }
@@ -223,7 +224,7 @@ module RuboCop
223
224
  ranges
224
225
  .drop_while { |r| !r.equal?(range) }
225
226
  .each_cons(2)
226
- .map { |r1, r2| r1.end.join(r2.begin).source }
227
+ .map { |range1, range2| range1.end.join(range2.begin).source }
227
228
  .all? { |intervening| intervening =~ /\A\s*,\s*\Z/ }
228
229
  end
229
230
 
@@ -249,8 +250,13 @@ module RuboCop
249
250
  def all_cop_names
250
251
  @all_cop_names ||= Cop.registry.names
251
252
  end
253
+
254
+ def ends_its_line?(range)
255
+ line = range.source_buffer.source_line(range.last_line)
256
+ (line =~ /\s*\z/) == range.last_column
257
+ end
252
258
  end
253
259
  end
254
260
  end
255
261
  end
256
- # rubocop:enable Lint/UnneededDisable
262
+ # rubocop:enable Lint/UnneededCopDisableDirective
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The Lint/UnneededCopEnableDirective cop needs to be disabled so as
4
+ # to be able to provide a (bad) example of an unneeded enable.
5
+
6
+ # rubocop:disable Lint/UnneededCopEnableDirective
7
+ module RuboCop
8
+ module Cop
9
+ module Lint
10
+ # This cop detects instances of rubocop:enable comments that can be
11
+ # removed.
12
+ #
13
+ # @example
14
+ # # bad
15
+ # foo = 1
16
+ # # rubocop:enable Metrics/LineLength
17
+ #
18
+ # # good
19
+ # foo = 1
20
+ class UnneededCopEnableDirective < Cop
21
+ include RangeHelp
22
+ include SurroundingSpace
23
+
24
+ MSG = 'Unnecessary enabling of %<cop>s.'.freeze
25
+
26
+ def investigate(processed_source)
27
+ return if processed_source.blank?
28
+ offenses = processed_source.comment_config.extra_enabled_comments
29
+ offenses.each do |comment, name|
30
+ add_offense(
31
+ [comment, name],
32
+ location: range_of_offense(comment, name),
33
+ message: format(MSG, cop: name)
34
+ )
35
+ end
36
+ end
37
+
38
+ def autocorrect(comment_and_name)
39
+ lambda do |corrector|
40
+ corrector.remove(range_with_comma(*comment_and_name))
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def range_of_offense(comment, name)
47
+ start_pos = comment_start(comment) + cop_name_indention(comment, name)
48
+ range_between(start_pos, start_pos + name.size)
49
+ end
50
+
51
+ def comment_start(comment)
52
+ comment.loc.expression.begin_pos
53
+ end
54
+
55
+ def cop_name_indention(comment, name)
56
+ comment.text.index(name)
57
+ end
58
+
59
+ def range_with_comma(comment, name)
60
+ source = comment.loc.expression.source
61
+
62
+ begin_pos = cop_name_indention(comment, name)
63
+ end_pos = begin_pos + name.size
64
+ begin_pos = reposition(source, begin_pos, -1)
65
+ end_pos = reposition(source, end_pos, 1)
66
+
67
+ comma_pos =
68
+ if source[begin_pos - 1] == ','
69
+ :before
70
+ elsif source[end_pos] == ','
71
+ :after
72
+ else
73
+ :none
74
+ end
75
+
76
+ range_to_remove(begin_pos, end_pos, comma_pos, comment)
77
+ end
78
+
79
+ def range_to_remove(begin_pos, end_pos, comma_pos, comment)
80
+ start = comment_start(comment)
81
+ buffer = processed_source.buffer
82
+ range_class = Parser::Source::Range
83
+
84
+ case comma_pos
85
+ when :before
86
+ range_class.new(buffer, start + begin_pos - 1, start + end_pos)
87
+ when :after
88
+ range_class.new(buffer, start + begin_pos, start + end_pos + 1)
89
+ else
90
+ range_class.new(buffer, start, comment.loc.expression.end_pos)
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ # rubocop:enable Lint/UnneededCopEnableDirective
@@ -23,6 +23,7 @@ module RuboCop
23
23
  # require 'unloaded_feature'
24
24
  class UnneededRequireStatement < Cop
25
25
  extend TargetRubyVersion
26
+ include RangeHelp
26
27
 
27
28
  minimum_target_ruby_version 2.2
28
29
 
@@ -40,10 +40,10 @@ module RuboCop
40
40
  def on_begin(node)
41
41
  expressions = *node
42
42
 
43
- expressions.each_cons(2) do |e1, e2|
44
- next unless flow_expression?(e1)
43
+ expressions.each_cons(2) do |expression1, expression2|
44
+ next unless flow_expression?(expression1)
45
45
 
46
- add_offense(e2)
46
+ add_offense(expression2)
47
47
  end
48
48
  end
49
49
 
@@ -41,8 +41,9 @@ module RuboCop
41
41
  URI.decode_www_form_component
42
42
  ].freeze
43
43
 
44
- MSG = '`%s` method is obsolete and should not be used. Instead, use ' \
45
- '`%s`, `%s` or `%s` depending on your specific use case.'.freeze
44
+ MSG = '`%<uri_method>s` method is obsolete and should not be used. ' \
45
+ 'Instead, use %<replacements>s depending on your specific use ' \
46
+ 'case.'.freeze
46
47
 
47
48
  def_node_matcher :uri_escape_unescape?, <<-PATTERN
48
49
  (send
@@ -52,18 +53,18 @@ module RuboCop
52
53
 
53
54
  def on_send(node)
54
55
  uri_escape_unescape?(node) do |top_level, obsolete_method|
55
- replacement_methods = if %i[escape encode].include?(obsolete_method)
56
- ALTERNATE_METHODS_OF_URI_ESCAPE
57
- else
58
- ALTERNATE_METHODS_OF_URI_UNESCAPE
59
- end
56
+ replacements = if %i[escape encode].include?(obsolete_method)
57
+ ALTERNATE_METHODS_OF_URI_ESCAPE
58
+ else
59
+ ALTERNATE_METHODS_OF_URI_UNESCAPE
60
+ end
60
61
 
61
62
  double_colon = top_level ? '::' : ''
62
63
 
63
64
  message = format(
64
- MSG,
65
- "#{double_colon}URI.#{obsolete_method}",
66
- *replacement_methods
65
+ MSG, uri_method: "#{double_colon}URI.#{obsolete_method}",
66
+ replacements: "`#{replacements[0]}`, `#{replacements[1]}` " \
67
+ "or `#{replacements[2]}`"
67
68
  )
68
69
 
69
70
  add_offense(node, message: message)
@@ -91,7 +91,7 @@ module RuboCop
91
91
  # delegate :method_a, to: :method_b
92
92
  # end
93
93
  class UselessAccessModifier < Cop
94
- MSG = 'Useless `%s` access modifier.'.freeze
94
+ MSG = 'Useless `%<current>s` access modifier.'.freeze
95
95
 
96
96
  def on_class(node)
97
97
  check_node(node.children[2]) # class body
@@ -135,14 +135,14 @@ module RuboCop
135
135
  if node.begin_type?
136
136
  check_scope(node)
137
137
  elsif node.send_type? && node.access_modifier?
138
- add_offense(node, message: format(MSG, node.method_name))
138
+ add_offense(node, message: format(MSG, current: node.method_name))
139
139
  end
140
140
  end
141
141
 
142
142
  def check_scope(node)
143
143
  cur_vis, unused = check_child_nodes(node, nil, :public)
144
144
 
145
- add_offense(unused, message: format(MSG, cur_vis)) if unused
145
+ add_offense(unused, message: format(MSG, current: cur_vis)) if unused
146
146
  end
147
147
 
148
148
  def check_child_nodes(node, unused, cur_vis)
@@ -165,10 +165,12 @@ module RuboCop
165
165
  def check_new_visibility(node, unused, new_vis, cur_vis)
166
166
  # does this modifier just repeat the existing visibility?
167
167
  if new_vis == cur_vis
168
- add_offense(node, message: format(MSG, cur_vis))
168
+ add_offense(node, message: format(MSG, current: cur_vis))
169
169
  else
170
170
  # was the previous modifier never applied to any defs?
171
- add_offense(unused, message: format(MSG, cur_vis)) if unused
171
+ if unused
172
+ add_offense(unused, message: format(MSG, current: cur_vis))
173
+ end
172
174
  # once we have already warned about a certain modifier, don't
173
175
  # warn again even if it is never applied to any method defs
174
176
  unused = node
@@ -32,7 +32,7 @@ module RuboCop
32
32
  # end
33
33
  class UselessAssignment < Cop
34
34
  include NameSimilarity
35
- MSG = 'Useless assignment to variable - `%s`.'.freeze
35
+ MSG = 'Useless assignment to variable - `%<variable>s`.'.freeze
36
36
 
37
37
  def join_force?(force_class)
38
38
  force_class == VariableForce
@@ -65,7 +65,7 @@ module RuboCop
65
65
  def message_for_useless_assignment(assignment)
66
66
  variable = assignment.variable
67
67
 
68
- format(MSG, variable.name) +
68
+ format(MSG, variable: variable.name) +
69
69
  message_specification(assignment, variable).to_s
70
70
  end
71
71