rubocop 0.59.2 → 0.60.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +3 -2
  3. data/config/default.yml +2960 -552
  4. data/lib/rubocop.rb +1 -0
  5. data/lib/rubocop/ast/builder.rb +29 -29
  6. data/lib/rubocop/ast/node.rb +29 -25
  7. data/lib/rubocop/ast/node/args_node.rb +1 -1
  8. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +1 -1
  9. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +26 -0
  10. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +5 -1
  11. data/lib/rubocop/ast/node/pair_node.rb +8 -1
  12. data/lib/rubocop/ast/node/str_node.rb +1 -1
  13. data/lib/rubocop/cached_data.rb +2 -2
  14. data/lib/rubocop/config.rb +1 -1
  15. data/lib/rubocop/config_loader.rb +8 -0
  16. data/lib/rubocop/cop/autocorrect_logic.rb +7 -1
  17. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
  18. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -1
  19. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -1
  20. data/lib/rubocop/cop/generator.rb +10 -3
  21. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  22. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +1 -1
  23. data/lib/rubocop/cop/layout/align_hash.rb +9 -1
  24. data/lib/rubocop/cop/layout/block_end_newline.rb +2 -4
  25. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +7 -7
  26. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  27. data/lib/rubocop/cop/layout/dot_position.rb +2 -2
  28. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  29. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +1 -2
  30. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  31. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +25 -25
  32. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +1 -1
  34. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -1
  35. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  36. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
  37. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +1 -1
  38. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +1 -1
  39. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  40. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  41. data/lib/rubocop/cop/layout/indent_hash.rb +1 -1
  42. data/lib/rubocop/cop/layout/indent_heredoc.rb +2 -2
  43. data/lib/rubocop/cop/layout/indentation_consistency.rb +1 -1
  44. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  45. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  46. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +1 -1
  47. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
  48. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +84 -43
  49. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  50. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  51. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -2
  52. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +1 -1
  53. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +2 -2
  54. data/lib/rubocop/cop/lint/ambiguous_operator.rb +5 -5
  55. data/lib/rubocop/cop/lint/assignment_in_condition.rb +10 -20
  56. data/lib/rubocop/cop/lint/ensure_return.rb +3 -0
  57. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +3 -3
  58. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  59. data/lib/rubocop/cop/lint/percent_string_array.rb +2 -2
  60. data/lib/rubocop/cop/lint/percent_symbol_array.rb +10 -7
  61. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +3 -4
  62. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -2
  63. data/lib/rubocop/cop/lint/syntax.rb +3 -2
  64. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +3 -3
  65. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -7
  66. data/lib/rubocop/cop/metrics/abc_size.rb +1 -17
  67. data/lib/rubocop/cop/metrics/line_length.rb +14 -10
  68. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +45 -0
  69. data/lib/rubocop/cop/mixin/check_assignment.rb +12 -6
  70. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -1
  71. data/lib/rubocop/cop/mixin/configurable_formatting.rb +0 -2
  72. data/lib/rubocop/cop/mixin/configurable_max.rb +4 -2
  73. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  74. data/lib/rubocop/cop/mixin/configurable_numbering.rb +2 -2
  75. data/lib/rubocop/cop/mixin/hash_alignment.rb +32 -5
  76. data/lib/rubocop/cop/mixin/heredoc.rb +1 -1
  77. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -4
  78. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  79. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -0
  80. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  81. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  82. data/lib/rubocop/cop/naming/constant_name.rb +1 -1
  83. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  84. data/lib/rubocop/cop/naming/method_name.rb +2 -0
  85. data/lib/rubocop/cop/naming/variable_number.rb +1 -1
  86. data/lib/rubocop/cop/offense.rb +1 -1
  87. data/lib/rubocop/cop/performance/regexp_match.rb +1 -1
  88. data/lib/rubocop/cop/performance/sample.rb +3 -2
  89. data/lib/rubocop/cop/performance/start_with.rb +1 -1
  90. data/lib/rubocop/cop/performance/string_replacement.rb +1 -1
  91. data/lib/rubocop/cop/rails/date.rb +8 -8
  92. data/lib/rubocop/cop/rails/dynamic_find_by.rb +1 -1
  93. data/lib/rubocop/cop/rails/exit.rb +8 -9
  94. data/lib/rubocop/cop/rails/output_safety.rb +3 -3
  95. data/lib/rubocop/cop/rails/read_write_attribute.rb +5 -4
  96. data/lib/rubocop/cop/rails/refute_methods.rb +13 -13
  97. data/lib/rubocop/cop/rails/reversible_migration.rb +2 -1
  98. data/lib/rubocop/cop/rails/skips_model_validations.rb +17 -0
  99. data/lib/rubocop/cop/registry.rb +11 -2
  100. data/lib/rubocop/cop/style/and_or.rb +3 -3
  101. data/lib/rubocop/cop/style/collection_methods.rb +26 -0
  102. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  103. data/lib/rubocop/cop/style/encoding.rb +1 -1
  104. data/lib/rubocop/cop/style/even_odd.rb +2 -2
  105. data/lib/rubocop/cop/style/for.rb +3 -3
  106. data/lib/rubocop/cop/style/global_vars.rb +1 -1
  107. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  108. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -13
  109. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  110. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  111. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +4 -7
  112. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  113. data/lib/rubocop/cop/style/module_function.rb +1 -1
  114. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  115. data/lib/rubocop/cop/style/mutable_constant.rb +15 -1
  116. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  117. data/lib/rubocop/cop/style/not.rb +2 -1
  118. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +6 -6
  119. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  120. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  121. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  122. data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -1
  123. data/lib/rubocop/cop/style/proc.rb +1 -1
  124. data/lib/rubocop/cop/style/redundant_freeze.rb +10 -0
  125. data/lib/rubocop/cop/style/redundant_parentheses.rb +6 -2
  126. data/lib/rubocop/cop/style/redundant_self.rb +1 -1
  127. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  128. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  129. data/lib/rubocop/cop/style/ternary_parentheses.rb +4 -3
  130. data/lib/rubocop/cop/style/unneeded_condition.rb +2 -2
  131. data/lib/rubocop/cop/style/unneeded_percent_q.rb +2 -2
  132. data/lib/rubocop/cop/style/unpack_first.rb +1 -1
  133. data/lib/rubocop/cop/team.rb +3 -2
  134. data/lib/rubocop/cop/util.rb +2 -22
  135. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  136. data/lib/rubocop/cop/variable_force/variable.rb +3 -4
  137. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  138. data/lib/rubocop/formatter/base_formatter.rb +3 -3
  139. data/lib/rubocop/formatter/disabled_config_formatter.rb +16 -1
  140. data/lib/rubocop/formatter/formatter_set.rb +14 -14
  141. data/lib/rubocop/formatter/html_formatter.rb +4 -4
  142. data/lib/rubocop/formatter/json_formatter.rb +13 -13
  143. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -4
  144. data/lib/rubocop/magic_comment.rb +4 -4
  145. data/lib/rubocop/node_pattern.rb +17 -17
  146. data/lib/rubocop/options.rb +93 -82
  147. data/lib/rubocop/result_cache.rb +9 -1
  148. data/lib/rubocop/rspec/expect_offense.rb +2 -2
  149. data/lib/rubocop/rspec/shared_contexts.rb +11 -11
  150. data/lib/rubocop/rspec/shared_examples.rb +4 -4
  151. data/lib/rubocop/string_interpreter.rb +1 -1
  152. data/lib/rubocop/version.rb +1 -1
  153. metadata +6 -13
  154. data/config/disabled.yml +0 -161
  155. data/config/enabled.yml +0 -2092
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks the indentation of hanging closing parentheses in
6
+ # This cop checks the indentation of hanging closing parentheses in
7
7
  # method calls, method definitions, and grouped expressions. A hanging
8
8
  # closing parenthesis means `)` preceded by a line break.
9
9
  #
@@ -116,9 +116,9 @@ module RuboCop
116
116
 
117
117
  add_offense(right_paren,
118
118
  location: right_paren,
119
- message: message(correct_column,
120
- left_paren,
121
- right_paren))
119
+ message: message(correct_column,
120
+ left_paren,
121
+ right_paren))
122
122
  end
123
123
 
124
124
  def check_for_no_elements(node)
@@ -135,9 +135,9 @@ module RuboCop
135
135
  correct_column = candidates.first
136
136
  add_offense(right_paren,
137
137
  location: right_paren,
138
- message: message(correct_column,
139
- left_paren,
140
- right_paren))
138
+ message: message(correct_column,
139
+ left_paren,
140
+ right_paren))
141
141
  end
142
142
 
143
143
  def expected_column(left_paren, elements)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks the indentation of comments.
6
+ # This cop checks the indentation of comments.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -8,7 +8,7 @@ module RuboCop
8
8
  # @example EnforcedStyle: leading (default)
9
9
  # # bad
10
10
  # something.
11
- # mehod
11
+ # method
12
12
  #
13
13
  # # good
14
14
  # something
@@ -21,7 +21,7 @@ module RuboCop
21
21
  #
22
22
  # # good
23
23
  # something.
24
- # mehod
24
+ # method
25
25
  class DotPosition < Cop
26
26
  include ConfigurableEnforcedStyle
27
27
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks the alignment of else keywords. Normally they should
6
+ # This cop checks the alignment of else keywords. Normally they should
7
7
  # be aligned with an if/unless/while/until/begin/def keyword, but there
8
8
  # are special cases when they should follow the same rules as the
9
9
  # alignment of end.
@@ -24,12 +24,11 @@ module RuboCop
24
24
  include RangeHelp
25
25
 
26
26
  MSG = 'Add an empty line after magic comments.'.freeze
27
- BLANK_LINE = /\A\s*\z/
28
27
 
29
28
  def investigate(source)
30
29
  return unless source.ast &&
31
30
  (last_magic_comment = last_magic_comment(source))
32
- return if source[last_magic_comment.loc.line] =~ BLANK_LINE
31
+ return if source[last_magic_comment.loc.line].strip.empty?
33
32
 
34
33
  offending_range =
35
34
  source_range(source.buffer, last_magic_comment.loc.line + 1, 0)
@@ -5,7 +5,7 @@ require 'set'
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Layout
8
- # This cops checks for two or more consecutive blank lines.
8
+ # This cop checks for two or more consecutive blank lines.
9
9
  #
10
10
  # @example
11
11
  #
@@ -32,21 +32,21 @@ module RuboCop
32
32
  def on_class(node)
33
33
  _name, superclass, _body = *node
34
34
 
35
- @class_or_module_def_line = if superclass
36
- superclass.first_line
37
- else
38
- node.source_range.first_line
39
- end
35
+ @class_or_module_def = superclass || node.source_range
40
36
  end
41
37
 
42
38
  def on_module(node)
43
- @class_or_module_def_line = node.source_range.first_line
39
+ @class_or_module_def = node.source_range
44
40
  end
45
41
 
46
42
  def on_sclass(node)
47
43
  self_node, _body = *node
48
44
 
49
- @class_or_module_def_line = self_node.source_range.first_line
45
+ @class_or_module_def = self_node.source_range
46
+ end
47
+
48
+ def on_block(node)
49
+ @block_line = node.source_range.first_line
50
50
  end
51
51
 
52
52
  def on_send(node)
@@ -59,15 +59,13 @@ module RuboCop
59
59
 
60
60
  def autocorrect(node)
61
61
  lambda do |corrector|
62
- send_line = node.first_line
63
- next_line = processed_source[send_line]
64
62
  line = range_by_whole_lines(node.source_range)
65
63
 
66
- unless previous_line_empty?(send_line)
64
+ unless previous_line_empty?(node.first_line)
67
65
  corrector.insert_before(line, "\n")
68
66
  end
69
67
 
70
- unless next_line_empty?(next_line)
68
+ unless next_line_empty?(node.last_line)
71
69
  corrector.insert_after(line, "\n")
72
70
  end
73
71
  end
@@ -85,42 +83,44 @@ module RuboCop
85
83
  previous_line = previous_line_ignoring_comments(processed_source,
86
84
  send_line)
87
85
 
88
- block_start?(previous_line) ||
86
+ block_start?(send_line) ||
89
87
  class_def?(send_line) ||
90
88
  previous_line.blank?
91
89
  end
92
90
 
93
- def next_line_empty?(next_line)
94
- body_end?(next_line) || next_line.blank?
91
+ def next_line_empty?(last_send_line)
92
+ next_line = processed_source[last_send_line]
93
+
94
+ body_end?(last_send_line) || next_line.blank?
95
95
  end
96
96
 
97
97
  def empty_lines_around?(node)
98
- send_line = node.first_line
99
-
100
- next_line = processed_source[send_line]
101
-
102
- previous_line_empty?(send_line) && next_line_empty?(next_line)
98
+ previous_line_empty?(node.first_line) &&
99
+ next_line_empty?(node.last_line)
103
100
  end
104
101
 
105
102
  def class_def?(line)
106
- return false unless @class_or_module_def_line
103
+ return false unless @class_or_module_def
107
104
 
108
- line == @class_or_module_def_line + 1
105
+ line == @class_or_module_def.first_line + 1
109
106
  end
110
107
 
111
108
  def block_start?(line)
112
- line.match(/ (do|{)( \|.*?\|)?\s?$/)
109
+ return false unless @block_line
110
+
111
+ line == @block_line + 1
113
112
  end
114
113
 
115
114
  def body_end?(line)
116
- line =~ /^\s*end\b/
115
+ return false unless @class_or_module_def
116
+
117
+ line == @class_or_module_def.last_line - 1
117
118
  end
118
119
 
119
120
  def message(node)
120
121
  send_line = node.first_line
121
- previous_line = processed_source[send_line - 2]
122
122
 
123
- if block_start?(previous_line) ||
123
+ if block_start?(send_line) ||
124
124
  class_def?(send_line)
125
125
  format(MSG_AFTER, modifier: node.loc.selector.source)
126
126
  else
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks if empty lines exist around the arguments
6
+ # This cop checks if empty lines exist around the arguments
7
7
  # of a method invocation.
8
8
  #
9
9
  # @example
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks if empty lines exist around the bodies of begin-end
6
+ # This cop checks if empty lines exist around the bodies of begin-end
7
7
  # blocks.
8
8
  #
9
9
  # @example
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks if empty lines around the bodies of blocks match
6
+ # This cop checks if empty lines around the bodies of blocks match
7
7
  # the configuration.
8
8
  #
9
9
  # @example EnforcedStyle: empty_lines
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks if empty lines around the bodies of classes match
6
+ # This cop checks if empty lines around the bodies of classes match
7
7
  # the configuration.
8
8
  #
9
9
  # @example EnforcedStyle: empty_lines
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks if empty lines exist around the bodies of `begin`
6
+ # This cop checks if empty lines exist around the bodies of `begin`
7
7
  # sections. This cop doesn't check empty lines at `begin` body
8
8
  # beginning/end and around method definition body.
9
9
  # `Style/EmptyLinesAroundBeginBody` or `Style/EmptyLinesAroundMethodBody`
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks if empty lines exist around the bodies of methods.
6
+ # This cop checks if empty lines exist around the bodies of methods.
7
7
  #
8
8
  # @example
9
9
  #
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks if empty lines around the bodies of modules match
6
+ # This cop checks if empty lines around the bodies of modules match
7
7
  # the configuration.
8
8
  #
9
9
  # @example EnforcedStyle: empty_lines
@@ -113,7 +113,7 @@ module RuboCop
113
113
  # assignment, we let rhs be the receiver of those method calls before
114
114
  # we check if it's an if/unless/while/until.
115
115
  return unless (rhs = first_part_of_call_chain(rhs))
116
- return unless CONDITIONAL_NODES.include?(rhs.type)
116
+ return unless rhs.conditional?
117
117
  return if rhs.if_type? && rhs.ternary?
118
118
 
119
119
  check_asgn_alignment(node, rhs)
@@ -168,7 +168,7 @@ module RuboCop
168
168
  text = base_range(send_node, arg_node).source.strip
169
169
  base = if text !~ /\n/ && special_inner_call_indentation?(send_node)
170
170
  "`#{text}`"
171
- elsif text.lines.reverse_each.first =~ /^\s*#/
171
+ elsif comment_line?(text.lines.reverse_each.first)
172
172
  'the start of the previous line (not counting the comment)'
173
173
  else
174
174
  'the start of the previous line'
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks the indentation of the first key in a hash literal
6
+ # This cop checks the indentation of the first key in a hash literal
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
  #
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks the indentation of the here document bodies. The bodies
6
+ # This cop checks the indentation of the here document bodies. The bodies
7
7
  # are indented one step.
8
8
  # In Ruby 2.3 or newer, squiggly heredocs (`<<~`) should be used. If you
9
9
  # use the older rubies, you should introduce some library to your project
@@ -88,7 +88,7 @@ module RuboCop
88
88
 
89
89
  def on_heredoc(node)
90
90
  body = heredoc_body(node)
91
- return if body =~ /\A\s*\z/
91
+ return if body.strip.empty?
92
92
 
93
93
  body_indent_level = indent_level(body)
94
94
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks for inconsistent indentation.
6
+ # This cop checks for inconsistent indentation.
7
7
  #
8
8
  # The difference between `rails` and `normal` is that the `rails` style
9
9
  # prescribes that in classes and modules the `protected` and `private`
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks for indentation that doesn't use the specified number
6
+ # This cop checks for indentation that doesn't use the specified number
7
7
  # of spaces.
8
8
  #
9
9
  # See also the IndentationConsistency cop which is the companion to this
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cops checks for indentation of the first non-blank non-comment
6
+ # This cop checks for indentation of the first non-blank non-comment
7
7
  # line in a file.
8
8
  #
9
9
  # @example
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Layout
6
6
  # This cop checks that the closing brace in an array literal is either
7
- # on the same line as the last array element, or a new line.
7
+ # on the same line as the last array element or on a new line.
8
8
  #
9
9
  # When using the `symmetrical` (default) style:
10
10
  #
@@ -61,7 +61,7 @@ module RuboCop
61
61
  private
62
62
 
63
63
  def relevant_node?(node)
64
- return false if node.unary_operation?
64
+ return false if node.send_type? && node.unary_operation?
65
65
 
66
66
  !node.loc.dot # Don't check method calls with dot operator.
67
67
  end
@@ -29,6 +29,7 @@ module RuboCop
29
29
  '%<begin_loc_line>d, %<begin_loc_column>d.'.freeze
30
30
  ANCESTOR_TYPES = %i[kwbegin def defs class module].freeze
31
31
  RUBY_2_5_ANCESTOR_TYPES = (ANCESTOR_TYPES + [:block]).freeze
32
+ ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS = %i[def defs].freeze
32
33
 
33
34
  def on_resbody(node)
34
35
  check(node) unless modifier?(node)
@@ -38,6 +39,18 @@ module RuboCop
38
39
  check(node)
39
40
  end
40
41
 
42
+ def autocorrect(node)
43
+ whitespace = whitespace_range(node)
44
+ # Some inline node is sitting before current node.
45
+ return nil unless whitespace.source.strip.empty?
46
+
47
+ alignment_node = alignment_node(node)
48
+ return false if alignment_node.nil?
49
+
50
+ new_column = alignment_node.loc.column
51
+ ->(corrector) { corrector.replace(whitespace, ' ' * new_column) }
52
+ end
53
+
41
54
  def investigate(processed_source)
42
55
  @modifier_locations =
43
56
  processed_source.tokens.each_with_object([]) do |token, locations|
@@ -47,50 +60,88 @@ module RuboCop
47
60
  end
48
61
  end
49
62
 
50
- def autocorrect(node)
51
- whitespace = whitespace_range(node)
52
- return false unless whitespace.source.strip.empty?
63
+ private
53
64
 
54
- new_column = ancestor_node(node).loc.end.column
55
- ->(corrector) { corrector.replace(whitespace, ' ' * new_column) }
65
+ # Check alignment of node with rescue or ensure modifiers.
66
+
67
+ def check(node)
68
+ alignment_node = alignment_node(node)
69
+ return if alignment_node.nil?
70
+
71
+ alignment_loc = alignment_node.loc.expression
72
+ kw_loc = node.loc.keyword
73
+
74
+ return if
75
+ alignment_loc.column == kw_loc.column ||
76
+ alignment_loc.line == kw_loc.line
77
+
78
+ add_offense(
79
+ node,
80
+ location: kw_loc,
81
+ message: format_message(alignment_node, alignment_loc, kw_loc)
82
+ )
56
83
  end
57
84
 
58
- private
85
+ def format_message(alignment_node, alignment_loc, kw_loc)
86
+ format(
87
+ MSG,
88
+ kw_loc: kw_loc.source,
89
+ kw_loc_line: kw_loc.line,
90
+ kw_loc_column: kw_loc.column,
91
+ beginning: alignment_source(alignment_node, alignment_loc),
92
+ begin_loc_line: alignment_loc.line,
93
+ begin_loc_column: alignment_loc.column
94
+ )
95
+ end
59
96
 
60
- def check(node)
97
+ def alignment_source(node, starting_loc)
98
+ ending_loc =
99
+ case node.type
100
+ when :block, :kwbegin
101
+ node.loc.begin
102
+ when :def, :defs, :class, :module
103
+ node.loc.name
104
+ else
105
+ # It is a wrapper with access modifier.
106
+ node.child_nodes.first.loc.name
107
+ end
108
+
109
+ range_between(starting_loc.begin_pos, ending_loc.end_pos).source
110
+ end
111
+
112
+ # We will use ancestor or wrapper with access modifier.
113
+
114
+ def alignment_node(node)
61
115
  ancestor_node = ancestor_node(node)
62
- alignment_loc = ancestor_node.loc.expression
63
- kw_loc = node.loc.keyword
116
+ return nil if ancestor_node.nil?
64
117
 
65
- return if alignment_loc.column == kw_loc.column
66
- return if alignment_loc.line == kw_loc.line
118
+ access_modifier_node = access_modifier_node(ancestor_node)
119
+ return ancestor_node if access_modifier_node.nil?
67
120
 
68
- add_offense(node,
69
- location: kw_loc,
70
- message: format_message(kw_loc,
71
- alignment_loc,
72
- ancestor_node))
121
+ access_modifier_node
73
122
  end
74
123
 
75
- def format_message(kw_loc, alignment_loc, ancestor_node)
76
- format(MSG,
77
- kw_loc: kw_loc.source,
78
- kw_loc_line: kw_loc.line,
79
- kw_loc_column: kw_loc.column,
80
- beginning: alignment_source(ancestor_node),
81
- begin_loc_line: alignment_loc.line,
82
- begin_loc_column: alignment_loc.column)
124
+ def ancestor_node(node)
125
+ ancestor_types =
126
+ if target_ruby_version >= 2.5
127
+ RUBY_2_5_ANCESTOR_TYPES
128
+ else
129
+ ANCESTOR_TYPES
130
+ end
131
+
132
+ node.each_ancestor(*ancestor_types).first
83
133
  end
84
134
 
85
- def alignment_source(node)
86
- ending = case node.type
87
- when :def, :defs, :class, :module
88
- node.loc.name
89
- when :block, :kwbegin
90
- node.loc.begin
91
- end
135
+ def access_modifier_node(node)
136
+ return nil unless
137
+ ANCESTOR_TYPES_WITH_ACCESS_MODIFIERS.include?(node.type)
138
+
139
+ access_modifier_node = node.ancestors.first
140
+ return nil unless
141
+ access_modifier_node.respond_to?(:access_modifier?) &&
142
+ access_modifier_node.access_modifier?
92
143
 
93
- range_between(node.loc.expression.begin_pos, ending.end_pos).source
144
+ access_modifier_node
94
145
  end
95
146
 
96
147
  def modifier?(node)
@@ -100,21 +151,11 @@ module RuboCop
100
151
  end
101
152
 
102
153
  def whitespace_range(node)
103
- begin_pos = node.loc.keyword.begin_pos
154
+ begin_pos = node.loc.keyword.begin_pos
104
155
  current_column = node.loc.keyword.column
105
156
 
106
157
  range_between(begin_pos - current_column, begin_pos)
107
158
  end
108
-
109
- def ancestor_node(node)
110
- types = if target_ruby_version >= 2.5
111
- RUBY_2_5_ANCESTOR_TYPES
112
- else
113
- ANCESTOR_TYPES
114
- end
115
-
116
- node.each_ancestor(*types).first
117
- end
118
159
  end
119
160
  end
120
161
  end