rubocop 0.34.2 → 0.35.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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +103 -31
  4. data/config/default.yml +32 -2
  5. data/config/disabled.yml +24 -0
  6. data/config/enabled.yml +20 -2
  7. data/lib/rubocop.rb +13 -0
  8. data/lib/rubocop/ast_node.rb +48 -0
  9. data/lib/rubocop/cli.rb +9 -0
  10. data/lib/rubocop/config.rb +8 -6
  11. data/lib/rubocop/config_loader.rb +30 -8
  12. data/lib/rubocop/cop/commissioner.rb +1 -1
  13. data/lib/rubocop/cop/cop.rb +19 -6
  14. data/lib/rubocop/cop/lint/circular_argument_reference.rb +33 -2
  15. data/lib/rubocop/cop/lint/debugger.rb +9 -56
  16. data/lib/rubocop/cop/lint/end_alignment.rb +29 -9
  17. data/lib/rubocop/cop/lint/eval.rb +6 -2
  18. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +24 -6
  19. data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -5
  20. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +10 -1
  21. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  22. data/lib/rubocop/cop/lint/space_before_first_arg.rb +1 -1
  23. data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -0
  24. data/lib/rubocop/cop/lint/unused_method_argument.rb +8 -0
  25. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  26. data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
  27. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +1 -1
  28. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +26 -3
  29. data/lib/rubocop/cop/mixin/check_assignment.rb +2 -3
  30. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +59 -12
  31. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -1
  32. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  33. data/lib/rubocop/cop/mixin/first_element_line_break.rb +41 -0
  34. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
  35. data/lib/rubocop/cop/mixin/safe_assignment.rb +3 -14
  36. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
  37. data/lib/rubocop/cop/performance/detect.rb +5 -1
  38. data/lib/rubocop/cop/performance/fixed_size.rb +50 -0
  39. data/lib/rubocop/cop/performance/size.rb +1 -1
  40. data/lib/rubocop/cop/performance/string_replacement.rb +14 -8
  41. data/lib/rubocop/cop/rails/pluralization_grammar.rb +97 -0
  42. data/lib/rubocop/cop/style/align_hash.rb +1 -12
  43. data/lib/rubocop/cop/style/align_parameters.rb +19 -7
  44. data/lib/rubocop/cop/style/and_or.rb +42 -13
  45. data/lib/rubocop/cop/style/block_comments.rb +4 -2
  46. data/lib/rubocop/cop/style/block_delimiters.rb +57 -18
  47. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
  48. data/lib/rubocop/cop/style/command_literal.rb +2 -10
  49. data/lib/rubocop/cop/style/copyright.rb +5 -3
  50. data/lib/rubocop/cop/style/documentation.rb +9 -6
  51. data/lib/rubocop/cop/style/dot_position.rb +6 -0
  52. data/lib/rubocop/cop/style/double_negation.rb +4 -15
  53. data/lib/rubocop/cop/style/each_with_object.rb +17 -4
  54. data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -5
  55. data/lib/rubocop/cop/style/encoding.rb +10 -4
  56. data/lib/rubocop/cop/style/extra_spacing.rb +23 -13
  57. data/lib/rubocop/cop/style/first_array_element_line_break.rb +41 -0
  58. data/lib/rubocop/cop/style/first_hash_element_line_break.rb +35 -0
  59. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +37 -0
  60. data/lib/rubocop/cop/style/first_method_parameter_line_break.rb +42 -0
  61. data/lib/rubocop/cop/style/for.rb +2 -1
  62. data/lib/rubocop/cop/style/if_unless_modifier.rb +31 -0
  63. data/lib/rubocop/cop/style/indent_hash.rb +67 -37
  64. data/lib/rubocop/cop/style/indentation_width.rb +1 -1
  65. data/lib/rubocop/cop/style/leading_comment_space.rb +3 -2
  66. data/lib/rubocop/cop/style/method_call_parentheses.rb +8 -0
  67. data/lib/rubocop/cop/style/method_def_parentheses.rb +10 -7
  68. data/lib/rubocop/cop/style/multiline_operation_indentation.rb +8 -13
  69. data/lib/rubocop/cop/style/nested_modifier.rb +97 -0
  70. data/lib/rubocop/cop/style/next.rb +18 -0
  71. data/lib/rubocop/cop/style/parallel_assignment.rb +57 -15
  72. data/lib/rubocop/cop/style/predicate_name.rb +7 -2
  73. data/lib/rubocop/cop/style/regexp_literal.rb +2 -10
  74. data/lib/rubocop/cop/style/single_line_methods.rb +7 -5
  75. data/lib/rubocop/cop/style/single_space_before_first_arg.rb +1 -1
  76. data/lib/rubocop/cop/style/space_around_operators.rb +2 -0
  77. data/lib/rubocop/cop/style/special_global_vars.rb +4 -2
  78. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +108 -0
  79. data/lib/rubocop/cop/style/trailing_comma.rb +9 -6
  80. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -2
  81. data/lib/rubocop/cop/style/unneeded_percent_q.rb +31 -20
  82. data/lib/rubocop/cop/style/variable_name.rb +5 -0
  83. data/lib/rubocop/cop/style/word_array.rb +2 -1
  84. data/lib/rubocop/cop/team.rb +17 -4
  85. data/lib/rubocop/cop/util.rb +5 -0
  86. data/lib/rubocop/cop/variable_force/locatable.rb +1 -1
  87. data/lib/rubocop/formatter/base_formatter.rb +1 -1
  88. data/lib/rubocop/formatter/disabled_config_formatter.rb +22 -10
  89. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  90. data/lib/rubocop/node_pattern.rb +390 -0
  91. data/lib/rubocop/options.rb +48 -36
  92. data/lib/rubocop/processed_source.rb +3 -1
  93. data/lib/rubocop/rake_task.rb +1 -1
  94. data/lib/rubocop/remote_config.rb +60 -0
  95. data/lib/rubocop/result_cache.rb +4 -2
  96. data/lib/rubocop/runner.rb +33 -10
  97. data/lib/rubocop/token.rb +2 -1
  98. data/lib/rubocop/version.rb +1 -1
  99. data/lib/rubocop/warning.rb +11 -0
  100. data/relnotes/v0.35.0.md +210 -0
  101. data/rubocop.gemspec +2 -2
  102. metadata +20 -6
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for a line break before the first element in a
7
+ # multi-line hash.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # { a: 1,
13
+ # b: 2}
14
+ #
15
+ # # good
16
+ # {
17
+ # a: 1,
18
+ # b: 2 }
19
+ class FirstHashElementLineBreak < Cop
20
+ include FirstElementLineBreak
21
+
22
+ MSG = 'Add a line break before the first element of a ' \
23
+ 'multi-line hash.'
24
+
25
+ def on_hash(node)
26
+ if node.loc.begin
27
+ check_children_line_break(node, node.children)
28
+ elsif method_uses_parens?(node.parent, node)
29
+ check_children_line_break(node, node.children, node.parent)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for a line break before the first argument in a
7
+ # multi-line method call.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # method(foo, bar,
13
+ # baz)
14
+ #
15
+ # # good
16
+ # method(
17
+ # foo, bar,
18
+ # baz)
19
+ #
20
+ # # ignored
21
+ # method foo, bar,
22
+ # baz
23
+ class FirstMethodArgumentLineBreak < Cop
24
+ include FirstElementLineBreak
25
+
26
+ MSG = 'Add a line break before the first argument of a ' \
27
+ 'multi-line method argument list.'
28
+
29
+ def on_send(node)
30
+ _receiver, _name, *args = *node
31
+
32
+ check_method_line_break(node, args)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for a line break before the first parameter in a
7
+ # multi-line method parameter definition.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # def method(foo, bar,
13
+ # baz)
14
+ # do_something
15
+ # end
16
+ #
17
+ # # good
18
+ # def method(
19
+ # foo, bar,
20
+ # baz)
21
+ # do_something
22
+ # end
23
+ #
24
+ # # ignored
25
+ # def method foo,
26
+ # bar
27
+ # do_something
28
+ # end
29
+ class FirstMethodParameterLineBreak < Cop
30
+ include OnMethodDef
31
+ include FirstElementLineBreak
32
+
33
+ MSG = 'Add a line break before the first parameter of a ' \
34
+ 'multi-line method parameter list.'
35
+
36
+ def on_method_def(node, _method_name, args, _body)
37
+ check_method_line_break(node, args.to_a)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -9,6 +9,7 @@ module RuboCop
9
9
  # allowed, however.
10
10
  class For < Cop
11
11
  include ConfigurableEnforcedStyle
12
+ EACH_LENGTH = 'each'.length
12
13
 
13
14
  def on_for(node)
14
15
  if style == :each
@@ -32,7 +33,7 @@ module RuboCop
32
33
  if style == :for
33
34
  end_pos = method.loc.expression.end_pos
34
35
  range = Parser::Source::Range.new(processed_source.buffer,
35
- end_pos - 'each'.length,
36
+ end_pos - EACH_LENGTH,
36
37
  end_pos)
37
38
  add_offense(range, range, 'Prefer `for` over `each`.') do
38
39
  opposite_style_detected
@@ -9,6 +9,8 @@ module RuboCop
9
9
  class IfUnlessModifier < Cop
10
10
  include StatementModifier
11
11
 
12
+ ASSIGNMENT_TYPES = [:lvasgn, :casgn, :cvasgn, :gvasgn, :ivasgn, :masgn]
13
+
12
14
  def message(keyword)
13
15
  "Favor modifier `#{keyword}` usage when having a single-line body." \
14
16
  ' Another good alternative is the usage of control flow `&&`/`||`.'
@@ -20,10 +22,38 @@ module RuboCop
20
22
  return if modifier_if?(node)
21
23
  return if elsif?(node)
22
24
  return if if_else?(node)
25
+ return if chained?(node)
23
26
  return unless fit_within_line_as_modifier_form?(node)
24
27
  add_offense(node, :keyword, message(node.loc.keyword.source))
25
28
  end
26
29
 
30
+ def chained?(node)
31
+ # Don't register offense for `if ... end.method`
32
+ return false if node.parent.nil? || !node.parent.send_type?
33
+ receiver = node.parent.children[0]
34
+ node.equal?(receiver)
35
+ end
36
+
37
+ def parenthesize?(node)
38
+ # Parenthesize corrected expression if changing to modifier-if form
39
+ # would change the meaning of the parent expression
40
+ # (due to the low operator precedence of modifier-if)
41
+ return false if node.parent.nil?
42
+ return true if ASSIGNMENT_TYPES.include?(node.parent.type)
43
+
44
+ if node.parent.send_type?
45
+ _receiver, _name, *args = *node.parent
46
+ return !method_uses_parens?(node.parent, args.first)
47
+ end
48
+
49
+ false
50
+ end
51
+
52
+ def method_uses_parens?(node, limit)
53
+ source = node.loc.expression.source_line[0...limit.loc.column]
54
+ source =~ /\s*\(\s*$/
55
+ end
56
+
27
57
  def autocorrect(node)
28
58
  cond, body, _else = if_node_parts(node)
29
59
 
@@ -36,6 +66,7 @@ module RuboCop
36
66
  if first_line_comment
37
67
  oneline << ' ' << first_line_comment.loc.expression.source
38
68
  end
69
+ oneline = "(#{oneline})" if parenthesize?(node)
39
70
 
40
71
  ->(corrector) { corrector.replace(node.loc.expression, oneline) }
41
72
  end
@@ -7,14 +7,37 @@ module RuboCop
7
7
  # where the opening brace and the first key are on separate lines. The
8
8
  # other keys' indentations are handled by the AlignHash cop.
9
9
  #
10
- # Hash literals that are arguments in a method call with parentheses, and
11
- # where the opening curly brace of the hash is on the same line as the
12
- # opening parenthesis of the method call, shall have their first key
13
- # indented one step (two spaces) more than the position inside the
14
- # opening parenthesis.
10
+ # By default, Hash literals that are arguments in a method call with
11
+ # parentheses, and where the opening curly brace of the hash is on the
12
+ # same line as the opening parenthesis of the method call, shall have
13
+ # their first key indented one step (two spaces) more than the position
14
+ # inside the opening parenthesis.
15
15
  #
16
16
  # Other hash literals shall have their first key indented one step more
17
17
  # than the start of the line where the opening curly brace is.
18
+ #
19
+ # This default style is called 'special_inside_parentheses'. Alternative
20
+ # styles are 'consistent' and 'align_braces'. Here are examples:
21
+ #
22
+ # # special_inside_parentheses
23
+ # hash = {
24
+ # key: :value
25
+ # }
26
+ # but_in_a_method_call({
27
+ # its_like: :this
28
+ # })
29
+ # # consistent
30
+ # hash = {
31
+ # key: :value
32
+ # }
33
+ # and_in_a_method_call({
34
+ # no: :difference
35
+ # })
36
+ # # align_braces
37
+ # and_now_for_something = {
38
+ # completely: :different
39
+ # }
40
+ #
18
41
  class IndentHash < Cop
19
42
  include AutocorrectAlignment
20
43
  include ConfigurableEnforcedStyle
@@ -62,13 +85,16 @@ module RuboCop
62
85
  end
63
86
 
64
87
  def check_right_brace(right_brace, left_brace, left_parenthesis)
88
+ # if the right brace is on the same line as the last value, accept
65
89
  return if right_brace.source_line[0...right_brace.column] =~ /\S/
66
90
 
67
91
  expected_column = base_column(left_brace, left_parenthesis)
68
92
  @column_delta = expected_column - right_brace.column
69
93
  return if @column_delta == 0
70
94
 
71
- msg = if style == :special_inside_parentheses && left_parenthesis
95
+ msg = if style == :align_braces
96
+ 'Indent the right brace the same as the left brace.'
97
+ elsif style == :special_inside_parentheses && left_parenthesis
72
98
  'Indent the right brace the same as the first position ' \
73
99
  'after the preceding left parenthesis.'
74
100
  else
@@ -93,15 +119,24 @@ module RuboCop
93
119
  end
94
120
 
95
121
  def check_first_pair(first_pair, left_brace, left_parenthesis, offset)
96
- column = first_pair.loc.expression.column
122
+ actual_column = first_pair.loc.expression.column
97
123
  expected_column = base_column(left_brace, left_parenthesis) +
98
124
  configured_indentation_width + offset
99
- @column_delta = expected_column - column
125
+ @column_delta = expected_column - actual_column
100
126
 
101
127
  if @column_delta == 0
102
- correct_style_detected
128
+ # which column was actually used as 'base column' for indentation?
129
+ # (not the column which we think should be the 'base column',
130
+ # but the one which has actually been used for that purpose)
131
+ base_column = actual_column - configured_indentation_width - offset
132
+ styles = detected_styles(base_column, left_parenthesis, left_brace)
133
+ if styles.size > 1
134
+ ambiguous_style_detected(*styles)
135
+ else
136
+ correct_style_detected
137
+ end
103
138
  else
104
- incorrect_style_detected(column, offset, first_pair,
139
+ incorrect_style_detected(actual_column, offset, first_pair,
105
140
  left_parenthesis, left_brace)
106
141
  end
107
142
  end
@@ -110,17 +145,29 @@ module RuboCop
110
145
  left_parenthesis, left_brace)
111
146
  add_offense(first_pair, :expression,
112
147
  message(base_description(left_parenthesis))) do
113
- if column == unexpected_column(left_brace, left_parenthesis,
114
- offset)
115
- opposite_style_detected
116
- else
117
- unrecognized_style_detected
118
- end
148
+ base_column = column - configured_indentation_width - offset
149
+ styles = detected_styles(base_column, left_parenthesis, left_brace)
150
+ ambiguous_style_detected(*styles)
119
151
  end
120
152
  end
121
153
 
154
+ def detected_styles(column, left_parenthesis, left_brace)
155
+ styles = []
156
+ if column == (left_brace.source_line =~ /\S/)
157
+ styles << :consistent
158
+ styles << :special_inside_parentheses unless left_parenthesis
159
+ end
160
+ if left_parenthesis && column == left_parenthesis.column + 1
161
+ styles << :special_inside_parentheses
162
+ end
163
+ styles << :align_braces if column == left_brace.column
164
+ styles
165
+ end
166
+
122
167
  def base_column(left_brace, left_parenthesis)
123
- if left_parenthesis && style == :special_inside_parentheses
168
+ if style == :align_braces
169
+ left_brace.column
170
+ elsif left_parenthesis && style == :special_inside_parentheses
124
171
  left_parenthesis.column + 1
125
172
  else
126
173
  left_brace.source_line =~ /\S/
@@ -129,32 +176,15 @@ module RuboCop
129
176
 
130
177
  # Returns the description of what the correct indentation is based on.
131
178
  def base_description(left_parenthesis)
132
- if left_parenthesis && style == :special_inside_parentheses
179
+ if style == :align_braces
180
+ 'the position of the opening brace'
181
+ elsif left_parenthesis && style == :special_inside_parentheses
133
182
  'the first position after the preceding left parenthesis'
134
183
  else
135
184
  'the start of the line where the left curly brace is'
136
185
  end
137
186
  end
138
187
 
139
- # Returns the "unexpected column", which is the column that would be
140
- # correct if the configuration was changed.
141
- def unexpected_column(left_brace, left_parenthesis, offset)
142
- # Set a crazy value by default, indicating that there's no other
143
- # configuration that can be chosen to make the used indentation
144
- # accepted.
145
- unexpected_base_column = -1000
146
-
147
- if left_parenthesis
148
- unexpected_base_column = if style == :special_inside_parentheses
149
- left_brace.source_line =~ /\S/
150
- else
151
- left_parenthesis.column + 1
152
- end
153
- end
154
-
155
- unexpected_base_column + configured_indentation_width + offset
156
- end
157
-
158
188
  def message(base_description)
159
189
  format('Use %d spaces for indentation in a hash, relative to %s.',
160
190
  configured_indentation_width, base_description)
@@ -257,7 +257,7 @@ module RuboCop
257
257
  return false unless body_node.loc.column == first_char_pos_on_line
258
258
 
259
259
  if [:rescue, :ensure].include?(body_node.type)
260
- block_body, *_ = *body_node
260
+ block_body, = *body_node
261
261
  return unless block_body
262
262
  end
263
263
 
@@ -6,13 +6,14 @@ module RuboCop
6
6
  # This cop checks whether comments have a leading space
7
7
  # after the # denoting the start of the comment. The
8
8
  # leading space is not required for some RDoc special syntax,
9
- # like #++, #--, #:nodoc, etc.
9
+ # like #++, #--, #:nodoc, etc. Neither is it required for
10
+ # =begin/=end comments.
10
11
  class LeadingCommentSpace < Cop
11
12
  MSG = 'Missing space after #.'
12
13
 
13
14
  def investigate(processed_source)
14
15
  processed_source.comments.each do |comment|
15
- next unless comment.text =~ /^#+[^#\s=:+-]/
16
+ next unless comment.text =~ /\A#+[^#\s=:+-]/
16
17
  next if comment.text.start_with?('#!') && comment.loc.line == 1
17
18
 
18
19
  add_offense(comment, :expression)
@@ -37,6 +37,14 @@ module RuboCop
37
37
  mlhs_node, _mrhs_node = *asgn_node
38
38
  asgn_node = mlhs_node.children[node.sibling_index]
39
39
  end
40
+ # `obj.method = value` parses as (send ... :method= ...), and will
41
+ # not be returned as an `asgn_node` here
42
+ # however, `obj.method ||= value` parses as (or-asgn (send ...) ...)
43
+ # which IS an `asgn_node`
44
+ if asgn_node.or_asgn_type? || asgn_node.and_asgn_type?
45
+ asgn_node, _value = *asgn_node
46
+ return false if asgn_node.send_type?
47
+ end
40
48
 
41
49
  asgn_node.loc.name.source == method_name.to_s
42
50
  end
@@ -10,7 +10,9 @@ module RuboCop
10
10
  include ConfigurableEnforcedStyle
11
11
 
12
12
  def on_method_def(node, _method_name, args, _body)
13
- if style == :require_parentheses
13
+ if style == :require_parentheses ||
14
+ (style == :require_no_parentheses_except_multiline &&
15
+ args.multiline?)
14
16
  if arguments?(args) && !parentheses?(args)
15
17
  missing_parentheses(node, args)
16
18
  else
@@ -25,7 +27,11 @@ module RuboCop
25
27
 
26
28
  def autocorrect(node)
27
29
  lambda do |corrector|
28
- if style == :require_parentheses
30
+ if node.args_type?
31
+ # offense is registered on args node when parentheses are unwanted
32
+ corrector.replace(node.loc.begin, ' ')
33
+ corrector.remove(node.loc.end)
34
+ else
29
35
  args_expr = args_node(node).loc.expression
30
36
  args_with_space = range_with_surrounding_space(args_expr, :left)
31
37
  just_space = Parser::Source::Range.new(args_expr.source_buffer,
@@ -33,9 +39,6 @@ module RuboCop
33
39
  args_expr.begin_pos)
34
40
  corrector.replace(just_space, '(')
35
41
  corrector.insert_after(args_expr, ')')
36
- elsif style == :require_no_parentheses
37
- corrector.replace(node.loc.begin, ' ')
38
- corrector.remove(node.loc.end)
39
42
  end
40
43
  end
41
44
  end
@@ -45,13 +48,13 @@ module RuboCop
45
48
  def missing_parentheses(node, args)
46
49
  add_offense(node, args.loc.expression,
47
50
  'Use def with parentheses when there are parameters.') do
48
- opposite_style_detected
51
+ unexpected_style_detected(:require_no_parentheses)
49
52
  end
50
53
  end
51
54
 
52
55
  def unwanted_parentheses(args)
53
56
  add_offense(args, :expression, 'Use def without parentheses.') do
54
- opposite_style_detected
57
+ unexpected_style_detected(:require_parentheses)
55
58
  end
56
59
  end
57
60
 
@@ -98,7 +98,7 @@ module RuboCop
98
98
  article = kw =~ /^[iu]/ ? 'an' : 'a'
99
99
  "a #{kind} in #{article} `#{kw}` statement"
100
100
  else
101
- 'an expression' + (assignment?(node) ? ' in an assignment' : '')
101
+ 'an expression' + (assignment_rhs?(node) ? ' in an assignment' : '')
102
102
  end
103
103
  end
104
104
 
@@ -142,7 +142,7 @@ module RuboCop
142
142
 
143
143
  def should_align?(node, given_style)
144
144
  given_style == :aligned && (kw_node_with_special_indentation(node) ||
145
- assignment?(node))
145
+ assignment_rhs?(node))
146
146
  end
147
147
 
148
148
  def kw_node_with_special_indentation(node)
@@ -160,17 +160,12 @@ module RuboCop
160
160
  end
161
161
  end
162
162
 
163
- def assignment?(node)
164
- node.each_ancestor.find do |a|
165
- case a.type
166
- when :send
167
- _receiver, method_name, *_args = *a
168
- # The []= operator is the only assignment operator that is parsed
169
- # as a :send node.
170
- method_name == :[]=
171
- when *ASGN_NODES
172
- true
173
- end
163
+ def assignment_rhs?(node)
164
+ node.ancestors.unshift(node).each_cons(2).any? do |child, parent|
165
+ return true if parent.asgn_rhs.equal?(child)
166
+ grandparent = parent.parent
167
+ return true if grandparent && grandparent.masgn_type? &&
168
+ grandparent.asgn_rhs.equal?(parent)
174
169
  end
175
170
  end
176
171