rubocop 0.89.1 → 0.90.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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +79 -11
  4. data/lib/rubocop.rb +13 -0
  5. data/lib/rubocop/cached_data.rb +1 -0
  6. data/lib/rubocop/cli/command.rb +1 -0
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -0
  8. data/lib/rubocop/cli/command/base.rb +1 -0
  9. data/lib/rubocop/cli/command/execute_runner.rb +1 -0
  10. data/lib/rubocop/cli/command/init_dotfile.rb +1 -0
  11. data/lib/rubocop/cli/command/show_cops.rb +1 -0
  12. data/lib/rubocop/cli/command/version.rb +1 -0
  13. data/lib/rubocop/cli/environment.rb +1 -0
  14. data/lib/rubocop/comment_config.rb +5 -0
  15. data/lib/rubocop/config_loader.rb +17 -6
  16. data/lib/rubocop/config_loader_resolver.rb +1 -0
  17. data/lib/rubocop/config_obsoletion.rb +1 -0
  18. data/lib/rubocop/config_validator.rb +3 -0
  19. data/lib/rubocop/cop/base.rb +23 -0
  20. data/lib/rubocop/cop/bundler/gem_comment.rb +7 -3
  21. data/lib/rubocop/cop/commissioner.rb +47 -7
  22. data/lib/rubocop/cop/correctors/alignment_corrector.rb +4 -4
  23. data/lib/rubocop/cop/correctors/condition_corrector.rb +3 -5
  24. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +9 -10
  25. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
  26. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +8 -3
  27. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -8
  28. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +4 -9
  29. data/lib/rubocop/cop/correctors/punctuation_corrector.rb +8 -10
  30. data/lib/rubocop/cop/documentation.rb +22 -0
  31. data/lib/rubocop/cop/generator.rb +1 -0
  32. data/lib/rubocop/cop/layout/block_alignment.rb +23 -19
  33. data/lib/rubocop/cop/layout/class_structure.rb +10 -9
  34. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +4 -6
  35. data/lib/rubocop/cop/layout/condition_position.rb +13 -15
  36. data/lib/rubocop/cop/layout/def_end_alignment.rb +7 -4
  37. data/lib/rubocop/cop/layout/dot_position.rb +21 -17
  38. data/lib/rubocop/cop/layout/empty_comment.rb +30 -23
  39. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +19 -16
  40. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +13 -13
  41. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +144 -0
  42. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +21 -23
  43. data/lib/rubocop/cop/layout/empty_lines.rb +6 -7
  44. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +4 -6
  45. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +7 -8
  46. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +3 -6
  47. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +2 -5
  48. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -5
  49. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -5
  50. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -5
  51. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +2 -5
  52. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +2 -5
  53. data/lib/rubocop/cop/layout/end_alignment.rb +6 -7
  54. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +2 -5
  55. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +2 -5
  56. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +4 -8
  57. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +2 -5
  58. data/lib/rubocop/cop/layout/hash_alignment.rb +17 -20
  59. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +15 -14
  60. data/lib/rubocop/cop/layout/heredoc_indentation.rb +14 -11
  61. data/lib/rubocop/cop/layout/initial_indentation.rb +6 -7
  62. data/lib/rubocop/cop/layout/leading_comment_space.rb +11 -9
  63. data/lib/rubocop/cop/layout/leading_empty_lines.rb +6 -11
  64. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +2 -5
  65. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +2 -5
  66. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +10 -14
  67. data/lib/rubocop/cop/layout/multiline_block_layout.rb +21 -19
  68. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +2 -5
  69. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +2 -5
  70. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +5 -9
  71. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -5
  72. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +2 -5
  73. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +18 -21
  74. data/lib/rubocop/cop/layout/space_after_colon.rb +11 -7
  75. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -5
  76. data/lib/rubocop/cop/layout/space_after_method_name.rb +5 -6
  77. data/lib/rubocop/cop/layout/space_after_not.rb +9 -11
  78. data/lib/rubocop/cop/layout/space_after_semicolon.rb +2 -5
  79. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +20 -15
  80. data/lib/rubocop/cop/layout/space_around_keyword.rb +17 -18
  81. data/lib/rubocop/cop/layout/space_around_operators.rb +17 -16
  82. data/lib/rubocop/cop/layout/space_before_block_braces.rb +23 -22
  83. data/lib/rubocop/cop/layout/space_before_comma.rb +3 -5
  84. data/lib/rubocop/cop/layout/space_before_comment.rb +10 -7
  85. data/lib/rubocop/cop/layout/space_before_first_arg.rb +7 -7
  86. data/lib/rubocop/cop/layout/space_before_semicolon.rb +2 -5
  87. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -17
  88. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +13 -16
  89. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +3 -8
  90. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +17 -16
  91. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +16 -19
  92. data/lib/rubocop/cop/layout/space_inside_parens.rb +9 -14
  93. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +5 -10
  94. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +8 -17
  95. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +13 -16
  96. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +10 -11
  97. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +10 -15
  98. data/lib/rubocop/cop/layout/trailing_whitespace.rb +11 -11
  99. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
  100. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  101. data/lib/rubocop/cop/lint/duplicate_require.rb +41 -0
  102. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +0 -11
  103. data/lib/rubocop/cop/lint/empty_file.rb +53 -0
  104. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  105. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +2 -35
  106. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +9 -19
  107. data/lib/rubocop/cop/lint/percent_string_array.rb +8 -12
  108. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -4
  109. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  110. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +57 -0
  111. data/lib/rubocop/cop/lint/useless_method_definition.rb +77 -0
  112. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +2 -0
  113. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -0
  114. data/lib/rubocop/cop/mixin/alignment.rb +3 -0
  115. data/lib/rubocop/cop/mixin/allowed_methods.rb +2 -0
  116. data/lib/rubocop/cop/mixin/annotation_comment.rb +5 -0
  117. data/lib/rubocop/cop/mixin/check_line_breakable.rb +16 -7
  118. data/lib/rubocop/cop/mixin/comments_help.rb +54 -0
  119. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +8 -7
  120. data/lib/rubocop/cop/mixin/empty_parameter.rb +3 -1
  121. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +3 -1
  122. data/lib/rubocop/cop/mixin/first_element_line_break.rb +3 -1
  123. data/lib/rubocop/cop/mixin/hash_transform_method.rb +17 -0
  124. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +3 -1
  125. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +12 -10
  126. data/lib/rubocop/cop/mixin/negative_conditional.rb +2 -2
  127. data/lib/rubocop/cop/mixin/percent_array.rb +14 -3
  128. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +1 -1
  129. data/lib/rubocop/cop/mixin/rescue_node.rb +10 -1
  130. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +4 -3
  131. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +4 -3
  132. data/lib/rubocop/cop/mixin/surrounding_space.rb +8 -4
  133. data/lib/rubocop/cop/mixin/trailing_comma.rb +7 -7
  134. data/lib/rubocop/cop/offense.rb +1 -0
  135. data/lib/rubocop/cop/severity.rb +0 -8
  136. data/lib/rubocop/cop/style/case_equality.rb +8 -3
  137. data/lib/rubocop/cop/style/case_like_if.rb +20 -4
  138. data/lib/rubocop/cop/style/class_methods_definitions.rb +131 -0
  139. data/lib/rubocop/cop/style/combinable_loops.rb +89 -0
  140. data/lib/rubocop/cop/style/empty_block_parameter.rb +9 -10
  141. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +9 -10
  142. data/lib/rubocop/cop/style/guard_clause.rb +1 -0
  143. data/lib/rubocop/cop/style/hash_syntax.rb +6 -5
  144. data/lib/rubocop/cop/style/hash_transform_keys.rb +14 -1
  145. data/lib/rubocop/cop/style/hash_transform_values.rb +14 -1
  146. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
  147. data/lib/rubocop/cop/style/keyword_parameters_order.rb +58 -0
  148. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +10 -1
  149. data/lib/rubocop/cop/style/multiline_when_then.rb +2 -2
  150. data/lib/rubocop/cop/style/negated_if.rb +6 -6
  151. data/lib/rubocop/cop/style/negated_unless.rb +6 -6
  152. data/lib/rubocop/cop/style/negated_while.rb +7 -15
  153. data/lib/rubocop/cop/style/nested_modifier.rb +10 -13
  154. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +11 -11
  155. data/lib/rubocop/cop/style/nested_ternary_operator.rb +14 -16
  156. data/lib/rubocop/cop/style/next.rb +10 -14
  157. data/lib/rubocop/cop/style/nil_comparison.rb +11 -11
  158. data/lib/rubocop/cop/style/non_nil_check.rb +32 -26
  159. data/lib/rubocop/cop/style/not.rb +19 -26
  160. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +4 -9
  161. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -11
  162. data/lib/rubocop/cop/style/one_line_conditional.rb +71 -23
  163. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  164. data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
  165. data/lib/rubocop/cop/style/or_assignment.rb +13 -10
  166. data/lib/rubocop/cop/style/parallel_assignment.rb +14 -14
  167. data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -6
  168. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +13 -19
  169. data/lib/rubocop/cop/style/percent_q_literals.rb +8 -10
  170. data/lib/rubocop/cop/style/perl_backrefs.rb +8 -10
  171. data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -14
  172. data/lib/rubocop/cop/style/proc.rb +6 -6
  173. data/lib/rubocop/cop/style/raise_args.rb +13 -24
  174. data/lib/rubocop/cop/style/random_with_offset.rb +15 -16
  175. data/lib/rubocop/cop/style/redundant_assignment.rb +8 -10
  176. data/lib/rubocop/cop/style/redundant_begin.rb +7 -9
  177. data/lib/rubocop/cop/style/redundant_capital_w.rb +6 -9
  178. data/lib/rubocop/cop/style/redundant_condition.rb +5 -6
  179. data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -12
  180. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +8 -8
  181. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -6
  182. data/lib/rubocop/cop/style/redundant_interpolation.rb +25 -24
  183. data/lib/rubocop/cop/style/redundant_parentheses.rb +7 -9
  184. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -13
  185. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +5 -14
  186. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  187. data/lib/rubocop/cop/style/redundant_self_assignment.rb +116 -0
  188. data/lib/rubocop/cop/style/regexp_literal.rb +10 -21
  189. data/lib/rubocop/cop/style/rescue_modifier.rb +29 -9
  190. data/lib/rubocop/cop/style/return_nil.rb +5 -5
  191. data/lib/rubocop/cop/style/safe_navigation.rb +13 -12
  192. data/lib/rubocop/cop/style/sample.rb +10 -13
  193. data/lib/rubocop/cop/style/self_assignment.rb +26 -22
  194. data/lib/rubocop/cop/style/semicolon.rb +6 -9
  195. data/lib/rubocop/cop/style/send.rb +2 -2
  196. data/lib/rubocop/cop/style/signal_exception.rb +21 -19
  197. data/lib/rubocop/cop/style/single_line_block_params.rb +4 -2
  198. data/lib/rubocop/cop/style/single_line_methods.rb +17 -16
  199. data/lib/rubocop/cop/style/slicing_with_range.rb +4 -7
  200. data/lib/rubocop/cop/style/sole_nested_conditional.rb +66 -0
  201. data/lib/rubocop/cop/style/special_global_vars.rb +10 -15
  202. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +17 -21
  203. data/lib/rubocop/cop/style/stderr_puts.rb +4 -6
  204. data/lib/rubocop/cop/style/string_hash_keys.rb +6 -7
  205. data/lib/rubocop/cop/style/string_methods.rb +7 -17
  206. data/lib/rubocop/cop/style/strip.rb +8 -14
  207. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -6
  208. data/lib/rubocop/cop/style/symbol_array.rb +5 -16
  209. data/lib/rubocop/cop/style/symbol_literal.rb +4 -6
  210. data/lib/rubocop/cop/style/symbol_proc.rb +14 -18
  211. data/lib/rubocop/cop/style/ternary_parentheses.rb +21 -20
  212. data/lib/rubocop/cop/style/trailing_body_on_class.rb +3 -6
  213. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +4 -7
  214. data/lib/rubocop/cop/style/trailing_body_on_module.rb +3 -6
  215. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
  216. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +2 -5
  217. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +7 -6
  218. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +2 -5
  219. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +8 -17
  220. data/lib/rubocop/cop/style/trivial_accessors.rb +26 -30
  221. data/lib/rubocop/cop/style/unless_else.rb +5 -8
  222. data/lib/rubocop/cop/style/unpack_first.rb +4 -8
  223. data/lib/rubocop/cop/style/variable_interpolation.rb +7 -10
  224. data/lib/rubocop/cop/style/when_then.rb +4 -6
  225. data/lib/rubocop/cop/style/while_until_do.rb +6 -16
  226. data/lib/rubocop/cop/style/while_until_modifier.rb +6 -20
  227. data/lib/rubocop/cop/style/word_array.rb +5 -23
  228. data/lib/rubocop/cop/style/yoda_condition.rb +4 -15
  229. data/lib/rubocop/cop/style/zero_length_predicate.rb +11 -13
  230. data/lib/rubocop/cop/team.rb +1 -0
  231. data/lib/rubocop/cop/util.rb +1 -1
  232. data/lib/rubocop/cop/utils/format_string.rb +3 -5
  233. data/lib/rubocop/cop/variable_force.rb +2 -0
  234. data/lib/rubocop/cops_documentation_generator.rb +4 -2
  235. data/lib/rubocop/core_ext/string.rb +1 -1
  236. data/lib/rubocop/ext/regexp_node.rb +46 -0
  237. data/lib/rubocop/file_finder.rb +1 -0
  238. data/lib/rubocop/formatter/auto_gen_config_formatter.rb +2 -1
  239. data/lib/rubocop/formatter/html_formatter.rb +2 -0
  240. data/lib/rubocop/formatter/progress_formatter.rb +2 -1
  241. data/lib/rubocop/formatter/quiet_formatter.rb +1 -1
  242. data/lib/rubocop/formatter/simple_text_formatter.rb +36 -6
  243. data/lib/rubocop/name_similarity.rb +1 -0
  244. data/lib/rubocop/options.rb +3 -0
  245. data/lib/rubocop/remote_config.rb +1 -0
  246. data/lib/rubocop/result_cache.rb +1 -0
  247. data/lib/rubocop/rspec/cop_helper.rb +4 -1
  248. data/lib/rubocop/rspec/expect_offense.rb +10 -5
  249. data/lib/rubocop/rspec/shared_contexts.rb +12 -0
  250. data/lib/rubocop/runner.rb +1 -0
  251. data/lib/rubocop/string_interpreter.rb +3 -0
  252. data/lib/rubocop/target_finder.rb +1 -0
  253. data/lib/rubocop/target_ruby.rb +6 -0
  254. data/lib/rubocop/version.rb +2 -1
  255. data/lib/rubocop/yaml_duplication_checker.rb +1 -0
  256. metadata +15 -2
@@ -5,6 +5,7 @@ require 'pathname'
5
5
 
6
6
  module RuboCop
7
7
  # A help class for ConfigLoader that handles configuration resolution.
8
+ # @api private
8
9
  class ConfigLoaderResolver
9
10
  def resolve_requires(path, hash)
10
11
  config_dir = File.dirname(path)
@@ -2,6 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  # This class handles obsolete configuration.
5
+ # @api private
5
6
  class ConfigObsoletion
6
7
  RENAMED_COPS = {
7
8
  'Layout/AlignArguments' => 'Layout/ArgumentAlignment',
@@ -8,11 +8,14 @@ module RuboCop
8
8
  class ConfigValidator
9
9
  extend Forwardable
10
10
 
11
+ # @api private
11
12
  COMMON_PARAMS = %w[Exclude Include Severity inherit_mode
12
13
  AutoCorrect StyleGuide Details].freeze
14
+ # @api private
13
15
  INTERNAL_PARAMS = %w[Description StyleGuide
14
16
  VersionAdded VersionChanged VersionRemoved
15
17
  Reference Safe SafeAutoCorrect].freeze
18
+ # @api private
16
19
  NEW_COPS_VALUES = %w[pending disable enable].freeze
17
20
 
18
21
  def_delegators :@config, :smart_loaded_path, :for_all_cops
@@ -46,6 +46,9 @@ module RuboCop
46
46
  # Consider creation API private
47
47
  InvestigationReport = Struct.new(:cop, :processed_source, :offenses, :corrector)
48
48
 
49
+ # List of methods names to restrict calls for `on_send` / `on_csend`
50
+ RESTRICT_ON_SEND = Set[].freeze
51
+
49
52
  # List of cops that should not try to autocorrect at the same
50
53
  # time as this cop
51
54
  #
@@ -56,6 +59,14 @@ module RuboCop
56
59
  []
57
60
  end
58
61
 
62
+ # Cops (other than builtin) are encouraged to implement this
63
+ # @return [String, nil]
64
+ #
65
+ # @api public
66
+ def self.documentation_url
67
+ Documentation.url_for(self) if builtin?
68
+ end
69
+
59
70
  def initialize(config = nil, options = nil)
60
71
  @config = config || Config.new
61
72
  @options = options || { debug: false }
@@ -279,6 +290,10 @@ module RuboCop
279
290
  @currently_disabled_lines ||= Set.new
280
291
  end
281
292
 
293
+ private_class_method def self.restrict_on_send
294
+ @restrict_on_send ||= self::RESTRICT_ON_SEND.to_set.freeze
295
+ end
296
+
282
297
  # Called before any investigation
283
298
  def begin_investigation(processed_source)
284
299
  @current_offenses = []
@@ -297,6 +312,14 @@ module RuboCop
297
312
 
298
313
  ### Actually private methods
299
314
 
315
+ def self.builtin?
316
+ return false unless (m = instance_methods(false).first) # any custom method will do
317
+
318
+ path, _line = instance_method(m).source_location
319
+ path.start_with?(__dir__)
320
+ end
321
+ private_class_method :builtin?
322
+
300
323
  def reset_investigation
301
324
  @currently_disabled_lines = @current_offenses = @processed_source = @current_corrector = nil
302
325
  end
@@ -70,7 +70,7 @@ module RuboCop
70
70
  def on_send(node)
71
71
  return unless gem_declaration?(node)
72
72
  return if ignored_gem?(node)
73
- return if commented?(node)
73
+ return if commented_any_descendant?(node)
74
74
  return if cop_config[CHECKED_OPTIONS_CONFIG].any? && !checked_options_present?(node)
75
75
 
76
76
  add_offense(node)
@@ -78,6 +78,10 @@ module RuboCop
78
78
 
79
79
  private
80
80
 
81
+ def commented_any_descendant?(node)
82
+ commented?(node) || node.each_descendant.any? { |n| commented?(n) }
83
+ end
84
+
81
85
  def commented?(node)
82
86
  preceding_lines = preceding_lines(node)
83
87
  preceding_comment?(node, preceding_lines.last)
@@ -86,12 +90,12 @@ module RuboCop
86
90
  # The args node1 & node2 may represent a RuboCop::AST::Node
87
91
  # or a Parser::Source::Comment. Both respond to #loc.
88
92
  def precede?(node1, node2)
89
- node2.loc.line - node1.loc.line == 1
93
+ node2.loc.line - node1.loc.line <= 1
90
94
  end
91
95
 
92
96
  def preceding_lines(node)
93
97
  processed_source.ast_with_comments[node].select do |line|
94
- line.loc.line < node.loc.line
98
+ line.loc.line <= node.loc.line
95
99
  end
96
100
  end
97
101
 
@@ -7,6 +7,9 @@ module RuboCop
7
7
  class Commissioner
8
8
  include RuboCop::AST::Traversal
9
9
 
10
+ RESTRICTED_CALLBACKS = %i[on_send on_csend].freeze
11
+ private_constant :RESTRICTED_CALLBACKS
12
+
10
13
  # How a Commissioner returns the results of the investigation
11
14
  # as a list of Cop::InvestigationReport and any errors caught
12
15
  # during the investigation.
@@ -42,7 +45,8 @@ module RuboCop
42
45
  @cops = cops
43
46
  @forces = forces
44
47
  @options = options
45
- @callbacks = {}
48
+ @callbacks = Hash.new { |h, k| h[k] = cops_callbacks_for(k) }
49
+ @restricted_map = {}
46
50
 
47
51
  reset
48
52
  end
@@ -57,10 +61,17 @@ module RuboCop
57
61
  method_name = :"on_#{node_type}"
58
62
  next unless method_defined?(method_name)
59
63
 
60
- define_method(method_name) do |node|
61
- trigger_responding_cops(method_name, node)
62
- super(node) unless NO_CHILD_NODES.include?(node_type)
64
+ if RESTRICTED_CALLBACKS.include?(method_name)
65
+ trigger_restricted = "trigger_restricted_cops(:on_#{node_type}, node)"
63
66
  end
67
+
68
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
69
+ def on_#{node_type}(node)
70
+ trigger_responding_cops(:on_#{node_type}, node)
71
+ #{trigger_restricted}
72
+ #{'super(node)' unless NO_CHILD_NODES.include?(node_type)}
73
+ end
74
+ RUBY
64
75
  end
65
76
 
66
77
  # @return [InvestigationReport]
@@ -83,9 +94,6 @@ module RuboCop
83
94
  private
84
95
 
85
96
  def trigger_responding_cops(callback, node)
86
- @callbacks[callback] ||= @cops.select do |cop|
87
- cop.respond_to?(callback)
88
- end
89
97
  @callbacks[callback].each do |cop|
90
98
  with_cop_error_handling(cop, node) do
91
99
  cop.send(callback, node)
@@ -97,6 +105,38 @@ module RuboCop
97
105
  @errors = []
98
106
  end
99
107
 
108
+ def cops_callbacks_for(callback)
109
+ callbacks = @cops.select do |cop|
110
+ cop.respond_to?(callback)
111
+ end
112
+ if RESTRICTED_CALLBACKS.include?(callback)
113
+ @restricted_map[callback] = restricted_map(callbacks)
114
+ end
115
+ callbacks
116
+ end
117
+
118
+ def trigger_restricted_cops(event, node)
119
+ name = node.method_name
120
+ @restricted_map.fetch(event)[name]&.each do |cop|
121
+ with_cop_error_handling(cop, node) do
122
+ cop.send(event, node)
123
+ end
124
+ end
125
+ end
126
+
127
+ # Note: mutates `callbacks` in place
128
+ def restricted_map(callbacks)
129
+ map = {}
130
+ callbacks.select! do |cop|
131
+ restrictions = cop.class.send :restrict_on_send
132
+ restrictions.each do |name|
133
+ (map[name] ||= []) << cop
134
+ end
135
+ restrictions.empty?
136
+ end
137
+ map
138
+ end
139
+
100
140
  def invoke(callback, cops, *args)
101
141
  cops.each do |cop|
102
142
  with_cop_error_handling(cop) do
@@ -29,13 +29,13 @@ module RuboCop
29
29
  end
30
30
  end
31
31
 
32
- def align_end(processed_source, node, align_to)
32
+ def align_end(corrector, processed_source, node, align_to)
33
33
  @processed_source = processed_source
34
34
  whitespace = whitespace_range(node)
35
35
  return false unless whitespace.source.strip.empty?
36
36
 
37
37
  column = alignment_column(align_to)
38
- ->(corrector) { corrector.replace(whitespace, ' ' * column) }
38
+ corrector.replace(whitespace, ' ' * column)
39
39
  end
40
40
 
41
41
  private
@@ -47,8 +47,8 @@ module RuboCop
47
47
  # string literals
48
48
  return if taboo_ranges.any? { |t| within?(range, t) }
49
49
 
50
- if column_delta.positive?
51
- corrector.insert_before(range, ' ' * column_delta) unless range.resize(1).source == "\n"
50
+ if column_delta.positive? && range.resize(1).source != "\n"
51
+ corrector.insert_before(range, ' ' * column_delta)
52
52
  elsif /\A[ \t]+\z/.match?(range.source)
53
53
  remove(range, corrector)
54
54
  end
@@ -5,13 +5,11 @@ module RuboCop
5
5
  # This class does condition auto-correction
6
6
  class ConditionCorrector
7
7
  class << self
8
- def correct_negative_condition(node)
8
+ def correct_negative_condition(corrector, node)
9
9
  condition = negated_condition(node)
10
10
 
11
- lambda do |corrector|
12
- corrector.replace(node.loc.keyword, node.inverse_keyword)
13
- corrector.replace(condition, condition.children.first.source)
14
- end
11
+ corrector.replace(node.loc.keyword, node.inverse_keyword)
12
+ corrector.replace(condition, condition.children.first.source)
15
13
  end
16
14
 
17
15
  private
@@ -5,20 +5,19 @@ module RuboCop
5
5
  # This class does empty line auto-correction
6
6
  class EmptyLineCorrector
7
7
  class << self
8
- def correct(node)
8
+ def correct(corrector, node)
9
9
  offense_style, range = node
10
- lambda do |corrector|
11
- case offense_style
12
- when :no_empty_lines
13
- corrector.remove(range)
14
- when :empty_lines
15
- corrector.insert_before(range, "\n")
16
- end
10
+
11
+ case offense_style
12
+ when :no_empty_lines
13
+ corrector.remove(range)
14
+ when :empty_lines
15
+ corrector.insert_before(range, "\n")
17
16
  end
18
17
  end
19
18
 
20
- def insert_before(node)
21
- ->(corrector) { corrector.insert_before(node, "\n") }
19
+ def insert_before(corrector, node)
20
+ corrector.insert_before(node, "\n")
22
21
  end
23
22
  end
24
23
  end
@@ -25,8 +25,8 @@ module RuboCop
25
25
  remove_semicolon(node, corrector)
26
26
  end
27
27
 
28
- def break_line_before(range:, node:, corrector:, indent_steps: 1,
29
- configured_width:)
28
+ def break_line_before(range:, node:, corrector:, configured_width:,
29
+ indent_steps: 1)
30
30
  corrector.insert_before(
31
31
  range,
32
32
  "\n#{' ' * (node.loc.keyword.column +
@@ -8,12 +8,17 @@ module RuboCop
8
8
  include MultilineLiteralBraceLayout
9
9
  include RangeHelp
10
10
 
11
- def initialize(node, processed_source)
11
+ def self.correct(corrector, node, processed_source)
12
+ new(corrector, node, processed_source).call
13
+ end
14
+
15
+ def initialize(corrector, node, processed_source)
16
+ @corrector = corrector
12
17
  @node = node
13
18
  @processed_source = processed_source
14
19
  end
15
20
 
16
- def call(corrector)
21
+ def call
17
22
  if closing_brace_on_same_line?(node)
18
23
  correct_same_line_brace(corrector)
19
24
  else
@@ -29,7 +34,7 @@ module RuboCop
29
34
 
30
35
  private
31
36
 
32
- attr_reader :node, :processed_source
37
+ attr_reader :corrector, :node, :processed_source
33
38
 
34
39
  def correct_same_line_brace(corrector)
35
40
  corrector.insert_before(node.loc.end, "\n")
@@ -5,15 +5,12 @@ module RuboCop
5
5
  # This auto-corrects parentheses
6
6
  class ParenthesesCorrector
7
7
  class << self
8
- def correct(node)
9
- lambda do |corrector|
10
- corrector.remove(node.loc.begin)
11
- corrector.remove(node.loc.end)
8
+ def correct(corrector, node)
9
+ corrector.remove(node.loc.begin)
10
+ corrector.remove(node.loc.end)
11
+ return unless ternary_condition?(node) && next_char_is_question_mark?(node)
12
12
 
13
- if ternary_condition?(node) && next_char_is_question_mark?(node)
14
- corrector.insert_after(node.loc.end, ' ')
15
- end
16
- end
13
+ corrector.insert_after(node.loc.end, ' ')
17
14
  end
18
15
 
19
16
  private
@@ -13,23 +13,18 @@ module RuboCop
13
13
  @preferred_delimiters = preferred_delimiters
14
14
  end
15
15
 
16
- def correct(node, char)
16
+ def correct(corrector, node, char)
17
17
  escape = escape_words?(node)
18
18
  char = char.upcase if escape
19
19
  delimiters = delimiters_for("%#{char}")
20
20
  contents = new_contents(node, escape, delimiters)
21
- wrap_contents(node, contents, char, delimiters)
21
+ wrap_contents(corrector, node, contents, char, delimiters)
22
22
  end
23
23
 
24
24
  private
25
25
 
26
- def wrap_contents(node, contents, char, delimiters)
27
- lambda do |corrector|
28
- corrector.replace(
29
- node,
30
- "%#{char}#{delimiters[0]}#{contents}#{delimiters[1]}"
31
- )
32
- end
26
+ def wrap_contents(corrector, node, contents, char, delimiters)
27
+ corrector.replace(node, "%#{char}#{delimiters[0]}#{contents}#{delimiters[1]}")
33
28
  end
34
29
 
35
30
  def escape_words?(node)
@@ -5,22 +5,20 @@ module RuboCop
5
5
  # This auto-corrects punctuation
6
6
  class PunctuationCorrector
7
7
  class << self
8
- def remove_space(space_before)
9
- ->(corrector) { corrector.remove(space_before) }
8
+ def remove_space(corrector, space_before)
9
+ corrector.remove(space_before)
10
10
  end
11
11
 
12
- def add_space(token)
13
- ->(corrector) { corrector.replace(token.pos, "#{token.pos.source} ") }
12
+ def add_space(corrector, token)
13
+ corrector.replace(token.pos, "#{token.pos.source} ")
14
14
  end
15
15
 
16
- def swap_comma(range)
16
+ def swap_comma(corrector, range)
17
17
  return unless range
18
18
 
19
- lambda do |corrector|
20
- case range.source
21
- when ',' then corrector.remove(range)
22
- else corrector.insert_after(range, ',')
23
- end
19
+ case range.source
20
+ when ',' then corrector.remove(range)
21
+ else corrector.insert_after(range, ',')
24
22
  end
25
23
  end
26
24
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Helpers for builtin documentation
6
+ module Documentation
7
+ module_function
8
+
9
+ # @api private
10
+ def department_to_basename(department)
11
+ "cops_#{department.downcase}"
12
+ end
13
+
14
+ # @api private
15
+ def url_for(cop_class)
16
+ base = department_to_basename(cop_class.department)
17
+ fragment = cop_class.cop_name.downcase.gsub(/[^a-z]/, '')
18
+ "https://docs.rubocop.org/rubocop/#{base}.html##{fragment}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -6,6 +6,7 @@ module RuboCop
6
6
  #
7
7
  # This generator will take a cop name and generate a source file
8
8
  # and spec file when given a valid qualified cop name.
9
+ # @api private
9
10
  class Generator
10
11
  # Note: RDoc 5.1.0 or lower has the following issue.
11
12
  # https://github.com/rubocop-hq/rubocop/issues/7043
@@ -61,9 +61,10 @@ module RuboCop
61
61
  # .each do
62
62
  # baz
63
63
  # end
64
- class BlockAlignment < Cop
64
+ class BlockAlignment < Base
65
65
  include ConfigurableEnforcedStyle
66
66
  include RangeHelp
67
+ extend AutoCorrector
67
68
 
68
69
  MSG = '%<current>s is not aligned with %<prefer>s%<alt_prefer>s.'
69
70
 
@@ -84,19 +85,6 @@ module RuboCop
84
85
  'EnforcedStyleAlignWith'
85
86
  end
86
87
 
87
- def autocorrect(node)
88
- ancestor_node = start_for_block_node(node)
89
- start_col = compute_start_col(ancestor_node, node)
90
- loc_end = node.loc.end
91
- delta = start_col - loc_end.column
92
-
93
- if delta.positive?
94
- add_space_before(loc_end, delta)
95
- elsif delta.negative?
96
- remove_space_before(loc_end.begin_pos, -delta)
97
- end
98
- end
99
-
100
88
  private
101
89
 
102
90
  def start_for_block_node(block_node)
@@ -163,7 +151,22 @@ module RuboCop
163
151
  message = format_message(start_loc, end_loc, do_source_line_column,
164
152
  error_source_line_column)
165
153
 
166
- add_offense(block_node, location: end_loc, message: message)
154
+ add_offense(end_loc, message: message) do |corrector|
155
+ autocorrect(corrector, block_node)
156
+ end
157
+ end
158
+
159
+ def autocorrect(corrector, node)
160
+ ancestor_node = start_for_block_node(node)
161
+ start_col = compute_start_col(ancestor_node, node)
162
+ loc_end = node.loc.end
163
+ delta = start_col - loc_end.column
164
+
165
+ if delta.positive?
166
+ add_space_before(corrector, loc_end, delta)
167
+ elsif delta.negative?
168
+ remove_space_before(corrector, loc_end.begin_pos, -delta)
169
+ end
167
170
  end
168
171
 
169
172
  def format_message(start_loc, end_loc, do_source_line_column,
@@ -230,13 +233,14 @@ module RuboCop
230
233
  (ancestor_node || node).source_range.column
231
234
  end
232
235
 
233
- def add_space_before(loc, delta)
234
- ->(corrector) { corrector.insert_before(loc, ' ' * delta) }
236
+ def add_space_before(corrector, loc, delta)
237
+ corrector.insert_before(loc, ' ' * delta)
235
238
  end
236
239
 
237
- def remove_space_before(end_pos, delta)
240
+ def remove_space_before(corrector, end_pos, delta)
238
241
  range = range_between(end_pos - delta, end_pos)
239
- ->(corrector) { corrector.remove(range) }
242
+
243
+ corrector.remove(range)
240
244
  end
241
245
  end
242
246
  end