rubocop 1.9.0 → 1.12.1

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 (275) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -14
  3. data/assets/output.html.erb +1 -1
  4. data/config/default.yml +70 -17
  5. data/config/obsoletion.yml +4 -0
  6. data/lib/rubocop.rb +5 -0
  7. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  8. data/lib/rubocop/cli/command/suggest_extensions.rb +3 -2
  9. data/lib/rubocop/comment_config.rb +43 -94
  10. data/lib/rubocop/config.rb +4 -1
  11. data/lib/rubocop/cop/base.rb +1 -0
  12. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -1
  13. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
  14. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -0
  15. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -0
  16. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  17. data/lib/rubocop/cop/exclude_limit.rb +26 -0
  18. data/lib/rubocop/cop/gemspec/date_assignment.rb +57 -0
  19. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -0
  20. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -0
  21. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +2 -0
  22. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +2 -0
  23. data/lib/rubocop/cop/generator.rb +2 -2
  24. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  25. data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -0
  26. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
  27. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -0
  28. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +151 -0
  29. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
  30. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -0
  31. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +1 -0
  32. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +1 -0
  33. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
  34. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +3 -0
  35. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +4 -0
  36. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  37. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +11 -8
  38. data/lib/rubocop/cop/layout/argument_alignment.rb +6 -5
  39. data/lib/rubocop/cop/layout/array_alignment.rb +7 -6
  40. data/lib/rubocop/cop/layout/assignment_indentation.rb +6 -3
  41. data/lib/rubocop/cop/layout/block_alignment.rb +1 -0
  42. data/lib/rubocop/cop/layout/block_end_newline.rb +4 -8
  43. data/lib/rubocop/cop/layout/class_structure.rb +1 -0
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +14 -15
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +16 -16
  46. data/lib/rubocop/cop/layout/else_alignment.rb +9 -6
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +20 -3
  48. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +37 -17
  49. data/lib/rubocop/cop/layout/extra_spacing.rb +2 -2
  50. data/lib/rubocop/cop/layout/first_argument_indentation.rb +27 -7
  51. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +9 -6
  52. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +22 -15
  53. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +6 -5
  54. data/lib/rubocop/cop/layout/indentation_consistency.rb +9 -6
  55. data/lib/rubocop/cop/layout/indentation_style.rb +27 -30
  56. data/lib/rubocop/cop/layout/indentation_width.rb +20 -9
  57. data/lib/rubocop/cop/layout/line_length.rb +2 -1
  58. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +26 -0
  59. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -5
  60. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +10 -5
  61. data/lib/rubocop/cop/layout/parameter_alignment.rb +6 -5
  62. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -1
  63. data/lib/rubocop/cop/layout/space_before_brackets.rb +9 -4
  64. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  65. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -0
  66. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -0
  67. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +2 -0
  68. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -0
  69. data/lib/rubocop/cop/lint/debugger.rb +60 -14
  70. data/lib/rubocop/cop/lint/deprecated_constants.rb +5 -0
  71. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +14 -4
  72. data/lib/rubocop/cop/lint/duplicate_branch.rb +1 -1
  73. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -0
  74. data/lib/rubocop/cop/lint/duplicate_require.rb +3 -2
  75. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
  76. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  77. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -0
  78. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -0
  79. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +1 -0
  80. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -0
  81. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -0
  82. data/lib/rubocop/cop/lint/multiple_comparison.rb +5 -4
  83. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -0
  84. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -0
  85. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +7 -0
  86. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -0
  87. data/lib/rubocop/cop/lint/number_conversion.rb +11 -2
  88. data/lib/rubocop/cop/lint/raise_exception.rb +2 -0
  89. data/lib/rubocop/cop/lint/rand_one.rb +1 -0
  90. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +1 -2
  91. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
  92. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -0
  93. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -3
  94. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -0
  95. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -0
  96. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -0
  97. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -0
  98. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -0
  99. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -0
  100. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  101. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
  102. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
  103. data/lib/rubocop/cop/lint/suppressed_exception.rb +44 -1
  104. data/lib/rubocop/cop/lint/symbol_conversion.rb +91 -3
  105. data/lib/rubocop/cop/lint/to_enum_arguments.rb +3 -0
  106. data/lib/rubocop/cop/lint/unified_integer.rb +1 -0
  107. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +5 -0
  108. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
  109. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -0
  110. data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -0
  111. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -0
  112. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -0
  113. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -0
  114. data/lib/rubocop/cop/lint/useless_times.rb +3 -0
  115. data/lib/rubocop/cop/message_annotator.rb +4 -1
  116. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  117. data/lib/rubocop/cop/metrics/module_length.rb +1 -0
  118. data/lib/rubocop/cop/metrics/parameter_lists.rb +6 -2
  119. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -4
  120. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +2 -0
  121. data/lib/rubocop/cop/mixin/alignment.rb +10 -3
  122. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  123. data/lib/rubocop/cop/mixin/code_length.rb +3 -1
  124. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  125. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -0
  126. data/lib/rubocop/cop/mixin/def_node.rb +1 -0
  127. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  128. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +3 -0
  129. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -0
  130. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -0
  131. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -0
  132. data/lib/rubocop/cop/mixin/line_length_help.rb +11 -6
  133. data/lib/rubocop/cop/mixin/method_complexity.rb +4 -1
  134. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +3 -1
  135. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -23
  136. data/lib/rubocop/cop/mixin/negative_conditional.rb +3 -0
  137. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +3 -3
  138. data/lib/rubocop/cop/mixin/rational_literal.rb +1 -0
  139. data/lib/rubocop/cop/mixin/safe_assignment.rb +5 -0
  140. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +4 -6
  141. data/lib/rubocop/cop/mixin/visibility_help.rb +1 -0
  142. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -0
  143. data/lib/rubocop/cop/naming/constant_name.rb +2 -0
  144. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +6 -0
  145. data/lib/rubocop/cop/naming/method_name.rb +3 -0
  146. data/lib/rubocop/cop/naming/predicate_name.rb +1 -0
  147. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -0
  148. data/lib/rubocop/cop/registry.rb +10 -1
  149. data/lib/rubocop/cop/security/eval.rb +1 -0
  150. data/lib/rubocop/cop/security/json_load.rb +1 -0
  151. data/lib/rubocop/cop/security/marshal_load.rb +1 -0
  152. data/lib/rubocop/cop/security/open.rb +1 -0
  153. data/lib/rubocop/cop/security/yaml_load.rb +1 -0
  154. data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -2
  155. data/lib/rubocop/cop/style/alias.rb +1 -0
  156. data/lib/rubocop/cop/style/and_or.rb +3 -1
  157. data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -0
  158. data/lib/rubocop/cop/style/array_coercion.rb +2 -0
  159. data/lib/rubocop/cop/style/array_join.rb +1 -0
  160. data/lib/rubocop/cop/style/attr.rb +1 -0
  161. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +59 -71
  162. data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +62 -0
  163. data/lib/rubocop/cop/style/case_equality.rb +2 -1
  164. data/lib/rubocop/cop/style/case_like_if.rb +15 -4
  165. data/lib/rubocop/cop/style/class_equality_comparison.rb +3 -0
  166. data/lib/rubocop/cop/style/collection_compact.rb +2 -0
  167. data/lib/rubocop/cop/style/colon_method_call.rb +1 -0
  168. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  169. data/lib/rubocop/cop/style/commented_keyword.rb +10 -10
  170. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
  171. data/lib/rubocop/cop/style/constant_visibility.rb +28 -0
  172. data/lib/rubocop/cop/style/date_time.rb +3 -0
  173. data/lib/rubocop/cop/style/dir.rb +1 -0
  174. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  175. data/lib/rubocop/cop/style/documentation.rb +30 -3
  176. data/lib/rubocop/cop/style/documentation_method.rb +1 -0
  177. data/lib/rubocop/cop/style/double_negation.rb +3 -2
  178. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -0
  179. data/lib/rubocop/cop/style/each_with_object.rb +1 -0
  180. data/lib/rubocop/cop/style/empty_literal.rb +9 -0
  181. data/lib/rubocop/cop/style/endless_method.rb +1 -0
  182. data/lib/rubocop/cop/style/eval_with_location.rb +90 -28
  183. data/lib/rubocop/cop/style/even_odd.rb +1 -0
  184. data/lib/rubocop/cop/style/expand_path_arguments.rb +3 -0
  185. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -1
  186. data/lib/rubocop/cop/style/exponential_notation.rb +6 -7
  187. data/lib/rubocop/cop/style/float_division.rb +4 -0
  188. data/lib/rubocop/cop/style/format_string.rb +2 -0
  189. data/lib/rubocop/cop/style/format_string_token.rb +1 -0
  190. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +0 -3
  191. data/lib/rubocop/cop/style/global_std_stream.rb +1 -0
  192. data/lib/rubocop/cop/style/hash_conversion.rb +108 -0
  193. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -0
  194. data/lib/rubocop/cop/style/hash_except.rb +1 -0
  195. data/lib/rubocop/cop/style/hash_like_case.rb +1 -0
  196. data/lib/rubocop/cop/style/hash_syntax.rb +16 -15
  197. data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -0
  198. data/lib/rubocop/cop/style/hash_transform_values.rb +4 -0
  199. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +37 -11
  200. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
  201. data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
  202. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +46 -2
  203. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -3
  204. data/lib/rubocop/cop/style/min_max.rb +1 -0
  205. data/lib/rubocop/cop/style/mixin_usage.rb +2 -0
  206. data/lib/rubocop/cop/style/module_function.rb +5 -0
  207. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -3
  208. data/lib/rubocop/cop/style/multiple_comparison.rb +21 -2
  209. data/lib/rubocop/cop/style/mutable_constant.rb +3 -0
  210. data/lib/rubocop/cop/style/negated_if_else_condition.rb +16 -2
  211. data/lib/rubocop/cop/style/nil_comparison.rb +6 -1
  212. data/lib/rubocop/cop/style/nil_lambda.rb +1 -0
  213. data/lib/rubocop/cop/style/non_nil_check.rb +7 -0
  214. data/lib/rubocop/cop/style/numeric_literals.rb +6 -9
  215. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -1
  216. data/lib/rubocop/cop/style/option_hash.rb +1 -0
  217. data/lib/rubocop/cop/style/or_assignment.rb +2 -0
  218. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -0
  219. data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -0
  220. data/lib/rubocop/cop/style/proc.rb +1 -0
  221. data/lib/rubocop/cop/style/random_with_offset.rb +5 -0
  222. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -0
  223. data/lib/rubocop/cop/style/redundant_begin.rb +44 -4
  224. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -0
  225. data/lib/rubocop/cop/style/redundant_exception.rb +2 -0
  226. data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -0
  227. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
  228. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -0
  229. data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -0
  230. data/lib/rubocop/cop/style/redundant_return.rb +4 -0
  231. data/lib/rubocop/cop/style/redundant_self.rb +7 -3
  232. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -0
  233. data/lib/rubocop/cop/style/redundant_sort.rb +1 -0
  234. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -0
  235. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  236. data/lib/rubocop/cop/style/rescue_modifier.rb +17 -14
  237. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -0
  238. data/lib/rubocop/cop/style/return_nil.rb +6 -0
  239. data/lib/rubocop/cop/style/safe_navigation.rb +2 -0
  240. data/lib/rubocop/cop/style/sample.rb +1 -0
  241. data/lib/rubocop/cop/style/signal_exception.rb +3 -0
  242. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
  243. data/lib/rubocop/cop/style/single_line_methods.rb +4 -1
  244. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -0
  245. data/lib/rubocop/cop/style/sole_nested_conditional.rb +20 -4
  246. data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
  247. data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
  248. data/lib/rubocop/cop/style/string_chars.rb +38 -0
  249. data/lib/rubocop/cop/style/string_concatenation.rb +1 -0
  250. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -0
  251. data/lib/rubocop/cop/style/strip.rb +1 -0
  252. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -0
  253. data/lib/rubocop/cop/style/symbol_proc.rb +25 -1
  254. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -0
  255. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +5 -0
  256. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
  257. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -0
  258. data/lib/rubocop/cop/style/unless_logical_operators.rb +105 -0
  259. data/lib/rubocop/cop/style/unpack_first.rb +1 -0
  260. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  261. data/lib/rubocop/cop/style/zero_length_predicate.rb +5 -0
  262. data/lib/rubocop/cop/util.rb +4 -1
  263. data/lib/rubocop/directive_comment.rb +69 -9
  264. data/lib/rubocop/ext/regexp_parser.rb +3 -6
  265. data/lib/rubocop/formatter/clang_style_formatter.rb +4 -2
  266. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  267. data/lib/rubocop/formatter/simple_text_formatter.rb +2 -1
  268. data/lib/rubocop/formatter/tap_formatter.rb +4 -2
  269. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  270. data/lib/rubocop/magic_comment.rb +1 -1
  271. data/lib/rubocop/name_similarity.rb +1 -1
  272. data/lib/rubocop/target_finder.rb +1 -0
  273. data/lib/rubocop/target_ruby.rb +21 -13
  274. data/lib/rubocop/version.rb +1 -1
  275. metadata +14 -7
@@ -35,6 +35,7 @@ module RuboCop
35
35
 
36
36
  RESTRICT_ON_SEND = %i[reject reject! select select!].freeze
37
37
 
38
+ # @!method reject_method?(node)
38
39
  def_node_matcher :reject_method?, <<~PATTERN
39
40
  (block
40
41
  (send
@@ -44,6 +45,7 @@ module RuboCop
44
45
  $(lvar _) :nil?))
45
46
  PATTERN
46
47
 
48
+ # @!method select_method?(node)
47
49
  def_node_matcher :select_method?, <<~PATTERN
48
50
  (block
49
51
  (send
@@ -22,6 +22,7 @@ module RuboCop
22
22
 
23
23
  MSG = 'Do not use `::` for method calls.'
24
24
 
25
+ # @!method java_type_node?(node)
25
26
  def_node_matcher :java_type_node?, <<~PATTERN
26
27
  (send
27
28
  (const nil? :Java) _)
@@ -165,7 +165,7 @@ module RuboCop
165
165
  end
166
166
 
167
167
  def preferred_delimiter
168
- (command_delimiter || default_delimiter).split(//)
168
+ (command_delimiter || default_delimiter).chars
169
169
  end
170
170
 
171
171
  def command_delimiter
@@ -43,16 +43,6 @@ module RuboCop
43
43
  MSG = 'Do not place comments on the same line as the ' \
44
44
  '`%<keyword>s` keyword.'
45
45
 
46
- def on_new_investigation
47
- processed_source.comments.each do |comment|
48
- next unless (match = line(comment).match(/(?<keyword>\S+).*#/)) && offensive?(comment)
49
-
50
- register_offense(comment, match[:keyword])
51
- end
52
- end
53
-
54
- private
55
-
56
46
  KEYWORDS = %w[begin class def end module].freeze
57
47
  KEYWORD_REGEXES = KEYWORDS.map { |w| /^\s*#{w}\s/ }.freeze
58
48
 
@@ -64,6 +54,16 @@ module RuboCop
64
54
  ].freeze
65
55
  ALLOWED_COMMENT_REGEXES = ALLOWED_COMMENTS.map { |c| /#\s*#{c}/ }.freeze
66
56
 
57
+ def on_new_investigation
58
+ processed_source.comments.each do |comment|
59
+ next unless (match = line(comment).match(/(?<keyword>\S+).*#/)) && offensive?(comment)
60
+
61
+ register_offense(comment, match[:keyword])
62
+ end
63
+ end
64
+
65
+ private
66
+
67
67
  def register_offense(comment, matched_keyword)
68
68
  add_offense(comment, message: format(MSG, keyword: matched_keyword)) do |corrector|
69
69
  range = range_with_surrounding_space(range: comment.loc.expression, newlines: false)
@@ -231,6 +231,7 @@ module RuboCop
231
231
 
232
232
  # The shovel operator `<<` does not have its own type. It is a `send`
233
233
  # type.
234
+ # @!method assignment_type?(node)
234
235
  def_node_matcher :assignment_type?, <<~PATTERN
235
236
  {
236
237
  #{ASSIGNMENT_TYPES.join(' ')}
@@ -300,6 +301,7 @@ module RuboCop
300
301
  style == :assign_inside_condition && assignment_rhs_exist?(node)
301
302
  end
302
303
 
304
+ # @!method candidate_condition?(node)
303
305
  def_node_matcher :candidate_condition?, '[{if case} !#allowed_ternary?]'
304
306
 
305
307
  def allowed_ternary?(assignment)
@@ -26,6 +26,24 @@ module RuboCop
26
26
  # public_constant :BAZ
27
27
  # end
28
28
  #
29
+ # @example IgnoreModules: false (default)
30
+ # # bad
31
+ # class Foo
32
+ # MyClass = Struct.new()
33
+ # end
34
+ #
35
+ # # good
36
+ # class Foo
37
+ # MyClass = Struct.new()
38
+ # public_constant :MyClass
39
+ # end
40
+ #
41
+ # @example IgnoreModules: true
42
+ # # good
43
+ # class Foo
44
+ # MyClass = Struct.new()
45
+ # end
46
+ #
29
47
  class ConstantVisibility < Base
30
48
  MSG = 'Explicitly make `%<constant_name>s` public or private using ' \
31
49
  'either `#public_constant` or `#private_constant`.'
@@ -33,6 +51,7 @@ module RuboCop
33
51
  def on_casgn(node)
34
52
  return unless class_or_module_scope?(node)
35
53
  return if visibility_declaration?(node)
54
+ return if ignore_modules? && module?(node)
36
55
 
37
56
  message = message(node)
38
57
  add_offense(node, message: message)
@@ -40,6 +59,14 @@ module RuboCop
40
59
 
41
60
  private
42
61
 
62
+ def ignore_modules?
63
+ cop_config.fetch('IgnoreModules', false)
64
+ end
65
+
66
+ def module?(node)
67
+ node.children.last.class_constructor?
68
+ end
69
+
43
70
  def message(node)
44
71
  _namespace, constant_name, _value = *node
45
72
 
@@ -65,6 +92,7 @@ module RuboCop
65
92
  end
66
93
  end
67
94
 
95
+ # @!method visibility_declaration_for?(node, const_name)
68
96
  def_node_matcher :visibility_declaration_for?, <<~PATTERN
69
97
  (send nil? {:public_constant :private_constant} ({sym str} #match_name?(%1)))
70
98
  PATTERN
@@ -47,14 +47,17 @@ module RuboCop
47
47
  CLASS_MSG = 'Prefer Time over DateTime.'
48
48
  COERCION_MSG = 'Do not use #to_datetime.'
49
49
 
50
+ # @!method date_time?(node)
50
51
  def_node_matcher :date_time?, <<~PATTERN
51
52
  (send (const {nil? (cbase)} :DateTime) ...)
52
53
  PATTERN
53
54
 
55
+ # @!method historic_date?(node)
54
56
  def_node_matcher :historic_date?, <<~PATTERN
55
57
  (send _ _ _ (const (const {nil? (cbase)} :Date) _))
56
58
  PATTERN
57
59
 
60
+ # @!method to_datetime?(node)
58
61
  def_node_matcher :to_datetime?, <<~PATTERN
59
62
  (send _ :to_datetime)
60
63
  PATTERN
@@ -22,6 +22,7 @@ module RuboCop
22
22
  MSG = "Use `__dir__` to get an absolute path to the current file's directory."
23
23
  RESTRICT_ON_SEND = %i[expand_path dirname].freeze
24
24
 
25
+ # @!method dir_replacement?(node)
25
26
  def_node_matcher :dir_replacement?, <<~PATTERN
26
27
  {(send (const {nil? cbase} :File) :expand_path (send (const {nil? cbase} :File) :dirname #file_keyword?))
27
28
  (send (const {nil? cbase} :File) :dirname (send (const {nil? cbase} :File) :realpath #file_keyword?))}
@@ -70,8 +70,8 @@ module RuboCop
70
70
  end
71
71
 
72
72
  def directive_cops(comment)
73
- match = CommentConfig::COMMENT_DIRECTIVE_REGEXP.match(comment.text)
74
- match[2] ? match[2].split(',').map(&:strip) : []
73
+ match_captures = DirectiveComment.new(comment).match_captures
74
+ match_captures && match_captures[1] ? match_captures[1].split(',').map(&:strip) : []
75
75
  end
76
76
 
77
77
  def allowed_cops
@@ -60,13 +60,27 @@ module RuboCop
60
60
  # extend Foo
61
61
  # end
62
62
  #
63
+ # @example AllowedConstants: ['ClassMethods']
64
+ #
65
+ # # good
66
+ # module A
67
+ # module ClassMethods
68
+ # # ...
69
+ # end
70
+ # end
71
+ #
63
72
  class Documentation < Base
64
73
  include DocumentationComment
65
74
 
66
75
  MSG = 'Missing top-level %<type>s documentation comment.'
67
76
 
77
+ # @!method constant_definition?(node)
68
78
  def_node_matcher :constant_definition?, '{class module casgn}'
79
+
80
+ # @!method outer_module(node)
69
81
  def_node_search :outer_module, '(const (const nil? _) _)'
82
+
83
+ # @!method constant_visibility_declaration?(node)
70
84
  def_node_matcher :constant_visibility_declaration?, <<~PATTERN
71
85
  (send nil? {:public_constant :private_constant} ({sym str} _))
72
86
  PATTERN
@@ -85,14 +99,19 @@ module RuboCop
85
99
 
86
100
  def check(node, body, type)
87
101
  return if namespace?(body)
88
- return if documentation_comment?(node) || nodoc_comment?(node)
89
- return if compact_namespace?(node) &&
90
- nodoc_comment?(outer_module(node).first)
102
+ return if documentation_comment?(node)
103
+ return if constant_allowed?(node)
104
+ return if nodoc_self_or_outer_module?(node)
91
105
  return if macro_only?(body)
92
106
 
93
107
  add_offense(node.loc.keyword, message: format(MSG, type: type))
94
108
  end
95
109
 
110
+ def nodoc_self_or_outer_module?(node)
111
+ nodoc_comment?(node) ||
112
+ compact_namespace?(node) && nodoc_comment?(outer_module(node).first)
113
+ end
114
+
96
115
  def macro_only?(body)
97
116
  body.respond_to?(:macro?) && body.macro? ||
98
117
  body.respond_to?(:children) && body.children&.all? { |child| macro_only?(child) }
@@ -112,6 +131,10 @@ module RuboCop
112
131
  constant_definition?(node) || constant_visibility_declaration?(node)
113
132
  end
114
133
 
134
+ def constant_allowed?(node)
135
+ allowed_constants.include?(node.identifier.short_name)
136
+ end
137
+
115
138
  def compact_namespace?(node)
116
139
  /::/.match?(node.loc.name.source)
117
140
  end
@@ -138,6 +161,10 @@ module RuboCop
138
161
  def nodoc(node)
139
162
  processed_source.ast_with_comments[node.children.first].first
140
163
  end
164
+
165
+ def allowed_constants
166
+ @allowed_constants ||= cop_config.fetch('AllowedConstants', []).map(&:intern)
167
+ end
141
168
  end
142
169
  end
143
170
  end
@@ -97,6 +97,7 @@ module RuboCop
97
97
 
98
98
  MSG = 'Missing method documentation comment.'
99
99
 
100
+ # @!method module_function_node?(node)
100
101
  def_node_matcher :module_function_node?, <<~PATTERN
101
102
  (send nil? :module_function ...)
102
103
  PATTERN
@@ -5,8 +5,8 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks for uses of double negation (`!!`) to convert something to a boolean value.
7
7
  #
8
- # When using `EnforcedStyle: allowed_in_returns`, allow double nagation in contexts
9
- # that use boolean as a return value. When using `EnforcedStyle: forbidden`, double nagation
8
+ # When using `EnforcedStyle: allowed_in_returns`, allow double negation in contexts
9
+ # that use boolean as a return value. When using `EnforcedStyle: forbidden`, double negation
10
10
  # should be forbidden always.
11
11
  #
12
12
  # @example
@@ -39,6 +39,7 @@ module RuboCop
39
39
  MSG = 'Avoid the use of double negation (`!!`).'
40
40
  RESTRICT_ON_SEND = %i[!].freeze
41
41
 
42
+ # @!method double_negative?(node)
42
43
  def_node_matcher :double_negative?, '(send (send _ :!) :!)'
43
44
 
44
45
  def on_send(node)
@@ -46,6 +46,7 @@ module RuboCop
46
46
 
47
47
  private
48
48
 
49
+ # @!method offending_each_range(node)
49
50
  def_node_matcher :offending_each_range, <<~PATTERN
50
51
  (block (send (begin (${irange erange} (int $_) (int $_))) :each) (args) ...)
51
52
  PATTERN
@@ -23,6 +23,7 @@ module RuboCop
23
23
  MSG = 'Use `each_with_object` instead of `%<method>s`.'
24
24
  METHODS = %i[inject reduce].freeze
25
25
 
26
+ # @!method each_with_object_candidate?(node)
26
27
  def_node_matcher :each_with_object_candidate?, <<~PATTERN
27
28
  (block $(send _ {:inject :reduce} _) $_ $_)
28
29
  PATTERN
@@ -27,11 +27,20 @@ module RuboCop
27
27
 
28
28
  RESTRICT_ON_SEND = %i[new].freeze
29
29
 
30
+ # @!method array_node(node)
30
31
  def_node_matcher :array_node, '(send (const {nil? cbase} :Array) :new)'
32
+
33
+ # @!method hash_node(node)
31
34
  def_node_matcher :hash_node, '(send (const {nil? cbase} :Hash) :new)'
35
+
36
+ # @!method str_node(node)
32
37
  def_node_matcher :str_node, '(send (const {nil? cbase} :String) :new)'
38
+
39
+ # @!method array_with_block(node)
33
40
  def_node_matcher :array_with_block,
34
41
  '(block (send (const {nil? cbase} :Array) :new) args _)'
42
+
43
+ # @!method hash_with_block(node)
35
44
  def_node_matcher :hash_with_block, <<~PATTERN
36
45
  {
37
46
  (block (send (const {nil? cbase} :Hash) :new) args _)
@@ -11,6 +11,7 @@ module RuboCop
11
11
  # Other method definition types are not considered by this cop.
12
12
  #
13
13
  # The supported styles are:
14
+ #
14
15
  # * allow_single_line (default) - only single line endless method definitions are allowed.
15
16
  # * allow_always - all endless method definitions are allowed.
16
17
  # * disallow - all endless method definitions are disallowed.
@@ -12,6 +12,11 @@ module RuboCop
12
12
  # The cop also checks that the line number given relative to `__LINE__` is
13
13
  # correct.
14
14
  #
15
+ # This cop will autocorrect incorrect or missing filename and line number
16
+ # values. However, if `eval` is called without a binding argument, the cop
17
+ # will not attempt to automatically add a binding, or add filename and
18
+ # line values.
19
+ #
15
20
  # @example
16
21
  # # bad
17
22
  # eval <<-RUBY
@@ -36,7 +41,21 @@ module RuboCop
36
41
  # def do_something
37
42
  # end
38
43
  # RUBY
44
+ #
45
+ # This cop works only when a string literal is given as a code string.
46
+ # No offence is reported if a string variable is given as below:
47
+ #
48
+ # @example
49
+ # # not checked
50
+ # code = <<-RUBY
51
+ # def do_something
52
+ # end
53
+ # RUBY
54
+ # eval code
55
+ #
39
56
  class EvalWithLocation < Base
57
+ extend AutoCorrector
58
+
40
59
  MSG = 'Pass `__FILE__` and `__LINE__` to `%<method_name>s`.'
41
60
  MSG_EVAL = 'Pass a binding, `__FILE__` and `__LINE__` to `eval`.'
42
61
  MSG_INCORRECT_FILE = 'Incorrect file for `%<method_name>s`; ' \
@@ -46,10 +65,12 @@ module RuboCop
46
65
 
47
66
  RESTRICT_ON_SEND = %i[eval class_eval module_eval instance_eval].freeze
48
67
 
68
+ # @!method valid_eval_receiver?(node)
49
69
  def_node_matcher :valid_eval_receiver?, <<~PATTERN
50
70
  { nil? (const {nil? cbase} :Kernel) }
51
71
  PATTERN
52
72
 
73
+ # @!method line_with_offset?(node, sign, num)
53
74
  def_node_matcher :line_with_offset?, <<~PATTERN
54
75
  {
55
76
  (send #special_line_keyword? %1 (int %2))
@@ -64,23 +85,30 @@ module RuboCop
64
85
  return if node.method?(:eval) && !valid_eval_receiver?(node.receiver)
65
86
 
66
87
  code = node.arguments.first
67
- return unless code.str_type? || code.dstr_type?
88
+ return unless code && (code.str_type? || code.dstr_type?)
89
+
90
+ check_location(node, code)
91
+ end
92
+
93
+ private
68
94
 
95
+ def check_location(node, code)
69
96
  file, line = file_and_line(node)
70
97
 
71
98
  if line
72
99
  check_file(node, file)
73
100
  check_line(node, code)
101
+ elsif file
102
+ check_file(node, file)
103
+ add_offense_for_missing_line(node, code)
74
104
  else
75
- register_offense(node)
105
+ add_offense_for_missing_location(node, code)
76
106
  end
77
107
  end
78
108
 
79
- private
80
-
81
- def register_offense(node)
109
+ def register_offense(node, &block)
82
110
  msg = node.method?(:eval) ? MSG_EVAL : format(MSG, method_name: node.method_name)
83
- add_offense(node, message: msg)
111
+ add_offense(node, message: msg, &block)
84
112
  end
85
113
 
86
114
  def special_file_keyword?(node)
@@ -98,6 +126,10 @@ module RuboCop
98
126
  [node.arguments[base], node.arguments[base + 1]]
99
127
  end
100
128
 
129
+ def with_binding?(node)
130
+ node.method?(:eval) ? node.arguments.size >= 2 : true
131
+ end
132
+
101
133
  # FIXME: It's a Style/ConditionalAssignment's false positive.
102
134
  # rubocop:disable Style/ConditionalAssignment
103
135
  def with_lineno?(node)
@@ -109,18 +141,16 @@ module RuboCop
109
141
  end
110
142
  # rubocop:enable Style/ConditionalAssignment
111
143
 
112
- def message_incorrect_line(method_name, actual, sign, line_diff)
113
- expected =
114
- if line_diff.zero?
115
- '__LINE__'
116
- else
117
- "__LINE__ #{sign} #{line_diff}"
118
- end
144
+ def add_offense_for_incorrect_line(method_name, line_node, sign, line_diff)
145
+ expected = expected_line(sign, line_diff)
146
+ message = format(MSG_INCORRECT_LINE,
147
+ method_name: method_name,
148
+ actual: line_node.source,
149
+ expected: expected)
119
150
 
120
- format(MSG_INCORRECT_LINE,
121
- method_name: method_name,
122
- actual: actual.source,
123
- expected: expected)
151
+ add_offense(line_node.loc.expression, message: message) do |corrector|
152
+ corrector.replace(line_node, expected)
153
+ end
124
154
  end
125
155
 
126
156
  def check_file(node, file_node)
@@ -131,13 +161,14 @@ module RuboCop
131
161
  expected: '__FILE__',
132
162
  actual: file_node.source)
133
163
 
134
- add_offense(file_node, message: message)
164
+ add_offense(file_node, message: message) do |corrector|
165
+ corrector.replace(file_node, '__FILE__')
166
+ end
135
167
  end
136
168
 
137
169
  def check_line(node, code)
138
170
  line_node = node.arguments.last
139
- lineno_range = line_node.loc.expression
140
- line_diff = string_first_line(code) - lineno_range.first_line
171
+ line_diff = line_difference(line_node, code)
141
172
  if line_diff.zero?
142
173
  add_offense_for_same_line(node, line_node)
143
174
  else
@@ -145,6 +176,10 @@ module RuboCop
145
176
  end
146
177
  end
147
178
 
179
+ def line_difference(line_node, code)
180
+ string_first_line(code) - line_node.loc.expression.first_line
181
+ end
182
+
148
183
  def string_first_line(str_node)
149
184
  if str_node.heredoc?
150
185
  str_node.loc.heredoc_body.first_line
@@ -156,20 +191,47 @@ module RuboCop
156
191
  def add_offense_for_same_line(node, line_node)
157
192
  return if special_line_keyword?(line_node)
158
193
 
159
- add_offense(
160
- line_node.loc.expression,
161
- message: message_incorrect_line(node.method_name, line_node, nil, 0)
162
- )
194
+ add_offense_for_incorrect_line(node.method_name, line_node, nil, 0)
163
195
  end
164
196
 
165
197
  def add_offense_for_different_line(node, line_node, line_diff)
166
198
  sign = line_diff.positive? ? :+ : :-
167
199
  return if line_with_offset?(line_node, sign, line_diff.abs)
168
200
 
169
- add_offense(
170
- line_node.loc.expression,
171
- message: message_incorrect_line(node.method_name, line_node, sign, line_diff.abs)
172
- )
201
+ add_offense_for_incorrect_line(node.method_name, line_node, sign, line_diff.abs)
202
+ end
203
+
204
+ def expected_line(sign, line_diff)
205
+ if line_diff.zero?
206
+ '__LINE__'
207
+ else
208
+ "__LINE__ #{sign} #{line_diff.abs}"
209
+ end
210
+ end
211
+
212
+ def add_offense_for_missing_line(node, code)
213
+ register_offense(node) do |corrector|
214
+ line_str = missing_line(node, code)
215
+ corrector.insert_after(node.loc.expression.end, ", #{line_str}")
216
+ end
217
+ end
218
+
219
+ def add_offense_for_missing_location(node, code)
220
+ if node.method?(:eval) && !with_binding?(node)
221
+ register_offense(node)
222
+ return
223
+ end
224
+
225
+ register_offense(node) do |corrector|
226
+ line_str = missing_line(node, code)
227
+ corrector.insert_after(node.last_argument.source_range.end, ", __FILE__, #{line_str}")
228
+ end
229
+ end
230
+
231
+ def missing_line(node, code)
232
+ line_diff = line_difference(node.arguments.last, code)
233
+ sign = line_diff.positive? ? :+ : :-
234
+ expected_line(sign, line_diff)
173
235
  end
174
236
  end
175
237
  end