rubocop 1.32.0 → 1.35.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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +73 -16
  4. data/config/obsoletion.yml +23 -1
  5. data/lib/rubocop/cache_config.rb +29 -0
  6. data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +2 -2
  7. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  8. data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
  9. data/lib/rubocop/config.rb +1 -1
  10. data/lib/rubocop/config_finder.rb +68 -0
  11. data/lib/rubocop/config_loader.rb +12 -40
  12. data/lib/rubocop/config_loader_resolver.rb +1 -5
  13. data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
  14. data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
  15. data/lib/rubocop/config_obsoletion.rb +7 -2
  16. data/lib/rubocop/cop/cop.rb +1 -1
  17. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
  18. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  19. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
  20. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
  21. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
  22. data/lib/rubocop/cop/internal_affairs.rb +2 -0
  23. data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
  24. data/lib/rubocop/cop/layout/block_end_newline.rb +35 -5
  25. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
  26. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
  27. data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
  28. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
  29. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
  30. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
  31. data/lib/rubocop/cop/layout/indentation_width.rb +2 -0
  32. data/lib/rubocop/cop/layout/line_length.rb +4 -1
  33. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  34. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  35. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  36. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  37. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  38. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  39. data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
  40. data/lib/rubocop/cop/legacy/corrector.rb +1 -1
  41. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
  42. data/lib/rubocop/cop/lint/debugger.rb +26 -16
  43. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  44. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  45. data/lib/rubocop/cop/lint/empty_conditional_body.rb +65 -1
  46. data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
  47. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
  48. data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
  49. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
  50. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
  51. data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
  52. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
  53. data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
  54. data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
  55. data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -0
  56. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +10 -1
  57. data/lib/rubocop/cop/lint/unreachable_loop.rb +7 -1
  58. data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -4
  59. data/lib/rubocop/cop/lint/void.rb +2 -0
  60. data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
  61. data/lib/rubocop/cop/metrics/block_length.rb +6 -7
  62. data/lib/rubocop/cop/metrics/method_length.rb +8 -8
  63. data/lib/rubocop/cop/mixin/allowed_methods.rb +15 -1
  64. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -1
  65. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  66. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  67. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
  68. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +76 -1
  69. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
  70. data/lib/rubocop/cop/mixin/method_complexity.rb +8 -13
  71. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
  72. data/lib/rubocop/cop/mixin/range_help.rb +4 -5
  73. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  74. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  75. data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
  76. data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
  77. data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
  78. data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
  79. data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
  80. data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
  81. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  82. data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
  83. data/lib/rubocop/cop/style/double_negation.rb +2 -0
  84. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  85. data/lib/rubocop/cop/style/each_with_object.rb +39 -8
  86. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  87. data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
  88. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  89. data/lib/rubocop/cop/style/for.rb +2 -0
  90. data/lib/rubocop/cop/style/format_string_token.rb +21 -8
  91. data/lib/rubocop/cop/style/guard_clause.rb +27 -16
  92. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
  93. data/lib/rubocop/cop/style/hash_except.rb +0 -4
  94. data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
  95. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
  96. data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
  97. data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
  98. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
  99. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
  100. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
  101. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
  102. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  103. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
  104. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  105. data/lib/rubocop/cop/style/next.rb +3 -5
  106. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  107. data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
  108. data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
  109. data/lib/rubocop/cop/style/object_then.rb +2 -0
  110. data/lib/rubocop/cop/style/proc.rb +4 -1
  111. data/lib/rubocop/cop/style/redundant_begin.rb +2 -0
  112. data/lib/rubocop/cop/style/redundant_condition.rb +19 -4
  113. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  114. data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -22
  115. data/lib/rubocop/cop/style/redundant_self.rb +2 -0
  116. data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
  117. data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
  118. data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
  119. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  120. data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
  121. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  122. data/lib/rubocop/cop/style/symbol_proc.rb +34 -9
  123. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
  124. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
  125. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  126. data/lib/rubocop/cop/style/word_array.rb +1 -1
  127. data/lib/rubocop/cop/util.rb +1 -1
  128. data/lib/rubocop/ext/range.rb +15 -0
  129. data/lib/rubocop/feature_loader.rb +94 -0
  130. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  131. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  132. data/lib/rubocop/formatter/html_formatter.rb +3 -3
  133. data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
  134. data/lib/rubocop/formatter/tap_formatter.rb +1 -1
  135. data/lib/rubocop/result_cache.rb +22 -20
  136. data/lib/rubocop/server/cache.rb +36 -1
  137. data/lib/rubocop/server/cli.rb +19 -2
  138. data/lib/rubocop/version.rb +1 -1
  139. data/lib/rubocop.rb +5 -3
  140. metadata +15 -9
  141. data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -47,10 +47,15 @@ module RuboCop
47
47
 
48
48
  # Default rules for obsoletions are in config/obsoletion.yml
49
49
  # Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename`
50
- def load_rules
50
+ def load_rules # rubocop:disable Metrics/AbcSize
51
51
  rules = self.class.files.each_with_object({}) do |filename, hash|
52
52
  hash.merge!(YAML.safe_load(File.read(filename))) do |_key, first, second|
53
- first.merge(second)
53
+ case first
54
+ when Hash
55
+ first.merge(second)
56
+ when Array
57
+ first.concat(second)
58
+ end
54
59
  end
55
60
  end
56
61
 
@@ -7,7 +7,7 @@ module RuboCop
7
7
  module Cop
8
8
  # @deprecated Use Cop::Base instead
9
9
  # Legacy scaffold for Cops.
10
- # See https://docs.rubocop.org/rubocop/cop_api_v1_changelog.html
10
+ # See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html
11
11
  class Cop < Base
12
12
  attr_reader :offenses
13
13
 
@@ -5,9 +5,15 @@ module RuboCop
5
5
  # This autocorrects parentheses
6
6
  class ParenthesesCorrector
7
7
  class << self
8
+ include RangeHelp
9
+
10
+ COMMA_REGEXP = /(?<=\))\s*,/.freeze
11
+
8
12
  def correct(corrector, node)
9
13
  corrector.remove(node.loc.begin)
10
14
  corrector.remove(node.loc.end)
15
+ handle_orphaned_comma(corrector, node)
16
+
11
17
  return unless ternary_condition?(node) && next_char_is_question_mark?(node)
12
18
 
13
19
  corrector.insert_after(node.loc.end, ' ')
@@ -22,6 +28,58 @@ module RuboCop
22
28
  def next_char_is_question_mark?(node)
23
29
  node.loc.last_column == node.parent.loc.question.column
24
30
  end
31
+
32
+ def only_closing_paren_before_comma?(node)
33
+ source_buffer = node.source_range.source_buffer
34
+ line_range = source_buffer.line_range(node.loc.end.line)
35
+
36
+ line_range.source.start_with?(/\s*\)\s*,/)
37
+ end
38
+
39
+ # If removing parentheses leaves a comma on its own line, remove all the whitespace
40
+ # preceding it to prevent a syntax error.
41
+ def handle_orphaned_comma(corrector, node)
42
+ return unless only_closing_paren_before_comma?(node)
43
+
44
+ range = extend_range_for_heredoc(node, parens_range(node))
45
+ corrector.remove(range)
46
+
47
+ add_heredoc_comma(corrector, node)
48
+ end
49
+
50
+ # Get a range for the closing parenthesis and all whitespace to the left of it
51
+ def parens_range(node)
52
+ range_with_surrounding_space(
53
+ range: node.loc.end,
54
+ buffer: node.source_range.source_buffer,
55
+ side: :left,
56
+ newlines: true,
57
+ whitespace: true,
58
+ continuations: true
59
+ )
60
+ end
61
+
62
+ # If the node contains a heredoc, remove the comma too
63
+ # It'll be added back in the right place later
64
+ def extend_range_for_heredoc(node, range)
65
+ return range unless heredoc?(node)
66
+
67
+ comma_line = range_by_whole_lines(node.loc.end, buffer: node.source_range.source_buffer)
68
+ offset = comma_line.source.match(COMMA_REGEXP)[0]&.size || 0
69
+
70
+ range.adjust(end_pos: offset)
71
+ end
72
+
73
+ # Add a comma back after the heredoc identifier
74
+ def add_heredoc_comma(corrector, node)
75
+ return unless heredoc?(node)
76
+
77
+ corrector.insert_after(node.child_nodes.last.loc.expression, ',')
78
+ end
79
+
80
+ def heredoc?(node)
81
+ node.child_nodes.last.loc.is_a?(Parser::Source::Map::Heredoc)
82
+ end
25
83
  end
26
84
  end
27
85
  end
@@ -84,7 +84,7 @@ module RuboCop
84
84
  (str "true")
85
85
  PATTERN
86
86
 
87
- def on_block(node) # rubocop:disable Metrics/MethodLength
87
+ def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler
88
88
  gem_specification(node) do |block_var|
89
89
  metadata_value = metadata(node)
90
90
  mfa_value = mfa_value(metadata_value)
@@ -55,8 +55,8 @@ module RuboCop
55
55
  end
56
56
  end
57
57
 
58
- def require_path_fragments(require_directove)
59
- path = require_directove.match(REQUIRE_PATH)
58
+ def require_path_fragments(require_directive)
59
+ path = require_directive.match(REQUIRE_PATH)
60
60
 
61
61
  path ? path.captures.first.split('/') : []
62
62
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks for missing `numblock handlers. The blocks with numbered
7
+ # arguments introduced in Ruby 2.7 are parsed with a node type of
8
+ # `numblock` instead of block. Cops that define `block` handlers
9
+ # need to define `numblock` handlers or disable this cope for them.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ # class BlockRelatedCop < Base
15
+ # def on_block(node)
16
+ # end
17
+ # end
18
+ #
19
+ # # good
20
+ # class BlockRelatedCop < Base
21
+ # def on_block(node)
22
+ # end
23
+ #
24
+ # alias on_numblock on_block
25
+ # end
26
+ #
27
+ # class BlockRelatedCop < Base
28
+ # def on_block(node)
29
+ # end
30
+ #
31
+ # alias_method :on_numblock, :on_block
32
+ # end
33
+ #
34
+ # class BlockRelatedCop < Base
35
+ # def on_block(node)
36
+ # end
37
+ #
38
+ # def on_numblock(node)
39
+ # end
40
+ # end
41
+ class NumblockHandler < Base
42
+ MSG = 'Define on_numblock to handle blocks with numbered arguments.'
43
+
44
+ def on_def(node)
45
+ return unless block_handler?(node)
46
+ return unless node.parent
47
+
48
+ add_offense(node) unless numblock_handler?(node.parent)
49
+ end
50
+
51
+ private
52
+
53
+ # @!method block_handler?(node)
54
+ def_node_matcher :block_handler?, <<~PATTERN
55
+ (def :on_block (args (arg :node)) ...)
56
+ PATTERN
57
+
58
+ # @!method numblock_handler?(node)
59
+ def_node_matcher :numblock_handler?, <<~PATTERN
60
+ {
61
+ `(def :on_numblock (args (arg :node)) ...)
62
+ `(alias (sym :on_numblock) (sym :on_block))
63
+ `(send nil? :alias_method (sym :on_numblock) (sym :on_block))
64
+ }
65
+ PATTERN
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Enforces the use of `node.single_line?` instead of
7
+ # comparing `first_line` and `last_line` for equality.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # node.loc.first_line == node.loc.last_line
12
+ #
13
+ # # bad
14
+ # node.loc.last_line == node.loc.first_line
15
+ #
16
+ # # bad
17
+ # node.loc.line == node.loc.last_line
18
+ #
19
+ # # bad
20
+ # node.loc.last_line == node.loc.line
21
+ #
22
+ # # bad
23
+ # node.first_line == node.last_line
24
+ #
25
+ # # good
26
+ # node.single_line?
27
+ #
28
+ class SingleLineComparison < Base
29
+ extend AutoCorrector
30
+
31
+ MSG = 'Use `%<preferred>s`.'
32
+ RESTRICT_ON_SEND = %i[== !=].freeze
33
+
34
+ # @!method single_line_comparison(node)
35
+ def_node_matcher :single_line_comparison, <<~PATTERN
36
+ {
37
+ (send (send $_receiver {:line :first_line}) {:== :!=} (send _receiver :last_line))
38
+ (send (send $_receiver :last_line) {:== :!=} (send _receiver {:line :first_line}))
39
+ }
40
+ PATTERN
41
+
42
+ def on_send(node)
43
+ return unless (receiver = single_line_comparison(node))
44
+
45
+ bang = node.method?(:!=) ? '!' : ''
46
+ preferred = "#{bang}#{extract_receiver(receiver)}.single_line?"
47
+
48
+ add_offense(node, message: format(MSG, preferred: preferred)) do |corrector|
49
+ corrector.replace(node, preferred)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def extract_receiver(node)
56
+ node = node.receiver if node.send_type? && %i[loc source_range].include?(node.method_name)
57
+ node.source
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -10,6 +10,7 @@ require_relative 'internal_affairs/method_name_equal'
10
10
  require_relative 'internal_affairs/node_destructuring'
11
11
  require_relative 'internal_affairs/node_matcher_directive'
12
12
  require_relative 'internal_affairs/node_type_predicate'
13
+ require_relative 'internal_affairs/numblock_handler'
13
14
  require_relative 'internal_affairs/offense_location_keyword'
14
15
  require_relative 'internal_affairs/redundant_context_config_parameter'
15
16
  require_relative 'internal_affairs/redundant_described_class_as_subject'
@@ -17,6 +18,7 @@ require_relative 'internal_affairs/redundant_let_rubocop_config_new'
17
18
  require_relative 'internal_affairs/redundant_location_argument'
18
19
  require_relative 'internal_affairs/redundant_message_argument'
19
20
  require_relative 'internal_affairs/redundant_method_dispatch_node'
21
+ require_relative 'internal_affairs/single_line_comparison'
20
22
  require_relative 'internal_affairs/style_detected_api_use'
21
23
  require_relative 'internal_affairs/undefined_config'
22
24
  require_relative 'internal_affairs/useless_message_assertion'
@@ -82,6 +82,8 @@ module RuboCop
82
82
  check_block_alignment(start_for_block_node(node), node)
83
83
  end
84
84
 
85
+ alias on_numblock on_block
86
+
85
87
  def style_parameter_name
86
88
  'EnforcedStyleAlignWith'
87
89
  end
@@ -36,24 +36,54 @@ module RuboCop
36
36
  # If the end is on its own line, there is no offense
37
37
  return if begins_its_line?(node.loc.end)
38
38
 
39
- add_offense(node.loc.end, message: message(node)) do |corrector|
40
- corrector.replace(delimiter_range(node), "\n#{node.loc.end.source}#{offset(node)}")
41
- end
39
+ register_offense(node)
42
40
  end
43
41
 
42
+ alias on_numblock on_block
43
+
44
44
  private
45
45
 
46
+ def register_offense(node)
47
+ add_offense(node.loc.end, message: message(node)) do |corrector|
48
+ offense_range = offense_range(node)
49
+ replacement = "\n#{offense_range.source.strip}"
50
+
51
+ if (heredoc = last_heredoc_argument(node.body))
52
+ corrector.remove(offense_range)
53
+ corrector.insert_after(heredoc.loc.heredoc_end, replacement)
54
+ else
55
+ corrector.replace(offense_range, replacement)
56
+ end
57
+ end
58
+ end
59
+
46
60
  def message(node)
47
61
  format(MSG, line: node.loc.end.line, column: node.loc.end.column + 1)
48
62
  end
49
63
 
50
- def delimiter_range(node)
64
+ def last_heredoc_argument(node)
65
+ return unless node&.call_type?
66
+ return unless (arguments = node&.arguments)
67
+
68
+ heredoc = arguments.reverse.detect { |arg| arg.str_type? && arg.heredoc? }
69
+ return heredoc if heredoc
70
+
71
+ last_heredoc_argument(node.children.first)
72
+ end
73
+
74
+ def offense_range(node)
51
75
  Parser::Source::Range.new(
52
76
  node.loc.expression.source_buffer,
53
77
  node.children.compact.last.loc.expression.end_pos,
54
- node.loc.expression.end_pos
78
+ end_of_method_chain(node).loc.expression.end_pos
55
79
  )
56
80
  end
81
+
82
+ def end_of_method_chain(node)
83
+ return node unless node.parent&.call_type?
84
+
85
+ end_of_method_chain(node.parent)
86
+ end
57
87
  end
58
88
  end
59
89
  end
@@ -80,8 +80,11 @@ module RuboCop
80
80
  @block_line = node.source_range.first_line
81
81
  end
82
82
 
83
- def on_send(node)
84
- return unless node.bare_access_modifier? && !node.parent&.block_type?
83
+ alias on_numblock on_block
84
+
85
+ def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity
86
+ return unless node.bare_access_modifier? &&
87
+ !(node.parent&.block_type? || node.parent&.numblock_type?)
85
88
  return if expected_empty_lines?(node)
86
89
 
87
90
  message = message(node)
@@ -32,6 +32,8 @@ module RuboCop
32
32
 
33
33
  check(node, node.body, adjusted_first_line: first_line)
34
34
  end
35
+
36
+ alias on_numblock on_block
35
37
  end
36
38
  end
37
39
  end
@@ -22,20 +22,20 @@ module RuboCop
22
22
  # # all platforms.
23
23
  #
24
24
  # # bad
25
- # puts 'Hello' # Return character is CR+LF on all platfoms.
25
+ # puts 'Hello' # Return character is CR+LF on all platforms.
26
26
  #
27
27
  # # good
28
- # puts 'Hello' # Return character is LF on all platfoms.
28
+ # puts 'Hello' # Return character is LF on all platforms.
29
29
  #
30
30
  # @example EnforcedStyle: crlf
31
31
  # # The `crlf` style means that CR+LF (Carriage Return + Line Feed) is
32
32
  # # enforced on all platforms.
33
33
  #
34
34
  # # bad
35
- # puts 'Hello' # Return character is LF on all platfoms.
35
+ # puts 'Hello' # Return character is LF on all platforms.
36
36
  #
37
37
  # # good
38
- # puts 'Hello' # Return character is CR+LF on all platfoms.
38
+ # puts 'Hello' # Return character is CR+LF on all platforms.
39
39
  #
40
40
  class EndOfLine < Base
41
41
  include ConfigurableEnforcedStyle
@@ -153,7 +153,8 @@ module RuboCop
153
153
  MSG = 'Indent the first argument one step more than %<base>s.'
154
154
 
155
155
  def on_send(node)
156
- return if style != :consistent && enforce_first_argument_with_fixed_indentation?
156
+ return if style != :consistent && enforce_first_argument_with_fixed_indentation? &&
157
+ !enable_layout_first_method_argument_line_break?
157
158
  return if !node.arguments? || bare_operator?(node) || node.setter_method?
158
159
 
159
160
  indent = base_indentation(node) + configured_indentation_width
@@ -267,6 +268,10 @@ module RuboCop
267
268
  argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
268
269
  end
269
270
 
271
+ def enable_layout_first_method_argument_line_break?
272
+ config.for_cop('Layout/FirstMethodArgumentLineBreak')['Enabled']
273
+ end
274
+
270
275
  def argument_alignment_config
271
276
  config.for_cop('Layout/ArgumentAlignment')
272
277
  end
@@ -143,7 +143,7 @@ module RuboCop
143
143
  case indent_base_type
144
144
  when :left_brace_or_bracket
145
145
  'the position of the opening bracket'
146
- when :first_colmn_after_left_parenthesis
146
+ when :first_column_after_left_parenthesis
147
147
  'the first position after the preceding left parenthesis'
148
148
  when :parent_hash_key
149
149
  'the parent hash key'
@@ -164,7 +164,7 @@ module RuboCop
164
164
  case indent_base_type
165
165
  when :left_brace_or_bracket
166
166
  'Indent the right bracket the same as the left bracket.'
167
- when :first_colmn_after_left_parenthesis
167
+ when :first_column_after_left_parenthesis
168
168
  'Indent the right bracket the same as the first position ' \
169
169
  'after the preceding left parenthesis.'
170
170
  when :parent_hash_key
@@ -192,7 +192,7 @@ module RuboCop
192
192
  case indent_base_type
193
193
  when :left_brace_or_bracket
194
194
  'the position of the opening brace'
195
- when :first_colmn_after_left_parenthesis
195
+ when :first_column_after_left_parenthesis
196
196
  'the first position after the preceding left parenthesis'
197
197
  when :parent_hash_key
198
198
  'the parent hash key'
@@ -213,7 +213,7 @@ module RuboCop
213
213
  case indent_base_type
214
214
  when :left_brace_or_bracket
215
215
  'Indent the right brace the same as the left brace.'
216
- when :first_colmn_after_left_parenthesis
216
+ when :first_column_after_left_parenthesis
217
217
  'Indent the right brace the same as the first position ' \
218
218
  'after the preceding left parenthesis.'
219
219
  when :parent_hash_key
@@ -90,6 +90,8 @@ module RuboCop
90
90
  check_members(end_loc, [node.body])
91
91
  end
92
92
 
93
+ alias on_numblock on_block
94
+
93
95
  def on_class(node)
94
96
  base = node.loc.keyword
95
97
  return if same_line?(base, node.body)
@@ -22,6 +22,7 @@ module RuboCop
22
22
  # (Many of these are enabled by default.)
23
23
  #
24
24
  # * ArgumentAlignment
25
+ # * ArrayAlignment
25
26
  # * BlockAlignment
26
27
  # * BlockDelimiters
27
28
  # * BlockEndNewline
@@ -74,6 +75,8 @@ module RuboCop
74
75
  check_for_breakable_block(node)
75
76
  end
76
77
 
78
+ alias on_numblock on_block
79
+
77
80
  def on_potential_breakable_node(node)
78
81
  check_for_breakable_node(node)
79
82
  end
@@ -131,7 +134,7 @@ module RuboCop
131
134
  if block_node.arguments? && !block_node.lambda?
132
135
  block_node.arguments.loc.end
133
136
  else
134
- block_node.loc.begin
137
+ block_node.braces? ? block_node.loc.begin : block_node.loc.begin.adjust(begin_pos: 1)
135
138
  end
136
139
  end
137
140
 
@@ -73,7 +73,7 @@ module RuboCop
73
73
  return if node.send_type? && node.loc.operator&.source != '='
74
74
  return unless rhs
75
75
  return unless supported_types.include?(rhs.type)
76
- return if rhs.first_line == rhs.last_line
76
+ return if rhs.single_line?
77
77
 
78
78
  check_by_enforced_style(node, rhs)
79
79
  end
@@ -68,6 +68,8 @@ module RuboCop
68
68
  add_offense_for_expression(node, node.body, MSG)
69
69
  end
70
70
 
71
+ alias on_numblock on_block
72
+
71
73
  private
72
74
 
73
75
  def args_on_beginning_line?(node)
@@ -101,7 +101,7 @@ module RuboCop
101
101
  !comment_within?(node) &&
102
102
  node.each_descendant(:if, :case, :kwbegin, :def).none? &&
103
103
  node.each_descendant(:dstr, :str).none?(&:heredoc?) &&
104
- node.each_descendant(:begin).none? { |b| b.first_line != b.last_line }
104
+ node.each_descendant(:begin).none? { |b| !b.single_line? }
105
105
  end
106
106
 
107
107
  def convertible_block?(node)
@@ -29,7 +29,7 @@ module RuboCop
29
29
  include RangeHelp
30
30
  extend AutoCorrector
31
31
 
32
- def on_block(node)
32
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
33
33
  arguments = node.arguments
34
34
 
35
35
  return unless node.arguments? && pipes?(arguments)
@@ -41,7 +41,7 @@ module RuboCop
41
41
  check(node, [:operator].freeze) if node.keyword?
42
42
  end
43
43
 
44
- def on_block(node)
44
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
45
45
  check(node, %i[begin end].freeze)
46
46
  end
47
47
 
@@ -76,6 +76,8 @@ module RuboCop
76
76
  end
77
77
  end
78
78
 
79
+ alias on_numblock on_block
80
+
79
81
  private
80
82
 
81
83
  def check_empty(left_brace, space_plus_brace, used_style)
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Legacy
6
6
  # Legacy support for Corrector#corrections
7
- # See https://docs.rubocop.org/rubocop/cop_api_v1_changelog.html
7
+ # See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html
8
8
  class CorrectionsProxy
9
9
  def initialize(corrector)
10
10
  @corrector = corrector
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Legacy
6
6
  # Legacy Corrector for v0 API support.
7
- # See https://docs.rubocop.org/rubocop/cop_api_v1_changelog.html
7
+ # See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html
8
8
  class Corrector < RuboCop::Cop::Corrector
9
9
  # Support legacy second argument
10
10
  def initialize(source, corr = [])
@@ -6,8 +6,8 @@ module RuboCop
6
6
  # Checks for ambiguous block association with method
7
7
  # when param passed without parentheses.
8
8
  #
9
- # This cop can customize ignored methods with `IgnoredMethods`.
10
- # By default, there are no methods to ignored.
9
+ # This cop can customize allowed methods with `AllowedMethods`.
10
+ # By default, there are no methods to allowed.
11
11
  #
12
12
  # @example
13
13
  #
@@ -30,18 +30,30 @@ module RuboCop
30
30
  # # Lambda arguments require no disambiguation
31
31
  # foo = ->(bar) { bar.baz }
32
32
  #
33
- # @example IgnoredMethods: [] (default)
33
+ # @example AllowedMethods: [] (default)
34
34
  #
35
35
  # # bad
36
36
  # expect { do_something }.to change { object.attribute }
37
37
  #
38
- # @example IgnoredMethods: [change]
38
+ # @example AllowedMethods: [change]
39
39
  #
40
40
  # # good
41
41
  # expect { do_something }.to change { object.attribute }
42
42
  #
43
+ # @example AllowedPatterns: [] (default)
44
+ #
45
+ # # bad
46
+ # expect { do_something }.to change { object.attribute }
47
+ #
48
+ # @example AllowedPatterns: [/change/]
49
+ #
50
+ # # good
51
+ # expect { do_something }.to change { object.attribute }
52
+ # expect { do_something }.to not_change { object.attribute }
53
+ #
43
54
  class AmbiguousBlockAssociation < Base
44
- include IgnoredMethods
55
+ include AllowedMethods
56
+ include AllowedPattern
45
57
 
46
58
  MSG = 'Parenthesize the param `%<param>s` to make sure that the ' \
47
59
  'block will be associated with the `%<method>s` method ' \
@@ -52,7 +64,7 @@ module RuboCop
52
64
 
53
65
  return unless ambiguous_block_association?(node)
54
66
  return if node.parenthesized? || node.last_argument.lambda? || node.last_argument.proc? ||
55
- allowed_method?(node)
67
+ allowed_method_pattern?(node)
56
68
 
57
69
  message = message(node)
58
70
 
@@ -66,9 +78,10 @@ module RuboCop
66
78
  send_node.last_argument.block_type? && !send_node.last_argument.send_node.arguments?
67
79
  end
68
80
 
69
- def allowed_method?(node)
81
+ def allowed_method_pattern?(node)
70
82
  node.assignment? || node.operator_method? || node.method?(:[]) ||
71
- ignored_method?(node.last_argument.send_node.source)
83
+ allowed_method?(node.last_argument.method_name) ||
84
+ matches_allowed_pattern?(node.last_argument.method_name)
72
85
  end
73
86
 
74
87
  def message(send_node)