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
@@ -15,6 +15,8 @@ module RuboCop
15
15
  # attr_reader :one, :two, :three
16
16
  #
17
17
  class Attr < Cop
18
+ include RangeHelp
19
+
18
20
  MSG = 'Do not use `attr`. Use `%<replacement>s` instead.'.freeze
19
21
 
20
22
  def on_send(node)
@@ -17,12 +17,14 @@ module RuboCop
17
17
  # # of comments...
18
18
  #
19
19
  class BlockComments < Cop
20
+ include RangeHelp
21
+
20
22
  MSG = 'Do not use block comments.'.freeze
21
23
  BEGIN_LENGTH = "=begin\n".length
22
24
  END_LENGTH = "\n=end".length
23
25
 
24
26
  def investigate(processed_source)
25
- processed_source.comments.each do |comment|
27
+ processed_source.each_comment do |comment|
26
28
  next unless comment.document?
27
29
 
28
30
  add_offense(comment)
@@ -41,6 +41,7 @@ module RuboCop
41
41
  # some_method(x, y, {a: 1, b: 2}, {a: 1, b: 2})
42
42
  class BracesAroundHashParameters < Cop
43
43
  include ConfigurableEnforcedStyle
44
+ include RangeHelp
44
45
 
45
46
  MSG = '%<type>s curly braces around a hash parameter.'.freeze
46
47
 
@@ -129,7 +130,7 @@ module RuboCop
129
130
  def remove_braces_with_whitespace(corrector, node, space)
130
131
  right_brace_and_space = right_brace_and_space(node.loc.end, space)
131
132
 
132
- if comment_on_line?(right_brace_and_space.line)
133
+ if processed_source.comment_on_line?(right_brace_and_space.line)
133
134
  remove_braces(corrector, node)
134
135
  elsif node.multiline?
135
136
  remove_braces_with_range(corrector,
@@ -183,10 +184,6 @@ module RuboCop
183
184
  range_with_surrounding_comma(brace_and_space, :left)
184
185
  end
185
186
 
186
- def comment_on_line?(line)
187
- processed_source.comments.any? { |c| c.loc.line == line }
188
- end
189
-
190
187
  def remove_braces(corrector, node)
191
188
  corrector.remove(node.loc.begin)
192
189
  corrector.remove(node.loc.end)
@@ -23,6 +23,7 @@ module RuboCop
23
23
  # The compact style is only forced for classes/modules with one child.
24
24
  class ClassAndModuleChildren < Cop
25
25
  include ConfigurableEnforcedStyle
26
+ include RangeHelp
26
27
 
27
28
  NESTED_MSG = 'Use nested module/class definitions instead of ' \
28
29
  'compact style.'.freeze
@@ -6,6 +6,29 @@ module RuboCop
6
6
  # This cop checks for uses of class variables. Offenses
7
7
  # are signaled only on assignment to class variables to
8
8
  # reduce the number of offenses that would be reported.
9
+ #
10
+ # Setting value for class variable need to take care.
11
+ # If some class has been inherited by other classes, setting value
12
+ # for class variable affected children classes.
13
+ # So using class instance variable is better in almost case.
14
+ #
15
+ # @example
16
+ # # bad
17
+ # class A
18
+ # @@test = 10
19
+ # end
20
+ #
21
+ # # good
22
+ # class A
23
+ # @test = 10
24
+ # end
25
+ #
26
+ # class A
27
+ # def test
28
+ # @@test # you can access class variable without offence
29
+ # end
30
+ # end
31
+ #
9
32
  class ClassVars < Cop
10
33
  MSG = 'Replace class var %<class_var>s with a class ' \
11
34
  'instance var.'.freeze
@@ -22,8 +22,7 @@ module RuboCop
22
22
 
23
23
  def_node_matcher :java_type_node?, <<-PATTERN
24
24
  (send
25
- (const nil? :Java)
26
- {:boolean :byte :char :double :float :int :long :short})
25
+ (const nil? :Java) _)
27
26
  PATTERN
28
27
 
29
28
  def self.autocorrect_incompatible_with
@@ -32,6 +32,7 @@ module RuboCop
32
32
  # # OPTIMIZE: does not work
33
33
  class CommentAnnotation < Cop
34
34
  include AnnotationComment
35
+ include RangeHelp
35
36
 
36
37
  MSG = 'Annotation keywords like `%<keyword>s` should be all ' \
37
38
  'upper case, followed by a colon, and a space, ' \
@@ -40,8 +41,8 @@ module RuboCop
40
41
  'is missing a note.'.freeze
41
42
 
42
43
  def investigate(processed_source)
43
- processed_source.comments.each_with_index do |comment, ix|
44
- next unless first_comment_line?(processed_source.comments, ix)
44
+ processed_source.comments.each_with_index do |comment, index|
45
+ next unless first_comment_line?(processed_source.comments, index)
45
46
 
46
47
  margin, first_word, colon, space, note = split_comment(comment)
47
48
  next unless annotation?(comment) &&
@@ -68,8 +69,9 @@ module RuboCop
68
69
 
69
70
  private
70
71
 
71
- def first_comment_line?(comments, ix)
72
- ix.zero? || comments[ix - 1].loc.line < comments[ix].loc.line - 1
72
+ def first_comment_line?(comments, index)
73
+ index.zero? ||
74
+ comments[index - 1].loc.line < comments[index].loc.line - 1
73
75
  end
74
76
 
75
77
  def annotation_range(comment, margin, length)
@@ -33,13 +33,15 @@ module RuboCop
33
33
  # y
34
34
  # end
35
35
  class CommentedKeyword < Cop
36
+ include RangeHelp
37
+
36
38
  MSG = 'Do not place comments on the same line as the ' \
37
39
  '`%<keyword>s` keyword.'.freeze
38
40
 
39
41
  def investigate(processed_source)
40
42
  heredoc_lines = extract_heredoc_lines(processed_source.ast)
41
43
 
42
- processed_source.comments.each do |comment|
44
+ processed_source.each_comment do |comment|
43
45
  location = comment.location
44
46
  line_position = location.line
45
47
  line = processed_source.lines[line_position - 1]
@@ -9,7 +9,7 @@ module RuboCop
9
9
  extend NodePattern::Macros
10
10
 
11
11
  EQUAL = '='.freeze
12
- END_ALIGNMENT = 'Lint/EndAlignment'.freeze
12
+ END_ALIGNMENT = 'Layout/EndAlignment'.freeze
13
13
  ALIGN_WITH = 'EnforcedStyleAlignWith'.freeze
14
14
  KEYWORD = 'keyword'.freeze
15
15
 
@@ -16,6 +16,8 @@ module RuboCop
16
16
  # an offense is reported.
17
17
  #
18
18
  class Copyright < Cop
19
+ include RangeHelp
20
+
19
21
  MSG = 'Include a copyright notice matching /%<notice>s/ before ' \
20
22
  'any code.'.freeze
21
23
  AUTOCORRECT_EMPTY_WARNING = 'An AutocorrectNotice must be defined in' \
@@ -75,7 +77,7 @@ module RuboCop
75
77
  def notice_found?(processed_source)
76
78
  notice_found = false
77
79
  notice_regexp = Regexp.new(notice)
78
- processed_source.tokens.each do |token|
80
+ processed_source.each_token do |token|
79
81
  break unless token.comment?
80
82
  notice_found = !(token.text =~ notice_regexp).nil?
81
83
  break if notice_found
@@ -17,6 +17,8 @@ module RuboCop
17
17
  # # good
18
18
  # [1, 2].each_with_object({}) { |e, a| a[e] = e }
19
19
  class EachWithObject < Cop
20
+ include RangeHelp
21
+
20
22
  MSG = 'Use `each_with_object` instead of `%<method>s`.'.freeze
21
23
  METHODS = %i[inject reduce].freeze
22
24
 
@@ -51,7 +53,11 @@ module RuboCop
51
53
 
52
54
  return_value = return_value(node.body)
53
55
 
54
- corrector.remove(return_value.loc.expression)
56
+ if return_value_occupies_whole_line?(return_value)
57
+ corrector.remove(whole_line_expression(return_value))
58
+ else
59
+ corrector.remove(return_value.loc.expression)
60
+ end
55
61
  end
56
62
  end
57
63
  # rubocop:enable Metrics/AbcSize
@@ -90,6 +96,14 @@ module RuboCop
90
96
 
91
97
  accumulator_var == return_var
92
98
  end
99
+
100
+ def return_value_occupies_whole_line?(node)
101
+ whole_line_expression(node).source.strip == node.source
102
+ end
103
+
104
+ def whole_line_expression(node)
105
+ range_by_whole_lines(node.loc.expression, include_final_newline: true)
106
+ end
93
107
  end
94
108
  end
95
109
  end
@@ -23,6 +23,7 @@ module RuboCop
23
23
  # a { do_something }
24
24
  class EmptyBlockParameter < Cop
25
25
  include EmptyParameter
26
+ include RangeHelp
26
27
 
27
28
  MSG = 'Omit pipes for the empty block parameters.'.freeze
28
29
 
@@ -36,6 +36,8 @@ module RuboCop
36
36
  # puts 'more'
37
37
  # end
38
38
  class EmptyCaseCondition < Cop
39
+ include RangeHelp
40
+
39
41
  MSG = 'Do not use empty `case` condition, instead use an `if` '\
40
42
  'expression.'.freeze
41
43
 
@@ -92,6 +92,7 @@ module RuboCop
92
92
  class EmptyElse < Cop
93
93
  include OnNormalIfUnless
94
94
  include ConfigurableEnforcedStyle
95
+ include RangeHelp
95
96
 
96
97
  MSG = 'Redundant `else`-clause.'.freeze
97
98
 
@@ -108,7 +109,7 @@ module RuboCop
108
109
  return false if comment_in_else?(node)
109
110
 
110
111
  lambda do |corrector|
111
- end_pos = base_if_node(node).loc.end.begin_pos
112
+ end_pos = base_node(node).loc.end.begin_pos
112
113
  corrector.remove(range_between(node.loc.else.begin_pos, end_pos))
113
114
  end
114
115
  end
@@ -142,7 +143,7 @@ module RuboCop
142
143
 
143
144
  def comment_in_else?(node)
144
145
  range = else_line_range(node.loc)
145
- processed_source.comments.find { |c| range.include?(c.loc.line) }
146
+ processed_source.find_comment { |c| range.include?(c.loc.line) }
146
147
  end
147
148
 
148
149
  def else_line_range(loc)
@@ -150,9 +151,12 @@ module RuboCop
150
151
  loc.else.first_line..loc.end.first_line
151
152
  end
152
153
 
153
- def base_if_node(node)
154
- return node unless node.case_type? || node.elsif?
155
- node.each_ancestor(:if).find { |parent| parent.loc.end } || node
154
+ def base_node(node)
155
+ return node if node.case_type?
156
+ return node unless node.elsif?
157
+ node.each_ancestor(:if, :case, :when).find(-> { node }) do |parent|
158
+ parent.loc.end
159
+ end
156
160
  end
157
161
 
158
162
  def autocorrect_forbidden?(type)
@@ -18,6 +18,7 @@ module RuboCop
18
18
  # -> (arg) { do_something(arg) }
19
19
  class EmptyLambdaParameter < Cop
20
20
  include EmptyParameter
21
+ include RangeHelp
21
22
 
22
23
  MSG = 'Omit parentheses for the empty lambda parameters.'.freeze
23
24
 
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop enforces empty line after guard clause
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # def foo
12
+ # return if need_return?
13
+ # bar
14
+ # end
15
+ #
16
+ # # good
17
+ # def foo
18
+ # return if need_return?
19
+ #
20
+ # bar
21
+ # end
22
+ #
23
+ # # good
24
+ # def foo
25
+ # return if something?
26
+ # return if something_different?
27
+ #
28
+ # bar
29
+ # end
30
+ #
31
+ # # also good
32
+ # def foo
33
+ # if something?
34
+ # do_something
35
+ # return if need_return?
36
+ # end
37
+ # end
38
+ class EmptyLineAfterGuardClause < Cop
39
+ include RangeHelp
40
+
41
+ MSG = 'Add empty line after guard clause.'.freeze
42
+
43
+ def on_if(node)
44
+ return unless contains_guard_clause?(node)
45
+
46
+ return if node.parent.nil? || node.parent.single_line?
47
+ return if next_sibling_empty_or_guard_clause?(node)
48
+
49
+ return if next_line_empty?(node)
50
+
51
+ add_offense(node)
52
+ end
53
+
54
+ def autocorrect(node)
55
+ lambda do |corrector|
56
+ node_range = range_by_whole_lines(node.source_range)
57
+ corrector.insert_after(node_range, "\n")
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def contains_guard_clause?(node)
64
+ node.if_branch && node.if_branch.guard_clause?
65
+ end
66
+
67
+ def next_line_empty?(node)
68
+ processed_source[node.last_line].blank?
69
+ end
70
+
71
+ def next_sibling_empty_or_guard_clause?(node)
72
+ next_sibling = node.parent.children[node.sibling_index + 1]
73
+ return true if next_sibling.nil?
74
+
75
+ next_sibling.if_type? && contains_guard_clause?(next_sibling)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -18,6 +18,7 @@ module RuboCop
18
18
  # s = ''
19
19
  class EmptyLiteral < Cop
20
20
  include FrozenStringLiteral
21
+ include RangeHelp
21
22
 
22
23
  ARR_MSG = 'Use array literal `[]` instead of `Array.new`.'.freeze
23
24
  HASH_MSG = 'Use hash literal `{}` instead of `Hash.new`.'.freeze
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks ensures source files have no utf-8 encoding comments.
7
7
  class Encoding < Cop
8
+ include RangeHelp
9
+
8
10
  MSG_UNNECESSARY = 'Unnecessary utf-8 encoding comment.'.freeze
9
11
  ENCODING_PATTERN = /#.*coding\s?[:=]\s?(?:UTF|utf)-8/
10
12
  SHEBANG = '#!'.freeze
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for use of the `File.expand_path` arguments.
7
+ # Likewise, it also checks for the `Pathname.new` argument.
8
+ #
9
+ # Contrastive bad case and good case are alternately shown in
10
+ # the following examples.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # File.expand_path('..', __FILE__)
15
+ #
16
+ # # good
17
+ # File.expand_path(__dir__)
18
+ #
19
+ # # bad
20
+ # File.expand_path('../..', __FILE__)
21
+ #
22
+ # # good
23
+ # File.expand_path('..', __dir__)
24
+ #
25
+ # # bad
26
+ # File.expand_path('.', __FILE__)
27
+ #
28
+ # # good
29
+ # File.expand_path(__FILE__)
30
+ #
31
+ # # bad
32
+ # Pathname(__FILE__).parent.expand_path
33
+ #
34
+ # # good
35
+ # Pathname(__dir__).expand_path
36
+ #
37
+ # # bad
38
+ # Pathname.new(__FILE__).parent.expand_path
39
+ #
40
+ # # good
41
+ # Pathname.new(__dir__).expand_path
42
+ #
43
+ class ExpandPathArguments < Cop
44
+ include RangeHelp
45
+
46
+ MSG = 'Use `expand_path(%<new_path>s%<new_default_dir>s)` instead of ' \
47
+ '`expand_path(%<current_path>s, __FILE__)`.'.freeze
48
+ PATHNAME_MSG = 'Use `Pathname(__dir__).expand_path` instead of ' \
49
+ '`Pathname(__FILE__).parent.expand_path`.'.freeze
50
+ PATHNAME_NEW_MSG = 'Use `Pathname.new(__dir__).expand_path` ' \
51
+ 'instead of ' \
52
+ '`Pathname.new(__FILE__).parent.expand_path`.'.freeze
53
+
54
+ def_node_matcher :file_expand_path, <<-PATTERN
55
+ (send
56
+ (const nil? :File) :expand_path
57
+ $_
58
+ $_)
59
+ PATTERN
60
+
61
+ def_node_matcher :pathname_parent_expand_path, <<-PATTERN
62
+ (send
63
+ (send
64
+ (send nil? :Pathname
65
+ $_) :parent) :expand_path)
66
+ PATTERN
67
+
68
+ def_node_matcher :pathname_new_parent_expand_path, <<-PATTERN
69
+ (send
70
+ (send
71
+ (send
72
+ (const nil? :Pathname) :new
73
+ $_) :parent) :expand_path)
74
+ PATTERN
75
+
76
+ def on_send(node)
77
+ if (captured_values = file_expand_path(node))
78
+ current_path, default_dir = captured_values
79
+
80
+ inspect_offense_for_expand_path(node, current_path, default_dir)
81
+ elsif (default_dir = pathname_parent_expand_path(node))
82
+ return unless unrecommended_argument?(default_dir)
83
+
84
+ add_offense(node, message: PATHNAME_MSG)
85
+ elsif (default_dir = pathname_new_parent_expand_path(node))
86
+ return unless unrecommended_argument?(default_dir)
87
+
88
+ add_offense(node, message: PATHNAME_NEW_MSG)
89
+ end
90
+ end
91
+
92
+ def autocorrect(node)
93
+ lambda do |corrector|
94
+ if (captured_values = file_expand_path(node))
95
+ current_path, default_dir = captured_values
96
+
97
+ autocorrect_expand_path(corrector, current_path, default_dir)
98
+ elsif (default_dir = pathname_parent_expand_path(node)) ||
99
+ (default_dir = pathname_new_parent_expand_path(node))
100
+ corrector.replace(default_dir.loc.expression, '__dir__')
101
+ remove_parent_method(corrector, default_dir)
102
+ end
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def unrecommended_argument?(default_dir)
109
+ default_dir.source == '__FILE__'
110
+ end
111
+
112
+ def inspect_offense_for_expand_path(node, current_path, default_dir)
113
+ return unless unrecommended_argument?(default_dir) &&
114
+ current_path.str_type?
115
+
116
+ current_path = strip_surrounded_quotes!(current_path.source)
117
+
118
+ parent_path = parent_path(current_path)
119
+ new_path = parent_path == '' ? '' : "'#{parent_path}', "
120
+
121
+ new_default_dir = depth(current_path).zero? ? '__FILE__' : '__dir__'
122
+
123
+ message = format(
124
+ MSG,
125
+ new_path: new_path,
126
+ new_default_dir: new_default_dir,
127
+ current_path: "'#{current_path}'"
128
+ )
129
+
130
+ add_offense(node, location: :selector, message: message)
131
+ end
132
+
133
+ def autocorrect_expand_path(corrector, current_path, default_dir)
134
+ stripped_current_path = strip_surrounded_quotes!(current_path.source)
135
+
136
+ case depth(stripped_current_path)
137
+ when 0
138
+ range = arguments_range(current_path)
139
+
140
+ corrector.replace(range, '__FILE__')
141
+ when 1
142
+ range = arguments_range(current_path)
143
+
144
+ corrector.replace(range, '__dir__')
145
+ else
146
+ new_path = "'#{parent_path(stripped_current_path)}'"
147
+
148
+ corrector.replace(current_path.loc.expression, new_path)
149
+ corrector.replace(default_dir.loc.expression, '__dir__')
150
+ end
151
+ end
152
+
153
+ def strip_surrounded_quotes!(path_string)
154
+ path_string.slice!(path_string.length - 1)
155
+ path_string.slice!(0)
156
+
157
+ path_string
158
+ end
159
+
160
+ def depth(current_path)
161
+ paths = current_path.split(File::SEPARATOR)
162
+
163
+ paths.reject { |path| path == '.' }.count
164
+ end
165
+
166
+ def parent_path(current_path)
167
+ paths = current_path.split(File::SEPARATOR)
168
+
169
+ paths.delete('.')
170
+ paths.each_with_index do |path, index|
171
+ if path == '..'
172
+ paths.delete_at(index)
173
+ break
174
+ end
175
+ end
176
+
177
+ paths.join(File::SEPARATOR)
178
+ end
179
+
180
+ def remove_parent_method(corrector, default_dir)
181
+ node = default_dir.parent.parent.parent.children.first
182
+
183
+ corrector.remove(node.loc.dot)
184
+ corrector.remove(node.loc.selector)
185
+ end
186
+
187
+ def arguments_range(node)
188
+ range_between(node.parent.first_argument.source_range.begin_pos,
189
+ node.parent.last_argument.source_range.end_pos)
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end