rubocop 0.36.0 → 0.37.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 (111) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -2
  3. data/README.md +10 -1
  4. data/assets/output.html.erb +55 -1
  5. data/config/default.yml +9 -3
  6. data/config/disabled.yml +21 -0
  7. data/config/enabled.yml +11 -10
  8. data/lib/rubocop.rb +9 -2
  9. data/lib/rubocop/ast_node.rb +67 -19
  10. data/lib/rubocop/ast_node/builder.rb +1 -0
  11. data/lib/rubocop/ast_node/sexp.rb +1 -0
  12. data/lib/rubocop/ast_node/traversal.rb +171 -0
  13. data/lib/rubocop/cached_data.rb +4 -1
  14. data/lib/rubocop/cli.rb +1 -1
  15. data/lib/rubocop/config.rb +36 -20
  16. data/lib/rubocop/config_loader.rb +6 -5
  17. data/lib/rubocop/cop/commissioner.rb +27 -18
  18. data/lib/rubocop/cop/cop.rb +7 -6
  19. data/lib/rubocop/cop/lint/duplicated_key.rb +1 -8
  20. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  21. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +18 -1
  22. data/lib/rubocop/cop/lint/nested_method_definition.rb +5 -1
  23. data/lib/rubocop/cop/lint/unneeded_disable.rb +1 -1
  24. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +1 -0
  25. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +9 -2
  26. data/lib/rubocop/cop/mixin/check_assignment.rb +1 -1
  27. data/lib/rubocop/cop/mixin/classish_length.rb +3 -4
  28. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +8 -4
  29. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  30. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +2 -1
  31. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +35 -0
  32. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  33. data/lib/rubocop/cop/mixin/min_body_length.rb +1 -1
  34. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +58 -0
  35. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  36. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  37. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -2
  38. data/lib/rubocop/cop/performance/case_when_splat.rb +7 -0
  39. data/lib/rubocop/cop/performance/casecmp.rb +56 -17
  40. data/lib/rubocop/cop/performance/redundant_block_call.rb +17 -3
  41. data/lib/rubocop/cop/performance/redundant_merge.rb +7 -1
  42. data/lib/rubocop/cop/performance/times_map.rb +3 -4
  43. data/lib/rubocop/cop/severity.rb +1 -1
  44. data/lib/rubocop/cop/style/align_hash.rb +1 -1
  45. data/lib/rubocop/cop/style/align_parameters.rb +1 -1
  46. data/lib/rubocop/cop/style/and_or.rb +1 -1
  47. data/lib/rubocop/cop/style/block_comments.rb +2 -0
  48. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
  49. data/lib/rubocop/cop/style/copyright.rb +2 -2
  50. data/lib/rubocop/cop/style/documentation.rb +19 -29
  51. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  52. data/lib/rubocop/cop/style/else_alignment.rb +2 -2
  53. data/lib/rubocop/cop/style/encoding.rb +1 -1
  54. data/lib/rubocop/cop/style/first_parameter_indentation.rb +1 -1
  55. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -12
  56. data/lib/rubocop/cop/style/guard_clause.rb +2 -1
  57. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -8
  58. data/lib/rubocop/cop/style/indent_assignment.rb +1 -1
  59. data/lib/rubocop/cop/style/indentation_width.rb +3 -7
  60. data/lib/rubocop/cop/style/method_call_parentheses.rb +2 -1
  61. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  62. data/lib/rubocop/cop/style/multiline_array_brace_layout.rb +3 -41
  63. data/lib/rubocop/cop/style/multiline_hash_brace_layout.rb +57 -0
  64. data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +65 -0
  65. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +5 -4
  66. data/lib/rubocop/cop/style/multiline_method_definition_brace_layout.rb +62 -0
  67. data/lib/rubocop/cop/style/multiline_operation_indentation.rb +9 -3
  68. data/lib/rubocop/cop/style/mutable_constant.rb +18 -3
  69. data/lib/rubocop/cop/style/nested_modifier.rb +5 -2
  70. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -1
  71. data/lib/rubocop/cop/style/next.rb +32 -11
  72. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  73. data/lib/rubocop/cop/style/redundant_freeze.rb +13 -3
  74. data/lib/rubocop/cop/style/redundant_parentheses.rb +33 -7
  75. data/lib/rubocop/cop/style/send.rb +1 -1
  76. data/lib/rubocop/cop/style/space_around_keyword.rb +198 -0
  77. data/lib/rubocop/cop/style/space_around_operators.rb +2 -12
  78. data/lib/rubocop/cop/style/space_inside_block_braces.rb +1 -1
  79. data/lib/rubocop/cop/style/special_global_vars.rb +4 -4
  80. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  81. data/lib/rubocop/cop/style/trailing_blank_lines.rb +1 -1
  82. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +1 -0
  83. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +1 -0
  84. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  85. data/lib/rubocop/cop/style/zero_length_predicate.rb +55 -0
  86. data/lib/rubocop/cop/team.rb +30 -5
  87. data/lib/rubocop/cop/util.rb +16 -1
  88. data/lib/rubocop/cop/variable_force.rb +3 -12
  89. data/lib/rubocop/cop/variable_force/assignment.rb +3 -3
  90. data/lib/rubocop/cop/variable_force/locatable.rb +25 -6
  91. data/lib/rubocop/cop/variable_force/reference.rb +3 -3
  92. data/lib/rubocop/cop/variable_force/scope.rb +8 -7
  93. data/lib/rubocop/cop/variable_force/variable.rb +3 -3
  94. data/lib/rubocop/cop/variable_force/variable_table.rb +1 -1
  95. data/lib/rubocop/formatter/formatter_set.rb +2 -2
  96. data/lib/rubocop/node_pattern.rb +1 -1
  97. data/lib/rubocop/options.rb +10 -10
  98. data/lib/rubocop/path_util.rb +5 -0
  99. data/lib/rubocop/processed_source.rb +8 -2
  100. data/lib/rubocop/result_cache.rb +1 -1
  101. data/lib/rubocop/runner.rb +1 -1
  102. data/lib/rubocop/token.rb +2 -2
  103. data/lib/rubocop/version.rb +1 -1
  104. data/relnotes/v0.30.1.md +1 -0
  105. data/relnotes/v0.33.0.md +1 -1
  106. data/relnotes/v0.36.0.md +2 -1
  107. data/relnotes/v0.37.0.md +200 -0
  108. data/rubocop.gemspec +2 -1
  109. metadata +28 -7
  110. data/lib/rubocop/cop/style/space_after_control_keyword.rb +0 -35
  111. data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +0 -38
@@ -25,6 +25,10 @@ module RuboCop
25
25
  # end
26
26
  class RedundantBlockCall < Cop
27
27
  MSG = 'Use `yield` instead of `%s.call`.'.freeze
28
+ YIELD = 'yield'.freeze
29
+ OPEN_PAREN = '('.freeze
30
+ CLOSE_PAREN = ')'.freeze
31
+ SPACE = ' '.freeze
28
32
 
29
33
  def_node_matcher :blockarg_def, <<-END
30
34
  {(def _ (args ... (blockarg $_)) $_)
@@ -37,6 +41,7 @@ module RuboCop
37
41
 
38
42
  def on_def(node)
39
43
  blockarg_def(node) do |argname, body|
44
+ next unless body
40
45
  blockarg_calls(body, argname) do |blockcall|
41
46
  add_offense(blockcall, :expression, format(MSG, argname))
42
47
  end
@@ -46,9 +51,18 @@ module RuboCop
46
51
  # offenses are registered on the `block.call` nodes
47
52
  def autocorrect(node)
48
53
  _receiver, _method, *args = *node
49
- new_source = 'yield'
50
- new_source += ' ' unless args.empty?
51
- new_source += args.map(&:source).join(', ')
54
+ new_source = String.new(YIELD)
55
+ unless args.empty?
56
+ new_source += if parentheses?(node)
57
+ OPEN_PAREN
58
+ else
59
+ SPACE
60
+ end
61
+
62
+ new_source << args.map(&:source).join(', ')
63
+ end
64
+
65
+ new_source << CLOSE_PAREN if parentheses?(node)
52
66
  ->(corrector) { corrector.replace(node.source_range, new_source) }
53
67
  end
54
68
  end
@@ -15,13 +15,15 @@ module RuboCop
15
15
  AREF_ASGN = '%s[%s] = %s'.freeze
16
16
  MSG = 'Use `%s` instead of `%s`.'.freeze
17
17
 
18
- def_node_matcher :redundant_merge, '(send $_ :merge! (hash $...))'
18
+ def_node_matcher :redundant_merge,
19
+ '(send $_ {:merge! :update} (hash $...))'
19
20
  def_node_matcher :modifier_flow_control, '[{if while until} #modifier?]'
20
21
 
21
22
  def on_send(node)
22
23
  redundant_merge(node) do |receiver, pairs|
23
24
  next if node.value_used?
24
25
  next if pairs.size > 1 && !receiver.pure?
26
+ next if pairs.size > max_key_value_pairs
25
27
 
26
28
  assignments = to_assignments(receiver, pairs).join('; ')
27
29
  message = format(MSG, assignments, node.source)
@@ -79,6 +81,10 @@ module RuboCop
79
81
  def modifier?(node)
80
82
  node.loc.respond_to?(:end) && node.loc.end.nil?
81
83
  end
84
+
85
+ def max_key_value_pairs
86
+ cop_config['MaxKeyValuePairs'].to_i
87
+ end
82
88
  end
83
89
  end
84
90
  end
@@ -33,15 +33,14 @@ module RuboCop
33
33
  private
34
34
 
35
35
  def check(node)
36
- map_or_collect = times_map_call(node)
37
- if map_or_collect
36
+ times_map_call(node) do |map_or_collect|
38
37
  add_offense(node, :expression, format(MSG, map_or_collect))
39
38
  end
40
39
  end
41
40
 
42
41
  def_node_matcher :times_map_call, <<-END
43
- {(block (send (send _ :times) ${:map :collect}) ...)
44
- (send (send _ :times) ${:map :collect} (block_pass ...))}
42
+ {(block (send (send !nil :times) ${:map :collect}) ...)
43
+ (send (send !nil :times) ${:map :collect} (block_pass ...))}
45
44
  END
46
45
  end
47
46
  end
@@ -33,7 +33,7 @@ module RuboCop
33
33
  def initialize(name_or_code)
34
34
  name = Severity.name_from_code(name_or_code)
35
35
  unless NAMES.include?(name)
36
- fail ArgumentError, "Unknown severity: #{name}"
36
+ raise ArgumentError, "Unknown severity: #{name}"
37
37
  end
38
38
  @name = name.freeze
39
39
  freeze
@@ -234,7 +234,7 @@ module RuboCop
234
234
  when 'key' then KeyAlignment.new
235
235
  when 'table' then TableAlignment.new
236
236
  when 'separator' then SeparatorAlignment.new
237
- else fail "Unknown #{key}: #{cop_config[key]}"
237
+ else raise "Unknown #{key}: #{cop_config[key]}"
238
238
  end
239
239
  end
240
240
 
@@ -44,7 +44,7 @@ module RuboCop
44
44
  indentation_of_line = /\S.*/.match(line).begin(0)
45
45
  indentation_of_line + configured_indentation_width
46
46
  else
47
- args.first.loc.column
47
+ display_column(args.first.source_range)
48
48
  end
49
49
  end
50
50
 
@@ -91,7 +91,7 @@ module RuboCop
91
91
  elsif node.loc.selector.source == 'not'
92
92
  return correct_other(node, corrector)
93
93
  else
94
- fail 'unrecognized unary negation operator'
94
+ raise 'unrecognized unary negation operator'
95
95
  end
96
96
  end
97
97
  return unless correctable_send?(node)
@@ -23,6 +23,7 @@ module RuboCop
23
23
 
24
24
  lambda do |corrector|
25
25
  corrector.remove(eq_begin)
26
+ # rubocop:disable Style/ZeroLengthPredicate
26
27
  unless contents.length == 0
27
28
  corrector.replace(contents,
28
29
  contents.source
@@ -30,6 +31,7 @@ module RuboCop
30
31
  .gsub(/\n\n/, "\n#\n")
31
32
  .gsub(/\n(?=[^\z#])/, "\n# "))
32
33
  end
34
+ # rubocop:enable Style/ZeroLengthPredicate
33
35
  corrector.remove(eq_end)
34
36
  end
35
37
  end
@@ -46,6 +46,8 @@ module RuboCop
46
46
  "#{node.children[0].source} &&= "
47
47
  when :or_asgn
48
48
  "#{node.children[0].source} ||= "
49
+ when :casgn
50
+ "#{node.children[1]} = "
49
51
  when *ConditionalAssignment::VARIABLE_ASSIGNMENT_TYPES
50
52
  "#{node.children[0]} = "
51
53
  else
@@ -69,10 +69,10 @@ module RuboCop
69
69
  end
70
70
 
71
71
  def autocorrect(token)
72
- fail Warning, 'An AutocorrectNotice must be defined in ' \
72
+ raise Warning, 'An AutocorrectNotice must be defined in ' \
73
73
  'your RuboCop config' if autocorrect_notice.empty?
74
74
  regex = Regexp.new(notice)
75
- fail Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
75
+ raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
76
76
  "match Notice /#{notice}/" unless autocorrect_notice =~ regex
77
77
 
78
78
  lambda do |corrector|
@@ -19,37 +19,29 @@ module RuboCop
19
19
 
20
20
  def_node_matcher :constant_definition?, '{class module casgn}'
21
21
 
22
- def investigate(processed_source)
23
- ast = processed_source.ast
24
- return unless ast
22
+ def on_class(node)
23
+ _name, _superclass, body = *node
24
+ return unless body
25
+ return if namespace?(body)
26
+
27
+ ast_with_comments = processed_source.ast_with_comments
28
+ return if associated_comment?(node, ast_with_comments)
29
+ return if nodoc_comment?(node, ast_with_comments)
30
+ add_offense(node, :keyword, format(MSG, :class))
31
+ end
25
32
 
26
- ast_with_comments = Parser::Source::Comment.associate(
27
- ast,
28
- processed_source.comments
29
- )
33
+ def on_module(node)
34
+ _name, body = *node
35
+ return if namespace?(body)
30
36
 
31
- check(ast, ast_with_comments)
37
+ ast_with_comments = processed_source.ast_with_comments
38
+ return if associated_comment?(node, ast_with_comments)
39
+ return if nodoc_comment?(node, ast_with_comments)
40
+ add_offense(node, :keyword, format(MSG, :module))
32
41
  end
33
42
 
34
43
  private
35
44
 
36
- def check(ast, ast_with_comments)
37
- ast.each_node(:class, :module) do |node|
38
- case node.type
39
- when :class
40
- _name, _superclass, body = *node
41
- when :module
42
- _name, body = *node
43
- end
44
-
45
- next if node.type == :class && !body
46
- next if namespace?(body)
47
- next if associated_comment?(node, ast_with_comments)
48
- next if nodoc?(node, ast_with_comments)
49
- add_offense(node, :keyword, format(MSG, node.type.to_s))
50
- end
51
- end
52
-
53
45
  def namespace?(body_node)
54
46
  return false unless body_node
55
47
 
@@ -77,8 +69,6 @@ module RuboCop
77
69
  end
78
70
 
79
71
  def preceding_comments(node, ast_with_comments)
80
- return [] unless node && ast_with_comments
81
-
82
72
  ast_with_comments[node].select { |c| c.loc.line < node.loc.line }
83
73
  end
84
74
 
@@ -93,7 +83,7 @@ module RuboCop
93
83
  # proceeds to check its ancestors for :nodoc: all.
94
84
  # Note: How end-of-line comments are associated with code changed in
95
85
  # parser-2.2.0.4.
96
- def nodoc?(node, ast_with_comments, require_all = false)
86
+ def nodoc_comment?(node, ast_with_comments, require_all = false)
97
87
  return false unless node
98
88
  nodoc_node = node.children.first
99
89
  return false unless nodoc_node
@@ -104,7 +94,7 @@ module RuboCop
104
94
  return true if comment.text =~ regex
105
95
  end
106
96
 
107
- nodoc?(node.ancestors.first, ast_with_comments, true)
97
+ nodoc_comment?(node.ancestors.first, ast_with_comments, true)
108
98
  end
109
99
  end
110
100
  end
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Cop
6
6
  module Style
7
7
  # This cop looks for inject / reduce calls where the passed in object is
8
- # returned at the end and so could be replace by each_with_object without
8
+ # returned at the end and so could be replaced by each_with_object without
9
9
  # the need to return the object at the end.
10
10
  #
11
11
  # However, we can't replace with each_with_object if the accumulator
@@ -87,7 +87,7 @@ module RuboCop
87
87
  return unless rhs
88
88
 
89
89
  end_config = config.for_cop('Lint/EndAlignment')
90
- style = end_config['Enabled'] ? end_config['AlignWith'] : 'keyword'
90
+ style = end_config['AlignWith'] || 'keyword'
91
91
  base = variable_alignment?(node.loc, rhs, style.to_sym) ? node : rhs
92
92
 
93
93
  return if rhs.type != :if
@@ -99,7 +99,7 @@ module RuboCop
99
99
  def check_alignment(base_range, else_range)
100
100
  return unless begins_its_line?(else_range)
101
101
 
102
- @column_delta = base_range.column - else_range.column
102
+ @column_delta = effective_column(base_range) - else_range.column
103
103
  return if @column_delta == 0
104
104
 
105
105
  add_offense(else_range, else_range,
@@ -40,7 +40,7 @@ module RuboCop
40
40
  corrector.insert_before(range, "#{encoding}\n")
41
41
  end
42
42
  else
43
- fail "#{encoding} does not match #{ENCODING_PATTERN}"
43
+ raise "#{encoding} does not match #{ENCODING_PATTERN}"
44
44
  end
45
45
  end
46
46
 
@@ -86,7 +86,7 @@ module RuboCop
86
86
  if source.include?("\n")
87
87
  previous_code_line(range.line + source.count("\n") + 1) =~ /\S/
88
88
  else
89
- range.column
89
+ display_column(range)
90
90
  end
91
91
  end
92
92
 
@@ -11,10 +11,9 @@ module RuboCop
11
11
  # comment. The frozen string literal comment is only valid in Ruby 2.3+.
12
12
  class FrozenStringLiteralComment < Cop
13
13
  include ConfigurableEnforcedStyle
14
+ include FrozenStringLiteral
14
15
 
15
16
  MSG = 'Missing frozen string literal comment.'.freeze
16
- FROZEN_STRING_LITERAL = '# frozen_string_literal:'.freeze
17
- FROZEN_STRING_LITERAL_ENABLED = '# frozen_string_literal: true'.freeze
18
17
  SHEBANG = '#!'.freeze
19
18
 
20
19
  def_node_matcher :frozen_strings, '{(send {dstr str} :<< ...)
@@ -30,8 +29,8 @@ module RuboCop
30
29
  end
31
30
 
32
31
  def on_send(node)
33
- return if target_ruby_version < 2.3 && RUBY_VERSION < '2.3.0'
34
32
  return unless style == :when_needed
33
+ return if target_ruby_version < 2.3
35
34
  return if frozen_string_literal_comment_exists?(processed_source)
36
35
 
37
36
  frozen_strings(node) { offense(processed_source) }
@@ -52,15 +51,6 @@ module RuboCop
52
51
 
53
52
  private
54
53
 
55
- def frozen_string_literal_comment_exists?(processed_source)
56
- first_three_lines =
57
- [processed_source[0], processed_source[1], processed_source[2]]
58
- first_three_lines.compact!
59
- first_three_lines.any? do |line|
60
- line.start_with?(FROZEN_STRING_LITERAL)
61
- end
62
- end
63
-
64
54
  def last_special_comment(processed_source)
65
55
  token_number = 0
66
56
  if processed_source.tokens[token_number].text.start_with?(SHEBANG)
@@ -112,8 +112,9 @@ module RuboCop
112
112
  def line_too_long?(node, body, keyword, condition)
113
113
  max = config.for_cop('Metrics/LineLength')['Max'] || 80
114
114
  indent = node.loc.column
115
+ source = body && body.source || ''
115
116
  # 2 is for spaces on left and right of keyword
116
- indent + (body.source + keyword + condition.source).length + 2 > max
117
+ indent + (source + keyword + condition.source).length + 2 > max
117
118
  end
118
119
  end
119
120
  end
@@ -24,18 +24,11 @@ module RuboCop
24
24
  return if modifier_if?(node)
25
25
  return if elsif?(node)
26
26
  return if if_else?(node)
27
- return if chained?(node)
27
+ return if node.chained?
28
28
  return unless fit_within_line_as_modifier_form?(node)
29
29
  add_offense(node, :keyword, message(node.loc.keyword.source))
30
30
  end
31
31
 
32
- def chained?(node)
33
- # Don't register offense for `if ... end.method`
34
- return false if node.parent.nil? || !node.parent.send_type?
35
- receiver = node.parent.children[0]
36
- node.equal?(receiver)
37
- end
38
-
39
32
  def parenthesize?(node)
40
33
  # Parenthesize corrected expression if changing to modifier-if form
41
34
  # would change the meaning of the parent expression
@@ -34,7 +34,7 @@ module RuboCop
34
34
  return unless node.loc.operator
35
35
  return if node.loc.operator.line == rhs.loc.line
36
36
 
37
- base = node.source_range.column
37
+ base = display_column(node.source_range)
38
38
  check_alignment([rhs], base + configured_indentation_width)
39
39
  end
40
40
  end
@@ -89,11 +89,7 @@ module RuboCop
89
89
  *_, body = *args.first
90
90
 
91
91
  def_end_config = config.for_cop('Lint/DefEndAlignment')
92
- style = if def_end_config['Enabled']
93
- def_end_config['AlignWith']
94
- else
95
- 'start_of_line'
96
- end
92
+ style = def_end_config['AlignWith'] || 'start_of_line'
97
93
  base = style == 'def' ? args.first : node
98
94
 
99
95
  check_indentation(base.source_range, body)
@@ -174,7 +170,7 @@ module RuboCop
174
170
  return unless rhs
175
171
 
176
172
  end_config = config.for_cop('Lint/EndAlignment')
177
- style = end_config['Enabled'] ? end_config['AlignWith'] : 'keyword'
173
+ style = end_config['AlignWith'] || 'keyword'
178
174
  base = variable_alignment?(node.loc, rhs, style.to_sym) ? node : rhs
179
175
 
180
176
  case rhs.type
@@ -202,7 +198,7 @@ module RuboCop
202
198
  def check_indentation(base_loc, body_node, style = 'normal')
203
199
  return unless indentation_to_check?(base_loc, body_node)
204
200
 
205
- indentation = body_node.loc.column - base_loc.column
201
+ indentation = body_node.loc.column - effective_column(base_loc)
206
202
  @column_delta = configured_indentation_width - indentation
207
203
  return if @column_delta == 0
208
204
 
@@ -19,6 +19,7 @@ module RuboCop
19
19
  return unless args.empty? && node.loc.begin
20
20
  return if same_name_assignment?(node)
21
21
  return if lambda_call_syntax?(node)
22
+ return if node.keyword_not?
22
23
 
23
24
  add_offense(node, :begin)
24
25
  end
@@ -35,7 +36,7 @@ module RuboCop
35
36
  def same_name_assignment?(node)
36
37
  _receiver, method_name, *_args = *node
37
38
 
38
- node.each_ancestor(ASGN_NODES).any? do |asgn_node|
39
+ node.each_ancestor(*ASGN_NODES).any? do |asgn_node|
39
40
  if asgn_node.masgn_type?
40
41
  mlhs_node, _mrhs_node = *asgn_node
41
42
  asgn_node = mlhs_node.children[node.sibling_index]
@@ -69,7 +69,7 @@ module RuboCop
69
69
  end
70
70
 
71
71
  def arguments?(args)
72
- args.children.size > 0
72
+ !args.children.empty?
73
73
  end
74
74
 
75
75
  def parentheses?(args)
@@ -38,6 +38,8 @@ module RuboCop
38
38
  # :b
39
39
  # ]
40
40
  class MultilineArrayBraceLayout < Cop
41
+ include MultilineLiteralBraceLayout
42
+
41
43
  SAME_LINE_MESSAGE = 'Closing array brace must be on the same line as ' \
42
44
  'the last array element when opening brace is on the same line as ' \
43
45
  'the first array element.'.freeze
@@ -47,47 +49,7 @@ module RuboCop
47
49
  'from the first array element.'.freeze
48
50
 
49
51
  def on_array(node)
50
- return unless node.loc.begin # Ignore implicit arrays.
51
- return if node.children.empty? # Ignore empty arrays.
52
-
53
- if opening_brace_on_same_line?(node)
54
- return if closing_brace_on_same_line?(node)
55
-
56
- add_offense(node, :expression, SAME_LINE_MESSAGE)
57
- else
58
- return unless closing_brace_on_same_line?(node)
59
-
60
- add_offense(node, :expression, NEW_LINE_MESSAGE)
61
- end
62
- end
63
-
64
- def autocorrect(node)
65
- if closing_brace_on_same_line?(node)
66
- lambda do |corrector|
67
- corrector.insert_before(node.loc.end, "\n".freeze)
68
- end
69
- else
70
- range = Parser::Source::Range.new(
71
- node.source_range.source_buffer,
72
- node.children.last.source_range.end_pos,
73
- node.loc.end.begin_pos)
74
-
75
- ->(corrector) { corrector.remove(range) }
76
- end
77
- end
78
-
79
- private
80
-
81
- # This method depends on the fact that we have guarded
82
- # against implicit and empty arrays.
83
- def opening_brace_on_same_line?(node)
84
- node.loc.begin.line == node.children.first.loc.first_line
85
- end
86
-
87
- # This method depends on the fact that we have guarded
88
- # against implicit and empty arrays.
89
- def closing_brace_on_same_line?(node)
90
- node.loc.end.line == node.children.last.loc.last_line
52
+ check_brace_layout(node)
91
53
  end
92
54
  end
93
55
  end