rubocop 0.52.0 → 0.52.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 (166) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -5
  3. data/config/default.yml +1 -11
  4. data/config/disabled.yml +5 -0
  5. data/config/enabled.yml +6 -8
  6. data/lib/rubocop.rb +13 -2
  7. data/lib/rubocop/ast/node.rb +23 -15
  8. data/lib/rubocop/cli.rb +25 -2
  9. data/lib/rubocop/config.rb +23 -8
  10. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  11. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -0
  12. data/lib/rubocop/cop/commissioner.rb +1 -1
  13. data/lib/rubocop/cop/correctors/alignment_corrector.rb +121 -0
  14. data/lib/rubocop/cop/correctors/condition_corrector.rb +28 -0
  15. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +26 -0
  16. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +62 -0
  17. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +44 -0
  18. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +31 -0
  19. data/lib/rubocop/cop/correctors/punctuation_corrector.rb +29 -0
  20. data/lib/rubocop/cop/correctors/space_corrector.rb +34 -0
  21. data/lib/rubocop/cop/correctors/string_literal_corrector.rb +25 -0
  22. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +31 -0
  23. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  24. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -0
  25. data/lib/rubocop/cop/generator.rb +18 -87
  26. data/lib/rubocop/cop/generator/require_file_injector.rb +78 -0
  27. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
  28. data/lib/rubocop/cop/layout/align_array.rb +5 -1
  29. data/lib/rubocop/cop/layout/align_hash.rb +1 -1
  30. data/lib/rubocop/cop/layout/align_parameters.rb +5 -1
  31. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  32. data/lib/rubocop/cop/layout/class_structure.rb +2 -2
  33. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -1
  34. data/lib/rubocop/cop/layout/comment_indentation.rb +5 -1
  35. data/lib/rubocop/cop/layout/else_alignment.rb +5 -1
  36. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +3 -3
  37. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +17 -19
  38. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +4 -0
  39. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +4 -0
  40. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +4 -0
  41. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -0
  42. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +4 -0
  43. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +4 -0
  44. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +4 -0
  45. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +4 -0
  46. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +4 -0
  47. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
  48. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +6 -2
  49. data/lib/rubocop/cop/layout/indent_array.rb +6 -2
  50. data/lib/rubocop/cop/layout/indent_assignment.rb +6 -2
  51. data/lib/rubocop/cop/layout/indent_hash.rb +5 -1
  52. data/lib/rubocop/cop/layout/indentation_consistency.rb +5 -1
  53. data/lib/rubocop/cop/layout/indentation_width.rb +5 -1
  54. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +4 -0
  55. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +3 -3
  56. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -2
  57. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +4 -0
  58. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +4 -0
  59. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +6 -2
  60. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
  61. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -2
  62. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -1
  63. data/lib/rubocop/cop/layout/space_after_comma.rb +4 -0
  64. data/lib/rubocop/cop/layout/space_after_semicolon.rb +4 -0
  65. data/lib/rubocop/cop/layout/space_before_comma.rb +4 -0
  66. data/lib/rubocop/cop/layout/space_before_semicolon.rb +4 -0
  67. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +3 -2
  68. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +16 -7
  69. data/lib/rubocop/cop/layout/tab.rb +1 -1
  70. data/lib/rubocop/cop/lint/block_alignment.rb +1 -1
  71. data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -2
  72. data/lib/rubocop/cop/lint/end_alignment.rb +3 -1
  73. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  74. data/lib/rubocop/cop/lint/unused_block_argument.rb +4 -0
  75. data/lib/rubocop/cop/lint/unused_method_argument.rb +6 -0
  76. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -1
  77. data/lib/rubocop/cop/mixin/alignment.rb +70 -0
  78. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +2 -0
  79. data/lib/rubocop/cop/mixin/array_syntax.rb +2 -0
  80. data/lib/rubocop/cop/mixin/code_length.rb +2 -0
  81. data/lib/rubocop/cop/mixin/configurable_max.rb +2 -0
  82. data/lib/rubocop/cop/mixin/def_node.rb +3 -1
  83. data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
  84. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +3 -15
  85. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -25
  86. data/lib/rubocop/cop/mixin/enforce_superclass.rb +0 -6
  87. data/lib/rubocop/cop/mixin/first_element_line_break.rb +5 -9
  88. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +2 -2
  89. data/lib/rubocop/cop/mixin/ignored_pattern.rb +2 -0
  90. data/lib/rubocop/cop/mixin/integer_node.rb +2 -0
  91. data/lib/rubocop/cop/mixin/match_range.rb +2 -0
  92. data/lib/rubocop/cop/mixin/min_body_length.rb +2 -0
  93. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
  94. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +9 -48
  95. data/lib/rubocop/cop/mixin/negative_conditional.rb +2 -16
  96. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +12 -31
  97. data/lib/rubocop/cop/mixin/parentheses.rb +2 -19
  98. data/lib/rubocop/cop/mixin/percent_literal.rb +3 -3
  99. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +2 -0
  100. data/lib/rubocop/cop/mixin/rescue_node.rb +2 -0
  101. data/lib/rubocop/cop/mixin/safe_assignment.rb +2 -0
  102. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -3
  103. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -3
  104. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -2
  105. data/lib/rubocop/cop/mixin/string_help.rb +2 -0
  106. data/lib/rubocop/cop/mixin/string_literals_help.rb +2 -13
  107. data/lib/rubocop/cop/mixin/surrounding_space.rb +4 -21
  108. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -10
  109. data/lib/rubocop/cop/mixin/unused_argument.rb +2 -15
  110. data/lib/rubocop/cop/performance/case_when_splat.rb +1 -1
  111. data/lib/rubocop/cop/rails/action_filter.rb +3 -2
  112. data/lib/rubocop/cop/rails/active_support_aliases.rb +3 -2
  113. data/lib/rubocop/cop/rails/application_job.rb +6 -0
  114. data/lib/rubocop/cop/rails/application_record.rb +6 -0
  115. data/lib/rubocop/cop/rails/blank.rb +10 -9
  116. data/lib/rubocop/cop/rails/date.rb +22 -14
  117. data/lib/rubocop/cop/rails/delegate.rb +1 -1
  118. data/lib/rubocop/cop/rails/dynamic_find_by.rb +3 -2
  119. data/lib/rubocop/cop/rails/enum_uniqueness.rb +4 -2
  120. data/lib/rubocop/cop/rails/environment_comparison.rb +2 -2
  121. data/lib/rubocop/cop/rails/file_path.rb +1 -1
  122. data/lib/rubocop/cop/rails/find_by.rb +2 -2
  123. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +15 -7
  124. data/lib/rubocop/cop/rails/http_positional_arguments.rb +2 -2
  125. data/lib/rubocop/cop/rails/inverse_of.rb +130 -8
  126. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +3 -3
  127. data/lib/rubocop/cop/rails/pluralization_grammar.rb +3 -2
  128. data/lib/rubocop/cop/rails/presence.rb +31 -18
  129. data/lib/rubocop/cop/rails/present.rb +11 -8
  130. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +52 -10
  131. data/lib/rubocop/cop/rails/request_referer.rb +2 -3
  132. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +9 -2
  133. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +38 -10
  134. data/lib/rubocop/cop/style/class_and_module_children.rb +76 -0
  135. data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
  136. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  137. data/lib/rubocop/cop/style/format_string_token.rb +24 -4
  138. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +46 -0
  139. data/lib/rubocop/cop/style/hash_syntax.rb +4 -3
  140. data/lib/rubocop/cop/style/if_unless_modifier.rb +14 -0
  141. data/lib/rubocop/cop/style/method_def_parentheses.rb +79 -0
  142. data/lib/rubocop/cop/style/mixin_usage.rb +13 -2
  143. data/lib/rubocop/cop/style/multiline_if_modifier.rb +1 -1
  144. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +19 -0
  145. data/lib/rubocop/cop/style/negated_if.rb +1 -1
  146. data/lib/rubocop/cop/style/negated_while.rb +6 -4
  147. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
  148. data/lib/rubocop/cop/style/parentheses_around_condition.rb +4 -0
  149. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
  150. data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
  151. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  152. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  153. data/lib/rubocop/cop/style/string_literals.rb +4 -0
  154. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -0
  155. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +1 -1
  156. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -0
  157. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +4 -0
  158. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
  159. data/lib/rubocop/formatter/disabled_config_formatter.rb +33 -24
  160. data/lib/rubocop/options.rb +33 -10
  161. data/lib/rubocop/path_util.rb +7 -0
  162. data/lib/rubocop/token.rb +4 -0
  163. data/lib/rubocop/version.rb +1 -1
  164. metadata +14 -4
  165. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +0 -149
  166. data/lib/rubocop/cop/style/extend_self.rb +0 -92
@@ -34,7 +34,7 @@ module RuboCop
34
34
  # end
35
35
  # end
36
36
  class LexicallyScopedActionFilter < Cop
37
- MSG = '%s not explicitly defined on the controller.'.freeze
37
+ MSG = '%<action>s not explicitly defined on the controller.'.freeze
38
38
 
39
39
  FILTERS = %w[
40
40
  :after_action
@@ -101,9 +101,9 @@ module RuboCop
101
101
 
102
102
  def message(methods)
103
103
  if methods.size == 1
104
- format(MSG, "`#{methods[0]}` is")
104
+ format(MSG, action: "`#{methods[0]}` is")
105
105
  else
106
- format(MSG, "`#{methods.join('`, `')}` are")
106
+ format(MSG, action: "`#{methods.join('`, `')}` are")
107
107
  end
108
108
  end
109
109
  end
@@ -26,7 +26,7 @@ module RuboCop
26
26
 
27
27
  PLURAL_DURATION_METHODS = SINGULAR_DURATION_METHODS.invert.freeze
28
28
 
29
- MSG = 'Prefer `%s.%s`.'.freeze
29
+ MSG = 'Prefer `%<number>s.%<correct>s`.'.freeze
30
30
 
31
31
  def on_send(node)
32
32
  return unless duration_method?(node.method_name)
@@ -50,7 +50,8 @@ module RuboCop
50
50
  def message(node)
51
51
  number, = *node.receiver
52
52
 
53
- format(MSG, number, correct_method(node.method_name.to_s))
53
+ format(MSG, number: number,
54
+ correct: correct_method(node.method_name.to_s))
54
55
  end
55
56
 
56
57
  def correct_method(method_name)
@@ -45,11 +45,11 @@ module RuboCop
45
45
  (if
46
46
  (send $_recv :present?)
47
47
  _recv
48
- $_false
48
+ $!begin
49
49
  )
50
50
  (if
51
51
  (send $_recv :blank?)
52
- $_true
52
+ $!begin
53
53
  _recv
54
54
  )
55
55
  }
@@ -59,44 +59,57 @@ module RuboCop
59
59
  {
60
60
  (if
61
61
  (send (send $_recv :present?) :!)
62
- $_true
62
+ $!begin
63
63
  _recv
64
64
  )
65
65
  (if
66
66
  (send (send $_recv :blank?) :!)
67
67
  _recv
68
- $_false
68
+ $!begin
69
69
  )
70
70
  }
71
71
  PATTERN
72
72
 
73
73
  def on_if(node)
74
- receiver, other = redundant_receiver_and_other(node)
75
- unless receiver
76
- receiver, other = redundant_negative_receiver_and_other(node)
74
+ redundant_receiver_and_other(node) do |receiver, other|
75
+ unless ignore_other_node?(other)
76
+ add_offense(node, message: message(node, receiver, other))
77
+ end
78
+ end
79
+
80
+ redundant_negative_receiver_and_other(node) do |receiver, other|
81
+ unless ignore_other_node?(other)
82
+ add_offense(node, message: message(node, receiver, other))
83
+ end
77
84
  end
78
- return unless receiver
79
- message = format(MSG,
80
- prefer: replacement(receiver, other),
81
- current: node.source)
82
- add_offense(node, message: message)
83
85
  end
84
86
 
85
87
  def autocorrect(node)
86
88
  lambda do |corrector|
87
- receiver, other = redundant_receiver_and_other(node)
88
- unless receiver
89
- receiver, other = redundant_negative_receiver_and_other(node)
89
+ redundant_receiver_and_other(node) do |receiver, other|
90
+ corrector.replace(node.source_range, replacement(receiver, other))
91
+ end
92
+
93
+ redundant_negative_receiver_and_other(node) do |receiver, other|
94
+ corrector.replace(node.source_range, replacement(receiver, other))
90
95
  end
91
- return unless receiver
92
- corrector.replace(node.source_range, replacement(receiver, other))
93
96
  end
94
97
  end
95
98
 
96
99
  private
97
100
 
101
+ def ignore_other_node?(node)
102
+ node && (node.if_type? || node.rescue_type? || node.while_type?)
103
+ end
104
+
105
+ def message(node, receiver, other)
106
+ format(MSG,
107
+ prefer: replacement(receiver, other),
108
+ current: node.source)
109
+ end
110
+
98
111
  def replacement(receiver, other)
99
- or_source = other.nil_type? ? '' : " || #{other.source}"
112
+ or_source = other.nil? || other.nil_type? ? '' : " || #{other.source}"
100
113
  "#{receiver.source}.presence" + or_source
101
114
  end
102
115
  end
@@ -35,9 +35,11 @@ module RuboCop
35
35
  # # good
36
36
  # something if foo.present?
37
37
  class Present < Cop
38
- MSG_NOT_BLANK = 'Use `%s` instead of `%s`.'.freeze
39
- MSG_EXISTS_AND_NOT_EMPTY = 'Use `%s` instead of `%s`.'.freeze
40
- MSG_UNLESS_BLANK = 'Use `if %s` instead of `%s`.'.freeze
38
+ MSG_NOT_BLANK = 'Use `%<prefer>s` instead of `%<current>s`.'.freeze
39
+ MSG_EXISTS_AND_NOT_EMPTY = 'Use `%<prefer>s` instead of ' \
40
+ '`%<current>s`.'.freeze
41
+ MSG_UNLESS_BLANK = 'Use `if %<prefer>s` instead of ' \
42
+ '`%<current>s`.'.freeze
41
43
 
42
44
  def_node_matcher :exists_and_not_empty?, <<-PATTERN
43
45
  (and
@@ -65,8 +67,8 @@ module RuboCop
65
67
  not_blank?(node) do |receiver|
66
68
  add_offense(node,
67
69
  message: format(MSG_NOT_BLANK,
68
- replacement(receiver),
69
- node.source))
70
+ prefer: replacement(receiver),
71
+ current: node.source))
70
72
  end
71
73
  end
72
74
 
@@ -78,8 +80,8 @@ module RuboCop
78
80
 
79
81
  add_offense(node,
80
82
  message: format(MSG_EXISTS_AND_NOT_EMPTY,
81
- replacement(variable1),
82
- node.source))
83
+ prefer: replacement(variable1),
84
+ current: node.source))
83
85
  end
84
86
  end
85
87
 
@@ -99,7 +101,8 @@ module RuboCop
99
101
 
100
102
  unless_blank?(node) do |method_call, receiver|
101
103
  range = unless_condition(node, method_call)
102
- msg = format(MSG_UNLESS_BLANK, replacement(receiver), range.source)
104
+ msg = format(MSG_UNLESS_BLANK, prefer: replacement(receiver),
105
+ current: range.source)
103
106
  add_offense(node, location: range, message: msg)
104
107
  end
105
108
  end
@@ -26,6 +26,34 @@ module RuboCop
26
26
  # has_many :expenses
27
27
  # end
28
28
  # end
29
+ #
30
+ # @example
31
+ # # bad
32
+ # with_options options: false do |merger|
33
+ # merger.invoke(merger.something)
34
+ # end
35
+ #
36
+ # # good
37
+ # with_options options: false do
38
+ # invoke(something)
39
+ # end
40
+ #
41
+ # # good
42
+ # client = Client.new
43
+ # with_options options: false do |merger|
44
+ # client.invoke(merger.something, something)
45
+ # end
46
+ #
47
+ # # ok
48
+ # # When `with_options` includes a block, all scoping scenarios
49
+ # # cannot be evaluated. Thus, it is ok to include the explicit
50
+ # # receiver.
51
+ # with_options options: false do |merger|
52
+ # merger.invoke
53
+ # with_another_method do |another_receiver|
54
+ # merger.invoke(another_receiver)
55
+ # end
56
+ # end
29
57
  class RedundantReceiverInWithOptions < Cop
30
58
  extend TargetRailsVersion
31
59
 
@@ -38,26 +66,35 @@ module RuboCop
38
66
  (send nil? :with_options
39
67
  (...))
40
68
  (args
41
- (...))
42
- ...)
69
+ $_arg)
70
+ $_body)
43
71
  PATTERN
44
72
 
45
- def_node_search :assoc_has_redundant_receiver, <<-PATTERN
46
- (send
47
- (lvar _) ...)
73
+ def_node_search :all_block_nodes_in, <<-PATTERN
74
+ (block ...)
75
+ PATTERN
76
+
77
+ def_node_search :all_send_nodes_in, <<-PATTERN
78
+ (send ...)
48
79
  PATTERN
49
80
 
50
81
  def on_block(node)
51
- with_options?(node) do
52
- assoc_has_redundant_receiver(node).each do |assoc|
53
- add_offense(assoc, location: assoc.receiver.loc.expression)
82
+ with_options?(node) do |arg, body|
83
+ return unless all_block_nodes_in(body).count.zero?
84
+ send_nodes = all_send_nodes_in(body)
85
+
86
+ if send_nodes.all? { |n| same_value?(arg, n.receiver) }
87
+ send_nodes.each do |send_node|
88
+ receiver = send_node.receiver
89
+ add_offense(send_node, location: receiver.source_range)
90
+ end
54
91
  end
55
92
  end
56
93
  end
57
94
 
58
95
  def autocorrect(node)
59
96
  lambda do |corrector|
60
- corrector.remove(node.receiver.loc.expression)
97
+ corrector.remove(node.receiver.source_range)
61
98
  corrector.remove(node.loc.dot)
62
99
  corrector.remove(block_argument_range(node))
63
100
  end
@@ -66,7 +103,8 @@ module RuboCop
66
103
  private
67
104
 
68
105
  def block_argument_range(node)
69
- block_argument = node.parent.parent.children[1].loc.expression
106
+ block_node = node.each_ancestor(:block).first
107
+ block_argument = block_node.children[1].source_range
70
108
 
71
109
  range_between(
72
110
  search_begin_pos_of_space_before_block_argument(
@@ -85,6 +123,10 @@ module RuboCop
85
123
  begin_pos
86
124
  end
87
125
  end
126
+
127
+ def same_value?(arg_node, recv_node)
128
+ recv_node && recv_node.children[0] == arg_node.children[0]
129
+ end
88
130
  end
89
131
  end
90
132
  end
@@ -6,15 +6,14 @@ module RuboCop
6
6
  # This cop checks for consistent uses of `request.referer` or
7
7
  # `request.referrer`, depending on the cop's configuration.
8
8
  #
9
- # @example
10
- # # EnforcedStyle: referer
9
+ # @example EnforcedStyle: referer (default)
11
10
  # # bad
12
11
  # request.referrer
13
12
  #
14
13
  # # good
15
14
  # request.referer
16
15
  #
17
- # # EnforcedStyle: referrer
16
+ # @example EnforcedStyle: referrer
18
17
  # # bad
19
18
  # request.referer
20
19
  #
@@ -29,8 +29,7 @@ module RuboCop
29
29
 
30
30
  next if node.receiver != target_receiver
31
31
  next if node.method_name != target_method
32
- next if node.parent && node.parent.block_type?
33
- next if node.block_argument?
32
+ next if cleanup?(node)
34
33
 
35
34
  add_offense(node,
36
35
  message: format(MSG,
@@ -38,6 +37,14 @@ module RuboCop
38
37
  method: target_method))
39
38
  end
40
39
  end
40
+
41
+ private
42
+
43
+ def cleanup?(node)
44
+ parent = node.parent
45
+ node.block_argument? ||
46
+ (parent && (parent.block_type? || !parent.lvasgn_type?))
47
+ end
41
48
  end
42
49
  end
43
50
  end
@@ -125,24 +125,52 @@ module RuboCop
125
125
  end
126
126
  end
127
127
 
128
+ # rubocop:disable Metrics/AbcSize
128
129
  def remove_braces_with_whitespace(corrector, node, space)
129
130
  right_brace_and_space = right_brace_and_space(node.loc.end, space)
130
131
 
131
132
  if comment_on_line?(right_brace_and_space.line)
132
- # Removing a line break between a comment and the closing
133
- # parenthesis would cause a syntax error, so we only remove the
134
- # braces in that case.
135
133
  remove_braces(corrector, node)
134
+ elsif node.multiline?
135
+ remove_braces_with_range(corrector,
136
+ left_whole_line_range(node.loc.begin),
137
+ right_whole_line_range(node.loc.end))
136
138
  else
137
- left_brace_and_space =
138
- range_with_surrounding_space(range: node.loc.begin,
139
- side: :right,
140
- newlines: space[:newlines],
141
- whitespace: space[:left])
142
- corrector.remove(left_brace_and_space)
143
- corrector.remove(right_brace_and_space)
139
+ left_brace_and_space = left_brace_and_space(node.loc.begin, space)
140
+ remove_braces_with_range(corrector,
141
+ left_brace_and_space,
142
+ right_brace_and_space)
144
143
  end
145
144
  end
145
+ # rubocop:enable Metrics/AbcSize
146
+
147
+ def remove_braces_with_range(corrector, left_range, right_range)
148
+ corrector.remove(left_range)
149
+ corrector.remove(right_range)
150
+ end
151
+
152
+ def left_whole_line_range(loc_begin)
153
+ if range_by_whole_lines(loc_begin).source.strip == '{'
154
+ range_by_whole_lines(loc_begin, include_final_newline: true)
155
+ else
156
+ loc_begin
157
+ end
158
+ end
159
+
160
+ def right_whole_line_range(loc_end)
161
+ if range_by_whole_lines(loc_end).source.strip == '}'
162
+ range_by_whole_lines(loc_end, include_final_newline: true)
163
+ else
164
+ loc_end
165
+ end
166
+ end
167
+
168
+ def left_brace_and_space(loc_begin, space)
169
+ range_with_surrounding_space(range: loc_begin,
170
+ side: :right,
171
+ newlines: space[:newlines],
172
+ whitespace: space[:left])
173
+ end
146
174
 
147
175
  def right_brace_and_space(loc_end, space)
148
176
  brace_and_space =
@@ -40,8 +40,84 @@ module RuboCop
40
40
  check_style(node, body)
41
41
  end
42
42
 
43
+ def autocorrect(node)
44
+ lambda do |corrector|
45
+ if node.class_type?
46
+ name, superclass, body = *node
47
+ return if superclass && style != :nested
48
+ else
49
+ name, body = *node
50
+ end
51
+ nest_or_compact(corrector, node, name, body)
52
+ end
53
+ end
54
+
43
55
  private
44
56
 
57
+ def nest_or_compact(corrector, node, name, body)
58
+ if style == :nested
59
+ nest_definition(corrector, node)
60
+ else
61
+ compact_definition(corrector, node, name, body)
62
+ end
63
+ end
64
+
65
+ def nest_definition(corrector, node)
66
+ padding = ((' ' * indent_width) + leading_spaces(node)).to_s
67
+ padding_for_trailing_end = padding.sub(' ' * node.loc.end.column, '')
68
+
69
+ replace_keyword_with_module(corrector, node)
70
+ split_on_double_colon(corrector, node, padding)
71
+ add_trailing_end(corrector, node, padding_for_trailing_end)
72
+ end
73
+
74
+ def replace_keyword_with_module(corrector, node)
75
+ corrector.replace(node.loc.keyword, 'module'.freeze)
76
+ end
77
+
78
+ def split_on_double_colon(corrector, node, padding)
79
+ children_definition = node.children.first
80
+ range = range_between(children_definition.loc.double_colon.begin_pos,
81
+ children_definition.loc.double_colon.end_pos)
82
+ replacement = "\n#{padding}#{node.loc.keyword.source} ".freeze
83
+
84
+ corrector.replace(range, replacement)
85
+ end
86
+
87
+ def add_trailing_end(corrector, node, padding)
88
+ replacement = "#{padding}end\n#{leading_spaces(node)}end".freeze
89
+ corrector.replace(node.loc.end, replacement)
90
+ end
91
+
92
+ def compact_definition(corrector, node, name, body)
93
+ compact_node(corrector, node, name, body)
94
+ remove_end(corrector, body)
95
+ end
96
+
97
+ def compact_node(corrector, node, name, body)
98
+ const_name = "#{name.const_name}::#{body.children.first.const_name}"
99
+ replacement = "#{body.type} #{const_name}"
100
+ range = range_between(node.loc.keyword.begin_pos,
101
+ body.loc.name.end_pos)
102
+ corrector.replace(range, replacement)
103
+ end
104
+
105
+ def remove_end(corrector, body)
106
+ range = range_between(
107
+ body.loc.end.begin_pos - leading_spaces(body).size,
108
+ body.loc.end.end_pos + 1
109
+ )
110
+ corrector.remove(range)
111
+ end
112
+
113
+ def leading_spaces(node)
114
+ node.source_range.source_line[/\A\s*/]
115
+ end
116
+
117
+ def indent_width
118
+ @config.for_cop('IndentationWidth')['Width'] || 2
119
+ end
120
+
45
121
  def check_style(node, body)
46
122
  if style == :nested
47
123
  check_nested_style(node)