rubocop 0.25.0 → 0.26.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +37 -0
  4. data/README.md +2 -2
  5. data/assets/output.html.erb +190 -0
  6. data/config/default.yml +14 -2
  7. data/config/disabled.yml +7 -0
  8. data/config/enabled.yml +132 -5
  9. data/lib/rubocop.rb +5 -0
  10. data/lib/rubocop/cop/commissioner.rb +4 -10
  11. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -1
  12. data/lib/rubocop/cop/lint/end_in_method.rb +3 -8
  13. data/lib/rubocop/cop/lint/ensure_return.rb +2 -2
  14. data/lib/rubocop/cop/lint/space_before_first_arg.rb +8 -1
  15. data/lib/rubocop/cop/lint/useless_assignment.rb +35 -0
  16. data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -3
  17. data/lib/rubocop/cop/metrics/block_nesting.rb +3 -3
  18. data/lib/rubocop/cop/metrics/class_length.rb +1 -2
  19. data/lib/rubocop/cop/mixin/access_modifier_node.rb +5 -1
  20. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +2 -2
  21. data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
  22. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -4
  23. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -3
  24. data/lib/rubocop/cop/rails/delegate.rb +1 -1
  25. data/lib/rubocop/cop/rails/validation.rb +25 -2
  26. data/lib/rubocop/cop/style/alias.rb +1 -1
  27. data/lib/rubocop/cop/style/and_or.rb +12 -2
  28. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +19 -12
  29. data/lib/rubocop/cop/style/documentation.rb +1 -1
  30. data/lib/rubocop/cop/style/dot_position.rb +20 -0
  31. data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +5 -1
  32. data/lib/rubocop/cop/style/encoding.rb +4 -4
  33. data/lib/rubocop/cop/style/format_string.rb +12 -2
  34. data/lib/rubocop/cop/style/if_unless_modifier.rb +8 -11
  35. data/lib/rubocop/cop/style/infinite_loop.rb +57 -0
  36. data/lib/rubocop/cop/style/multiline_block_chain.rb +15 -16
  37. data/lib/rubocop/cop/style/multiline_if_then.rb +10 -0
  38. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -3
  39. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +3 -1
  40. data/lib/rubocop/cop/style/predicate_name.rb +23 -5
  41. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  42. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  43. data/lib/rubocop/cop/style/space_around_equals_in_parameter_default.rb +4 -8
  44. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +9 -11
  45. data/lib/rubocop/cop/style/space_inside_range_literal.rb +58 -0
  46. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  47. data/lib/rubocop/cop/style/symbol_proc.rb +71 -0
  48. data/lib/rubocop/cop/style/tab.rb +11 -3
  49. data/lib/rubocop/cop/style/unneeded_capital_w.rb +6 -2
  50. data/lib/rubocop/cop/style/variable_name.rb +4 -14
  51. data/lib/rubocop/cop/style/while_until_modifier.rb +12 -8
  52. data/lib/rubocop/cop/variable_force.rb +17 -30
  53. data/lib/rubocop/cop/variable_force/assignment.rb +15 -23
  54. data/lib/rubocop/cop/variable_force/locatable.rb +29 -8
  55. data/lib/rubocop/cop/variable_force/scope.rb +34 -23
  56. data/lib/rubocop/cop/variable_force/variable.rb +7 -10
  57. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  58. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  59. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  60. data/lib/rubocop/formatter/html_formatter.rb +90 -0
  61. data/lib/rubocop/formatter/progress_formatter.rb +1 -1
  62. data/lib/rubocop/options.rb +1 -0
  63. data/lib/rubocop/processed_source.rb +10 -1
  64. data/lib/rubocop/string_util.rb +153 -0
  65. data/lib/rubocop/target_finder.rb +1 -1
  66. data/lib/rubocop/version.rb +1 -1
  67. data/relnotes/v0.26.0.md +89 -0
  68. data/rubocop.gemspec +1 -0
  69. data/spec/rubocop/cli_spec.rb +60 -34
  70. data/spec/rubocop/config_loader_spec.rb +19 -15
  71. data/spec/rubocop/cop/commissioner_spec.rb +2 -2
  72. data/spec/rubocop/cop/lint/block_alignment_spec.rb +74 -58
  73. data/spec/rubocop/cop/lint/space_before_first_arg_spec.rb +7 -0
  74. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +173 -0
  75. data/spec/rubocop/cop/rails/validation_spec.rb +9 -2
  76. data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +26 -0
  77. data/spec/rubocop/cop/style/and_or_spec.rb +52 -61
  78. data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +26 -8
  79. data/spec/rubocop/cop/style/case_indentation_spec.rb +8 -8
  80. data/spec/rubocop/cop/style/def_with_parentheses_spec.rb +6 -2
  81. data/spec/rubocop/cop/style/dot_position_spec.rb +39 -0
  82. data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +12 -2
  83. data/spec/rubocop/cop/style/encoding_spec.rb +16 -28
  84. data/spec/rubocop/cop/style/format_string_spec.rb +12 -0
  85. data/spec/rubocop/cop/style/infinite_loop_spec.rb +48 -0
  86. data/spec/rubocop/cop/style/method_def_parentheses_spec.rb +3 -1
  87. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +9 -0
  88. data/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb +21 -1
  89. data/spec/rubocop/cop/style/predicate_name_spec.rb +44 -13
  90. data/spec/rubocop/cop/style/redundant_begin_spec.rb +32 -0
  91. data/spec/rubocop/cop/style/space_inside_range_literal_spec.rb +52 -0
  92. data/spec/rubocop/cop/style/symbol_proc_spec.rb +76 -0
  93. data/spec/rubocop/cop/style/tab_spec.rb +30 -0
  94. data/spec/rubocop/cop/style/trailing_whitespace_spec.rb +2 -1
  95. data/spec/rubocop/cop/style/unneeded_capital_w_spec.rb +18 -5
  96. data/spec/rubocop/cop/style/variable_name_spec.rb +5 -5
  97. data/spec/rubocop/cop/style/when_then_spec.rb +3 -1
  98. data/spec/rubocop/cop/style/while_until_do_spec.rb +4 -2
  99. data/spec/rubocop/cop/util_spec.rb +1 -9
  100. data/spec/rubocop/cop/variable_force/assignment_spec.rb +2 -15
  101. data/spec/rubocop/cop/variable_force/locatable_spec.rb +2 -37
  102. data/spec/rubocop/cop/variable_force/scope_spec.rb +156 -49
  103. data/spec/rubocop/cop/variable_force/variable_spec.rb +2 -1
  104. data/spec/rubocop/cop/variable_force_spec.rb +2 -1
  105. data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +2 -1
  106. data/spec/rubocop/formatter/html_formatter_spec.rb +145 -0
  107. data/spec/rubocop/formatter/simple_text_formatter_spec.rb +18 -6
  108. data/spec/rubocop/options_spec.rb +1 -0
  109. data/spec/rubocop/path_util_spec.rb +6 -4
  110. data/spec/rubocop/processed_source_spec.rb +17 -1
  111. data/spec/rubocop/string_util_spec.rb +46 -0
  112. metadata +33 -4
  113. data/spec/support/ast_helper.rb +0 -15
@@ -46,7 +46,7 @@ module RuboCop
46
46
  end
47
47
 
48
48
  def next_line_empty?(next_line)
49
- next_line.blank?
49
+ body_end?(next_line.lstrip) || next_line.blank?
50
50
  end
51
51
 
52
52
  def empty_lines_around?(node)
@@ -61,6 +61,10 @@ module RuboCop
61
61
  %w(class module).any? { |keyword| line.start_with?(keyword) }
62
62
  end
63
63
 
64
+ def body_end?(line)
65
+ line.start_with?('end')
66
+ end
67
+
64
68
  def message(node)
65
69
  format(MSG, node.loc.selector.source)
66
70
  end
@@ -3,9 +3,10 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks whether the source file has a utf-8 encoding comment or
7
- # not. This check makes sense only in Ruby 1.9, since in 2.0+ utf-8 is
8
- # the default source file encoding. There are two style:
6
+ # This cop checks whether the source file has a utf-8 encoding
7
+ # comment or not. This check makes sense only for code that
8
+ # should support Ruby 1.9, since in 2.0+ utf-8 is the default
9
+ # source file encoding. There are two style:
9
10
  #
10
11
  # when_needed - only enforce an encoding comment if there are non ASCII
11
12
  # characters, otherwise report an offense
@@ -17,7 +18,6 @@ module RuboCop
17
18
  MSG_UNNECESSARY = 'Unnecessary utf-8 encoding comment.'
18
19
 
19
20
  def investigate(processed_source)
20
- return if RUBY_VERSION >= '2.0.0'
21
21
  return if processed_source.buffer.source.empty?
22
22
 
23
23
  line_number = encoding_line_number(processed_source)
@@ -30,12 +30,22 @@ module RuboCop
30
30
  end
31
31
  end
32
32
 
33
+ def format_method?(name, node)
34
+ receiver, method_name, args = *node
35
+
36
+ # we do an argument count check to reduce false positives
37
+ return false if args && args.children.size < 2
38
+
39
+ # commands have no explicit receiver
40
+ !receiver && method_name == name
41
+ end
42
+
33
43
  def format?(node)
34
- command?(:format, node)
44
+ format_method?(:format, node)
35
45
  end
36
46
 
37
47
  def sprintf?(node)
38
- command?(:sprintf, node)
48
+ format_method?(:sprintf, node)
39
49
  end
40
50
 
41
51
  def percent?(node)
@@ -14,17 +14,14 @@ module RuboCop
14
14
  ' Another good alternative is the usage of control flow `&&`/`||`.'
15
15
  end
16
16
 
17
- def investigate(processed_source)
18
- return unless processed_source.ast
19
- on_node(:if, processed_source.ast) do |node|
20
- # discard ternary ops, if/else and modifier if/unless nodes
21
- next if ternary_op?(node)
22
- next if modifier_if?(node)
23
- next if elsif?(node)
24
- next if if_else?(node)
25
- next unless fit_within_line_as_modifier_form?(node)
26
- add_offense(node, :keyword, message(node.loc.keyword.source))
27
- end
17
+ def on_if(node)
18
+ # discard ternary ops, if/else and modifier if/unless nodes
19
+ return if ternary_op?(node)
20
+ return if modifier_if?(node)
21
+ return if elsif?(node)
22
+ return if if_else?(node)
23
+ return unless fit_within_line_as_modifier_form?(node)
24
+ add_offense(node, :keyword, message(node.loc.keyword.source))
28
25
  end
29
26
  end
30
27
  end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Use `Kernel#loop` for infinite loops.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # while true
11
+ # work
12
+ # end
13
+ #
14
+ # # good
15
+ # loop do
16
+ # work
17
+ # end
18
+ class InfiniteLoop < Cop
19
+ MSG = 'Use `Kernel#loop` for infinite loops.'
20
+
21
+ TRUTHY_LITERALS = [:str, :dstr, :int, :float, :array,
22
+ :hash, :regexp, :true]
23
+
24
+ FALSEY_LITERALS = [:nil, :false]
25
+
26
+ def on_while(node)
27
+ condition, = *node
28
+
29
+ return unless TRUTHY_LITERALS.include?(condition.type)
30
+
31
+ add_offense(node, :keyword)
32
+ end
33
+
34
+ def on_until(node)
35
+ condition, = *node
36
+
37
+ return unless FALSEY_LITERALS.include?(condition.type)
38
+
39
+ add_offense(node, :keyword)
40
+ end
41
+
42
+ def autocorrect(node)
43
+ @corrections << lambda do |corrector|
44
+ condition_node, = *node
45
+ start_range = node.loc.keyword.begin
46
+ end_range = if node.loc.begin
47
+ node.loc.begin.end
48
+ else
49
+ condition_node.loc.expression.end
50
+ end
51
+ corrector.replace(start_range.join(end_range), 'loop do')
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -18,24 +18,23 @@ module RuboCop
18
18
 
19
19
  def on_block(node)
20
20
  method, _args, _body = *node
21
- on_node(:send, method) do |send_node|
21
+ method.each_node(:send) do |send_node|
22
22
  receiver, _method_name, *_args = *send_node
23
- if receiver && receiver.type == :block
24
- # The begin and end could also be braces, but we call the
25
- # variables do... and end...
26
- do_kw_loc, end_kw_loc = receiver.loc.begin, receiver.loc.end
23
+ next unless receiver && receiver.type == :block
27
24
 
28
- if do_kw_loc.line != end_kw_loc.line
29
- range =
30
- Parser::Source::Range.new(end_kw_loc.source_buffer,
31
- end_kw_loc.begin_pos,
32
- method.loc.expression.end_pos)
33
- add_offense(nil, range)
34
- # Done. If there are more blocks in the chain, they will be
35
- # found by subsequent calls to on_block.
36
- break
37
- end
38
- end
25
+ # The begin and end could also be braces, but we call the
26
+ # variables do... and end...
27
+ do_kw_loc, end_kw_loc = receiver.loc.begin, receiver.loc.end
28
+ next if do_kw_loc.line == end_kw_loc.line
29
+
30
+ range =
31
+ Parser::Source::Range.new(end_kw_loc.source_buffer,
32
+ end_kw_loc.begin_pos,
33
+ method.loc.expression.end_pos)
34
+ add_offense(nil, range)
35
+ # Done. If there are more blocks in the chain, they will be
36
+ # found by subsequent calls to on_block.
37
+ break
39
38
  end
40
39
  end
41
40
  end
@@ -44,6 +44,16 @@ module RuboCop
44
44
  def message(node)
45
45
  "Never use `then` for multi-line `#{node.loc.keyword.source}`."
46
46
  end
47
+
48
+ def autocorrect(node)
49
+ @corrections << lambda do |corrector|
50
+ condition_node, = *node
51
+ end_of_condition_range = condition_node.loc.expression.end
52
+ then_range = node.loc.begin
53
+ whitespaces_and_then_range = end_of_condition_range.join(then_range)
54
+ corrector.remove(whitespaces_and_then_range)
55
+ end
56
+ end
47
57
  end
48
58
  end
49
59
  end
@@ -14,9 +14,9 @@ module RuboCop
14
14
  # discard non-ternary ops
15
15
  return unless loc.respond_to?(:question)
16
16
 
17
- node.children.each do |child|
18
- on_node(:if, child) do |c|
19
- add_offense(c, :expression) if c.loc.respond_to?(:question)
17
+ node.each_descendant(:if) do |nested_if_node|
18
+ if nested_if_node.loc.respond_to?(:question)
19
+ add_offense(nested_if_node, :expression)
20
20
  end
21
21
  end
22
22
  end
@@ -80,7 +80,9 @@ module RuboCop
80
80
  when String
81
81
  ''
82
82
  when Parser::AST::Node
83
- /(\s*)/.match(object.loc.send(part).source_line)[1]
83
+ part_range = object.loc.send(part)
84
+ left_of_part = part_range.source_line[0...part_range.column]
85
+ /^(\s*)$/.match(left_of_part) ? left_of_part : ''
84
86
  else
85
87
  fail "Unsupported object #{object}"
86
88
  end
@@ -23,21 +23,39 @@ module RuboCop
23
23
  private
24
24
 
25
25
  def on_method(node, method_name, _args, _body)
26
- prefix_blacklist.each do |prefix|
27
- next unless method_name.to_s.start_with?(prefix)
28
- add_offense(node, :name, message(method_name.to_s, prefix))
26
+ predicate_prefices.each do |prefix|
27
+ method_name = method_name.to_s
28
+ next unless method_name.start_with?(prefix)
29
+ next if method_name == expected_name(method_name, prefix)
30
+ add_offense(
31
+ node,
32
+ :name,
33
+ message(method_name, expected_name(method_name, prefix))
34
+ )
29
35
  end
30
36
  end
31
37
 
32
- def message(method_name, prefix)
33
- new_name = method_name.sub(prefix, '')
38
+ def expected_name(method_name, prefix)
39
+ new_name = if prefix_blacklist.include?(prefix)
40
+ method_name.sub(prefix, '')
41
+ else
42
+ method_name.dup
43
+ end
34
44
  new_name << '?' unless method_name.end_with?('?')
45
+ new_name
46
+ end
47
+
48
+ def message(method_name, new_name)
35
49
  "Rename `#{method_name}` to `#{new_name}`."
36
50
  end
37
51
 
38
52
  def prefix_blacklist
39
53
  cop_config['NamePrefixBlacklist']
40
54
  end
55
+
56
+ def predicate_prefices
57
+ cop_config['NamePrefix']
58
+ end
41
59
  end
42
60
  end
43
61
  end
@@ -41,7 +41,7 @@ module RuboCop
41
41
  range_with_surrounding_space(node.loc.expression),
42
42
  range_with_surrounding_space(
43
43
  child.loc.expression
44
- ).source.gsub(/^\s{#{indent_diff}}/, '')
44
+ ).source.gsub(/^[ \t]{#{indent_diff}}/, '')
45
45
  )
46
46
  end
47
47
  end
@@ -51,7 +51,7 @@ module RuboCop
51
51
  end
52
52
 
53
53
  def args_match?(method_name, args)
54
- actual_args = args.flat_map { |a| a.to_a }
54
+ actual_args = args.flat_map(&:to_a)
55
55
 
56
56
  actual_args == target_args(method_name).map(&:to_sym)
57
57
  end
@@ -9,14 +9,10 @@ module RuboCop
9
9
  include SurroundingSpace
10
10
  include ConfigurableEnforcedStyle
11
11
 
12
- def investigate(processed_source)
13
- return unless processed_source.ast
14
- @processed_source = processed_source
15
- on_node(:optarg, processed_source.ast) do |optarg|
16
- index = index_of_first_token(optarg)
17
- arg, equals, value = processed_source.tokens[index, 3]
18
- check_optarg(arg, equals, value)
19
- end
12
+ def on_optarg(node)
13
+ index = index_of_first_token(node)
14
+ arg, equals, value = processed_source.tokens[index, 3]
15
+ check_optarg(arg, equals, value)
20
16
  end
21
17
 
22
18
  private
@@ -11,18 +11,16 @@ module RuboCop
11
11
 
12
12
  MSG = 'Space inside %s.'
13
13
 
14
- def investigate(processed_source)
15
- return unless processed_source.ast
14
+ def on_hash(node)
15
+ b_ix = index_of_first_token(node)
16
16
  tokens = processed_source.tokens
17
17
 
18
- on_node(:hash, processed_source.ast) do |hash|
19
- b_ix = index_of_first_token(hash)
20
- if tokens[b_ix].type == :tLBRACE # Hash literal with braces?
21
- e_ix = index_of_last_token(hash)
22
- check(tokens[b_ix], tokens[b_ix + 1])
23
- check(tokens[e_ix - 1], tokens[e_ix]) unless b_ix == e_ix - 1
24
- end
25
- end
18
+ # Hash literal with braces?
19
+ return unless tokens[b_ix].type == :tLBRACE
20
+
21
+ e_ix = index_of_last_token(node)
22
+ check(tokens[b_ix], tokens[b_ix + 1])
23
+ check(tokens[e_ix - 1], tokens[e_ix]) unless b_ix == e_ix - 1
26
24
  end
27
25
 
28
26
  private
@@ -69,7 +67,7 @@ module RuboCop
69
67
  @corrections << lambda do |corrector|
70
68
  # It is possible that BracesAroundHashParameters will remove the
71
69
  # braces while this cop inserts spaces. This can lead to unwanted
72
- # changes to the inspected code. If we replace the brace with a
70
+ # changes to the inspected code. If we replace the brace with a
73
71
  # brace plus space (rather than just inserting a space), then any
74
72
  # removal of the same brace will give us a clobbering error. This
75
73
  # in turn will make RuboCop fall back on cop-by-cop
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for spaces inside range literals.
7
+ # @example
8
+ # # bad
9
+ # 1 .. 3
10
+ #
11
+ # # good
12
+ # 1..3
13
+ #
14
+ # # bad
15
+ # 'a' .. 'z'
16
+ #
17
+ # # good
18
+ # 'a'..'z'
19
+ class SpaceInsideRangeLiteral < Cop
20
+ MSG = 'Space inside range literal.'
21
+
22
+ def on_irange(node)
23
+ check(node)
24
+ end
25
+
26
+ def on_erange(node)
27
+ check(node)
28
+ end
29
+
30
+ private
31
+
32
+ def check(node)
33
+ expression = node.loc.expression.source
34
+ operator = node.loc.operator.source.gsub(/\./, '\.')
35
+
36
+ return unless expression =~ /(\s#{operator})|(#{operator}\s)/
37
+
38
+ add_offense(node, :expression)
39
+ end
40
+
41
+ def autocorrect(node)
42
+ expression = node.loc.expression.source
43
+ operator = node.loc.operator.source
44
+ operator_escaped = operator.gsub(/\./, '\.')
45
+
46
+ @corrections << lambda do |corrector|
47
+ corrector.replace(
48
+ node.loc.expression,
49
+ expression
50
+ .sub(/\s+#{operator_escaped}/, operator)
51
+ .sub(/#{operator_escaped}\s+/, operator)
52
+ )
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -55,7 +55,7 @@ module RuboCop
55
55
  NON_ENGLISH_VARS.include? var
56
56
  end
57
57
 
58
- # For now, we assume that lists are 2 items or less. Easy grammar!
58
+ # For now, we assume that lists are 2 items or less. Easy grammar!
59
59
  regular_msg = regular.join('` or `')
60
60
  english_msg = english.join('` or `')
61
61
 
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Use symbols as procs when possible.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # something.map { |s| s.upcase }
11
+ #
12
+ # # good
13
+ # something.map(&:upcase)
14
+ class SymbolProc < Cop
15
+ MSG = 'Pass `&:%s` as an argument to `%s` instead of a block.'
16
+
17
+ def on_block(node)
18
+ block_send, block_args, block_body = *node
19
+
20
+ _breceiver, bmethod_name, bargs = *block_send
21
+
22
+ # we should ignore lambdas
23
+ return if bmethod_name == :lambda
24
+ return if ignored_method?(bmethod_name)
25
+ # File.open(file) { |f| f.readlines }
26
+ return if bargs
27
+ # something { |x, y| ... }
28
+ return unless block_args.children.size == 1
29
+ return unless block_body && block_body.type == :send
30
+
31
+ receiver, method_name, args = *block_body
32
+
33
+ # method in block must be invoked on a lvar without args
34
+ return if args
35
+ return if receiver.type != :lvar
36
+
37
+ block_arg_name, = *block_args.children.first
38
+ receiver_name, = *receiver
39
+
40
+ return if block_arg_name != receiver_name
41
+
42
+ add_offense(node,
43
+ :expression,
44
+ format(MSG,
45
+ method_name,
46
+ bmethod_name))
47
+ end
48
+
49
+ def autocorrect(node)
50
+ @corrections << lambda do |corrector|
51
+ block_method, _block_args, block_body = *node
52
+ _receiver, method_name, _args = *block_body
53
+
54
+ replacement = "#{block_method.loc.expression.source}" \
55
+ "(&:#{method_name})"
56
+
57
+ corrector.replace(node.loc.expression, replacement)
58
+ end
59
+ end
60
+
61
+ def ignored_methods
62
+ cop_config['IgnoredMethods']
63
+ end
64
+
65
+ def ignored_method?(name)
66
+ ignored_methods.include?(name.to_s)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end