rubocop 0.58.2 → 0.59.0

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 (211) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +22 -7
  4. data/config/disabled.yml +33 -4
  5. data/config/enabled.yml +4 -11
  6. data/lib/rubocop.rb +5 -0
  7. data/lib/rubocop/ast/builder.rb +1 -0
  8. data/lib/rubocop/ast/node.rb +11 -33
  9. data/lib/rubocop/ast/node/block_node.rb +8 -1
  10. data/lib/rubocop/ast/node/defined_node.rb +13 -0
  11. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +16 -5
  12. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +21 -0
  13. data/lib/rubocop/ast/node/send_node.rb +3 -12
  14. data/lib/rubocop/ast/traversal.rb +10 -0
  15. data/lib/rubocop/cli.rb +4 -1
  16. data/lib/rubocop/config.rb +21 -5
  17. data/lib/rubocop/config_loader.rb +2 -0
  18. data/lib/rubocop/config_loader_resolver.rb +3 -1
  19. data/lib/rubocop/cop/autocorrect_logic.rb +1 -0
  20. data/lib/rubocop/cop/bundler/gem_comment.rb +64 -0
  21. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -0
  22. data/lib/rubocop/cop/commissioner.rb +2 -0
  23. data/lib/rubocop/cop/cop.rb +3 -0
  24. data/lib/rubocop/cop/corrector.rb +2 -0
  25. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -0
  26. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  27. data/lib/rubocop/cop/correctors/space_corrector.rb +2 -0
  28. data/lib/rubocop/cop/force.rb +1 -0
  29. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -0
  30. data/lib/rubocop/cop/generator.rb +1 -0
  31. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -0
  32. data/lib/rubocop/cop/layout/class_structure.rb +4 -0
  33. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +5 -4
  34. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +35 -0
  35. data/lib/rubocop/cop/layout/else_alignment.rb +1 -0
  36. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -0
  37. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +1 -0
  38. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +5 -2
  39. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -0
  40. data/lib/rubocop/cop/layout/end_of_line.rb +1 -0
  41. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -0
  42. data/lib/rubocop/cop/layout/indent_array.rb +1 -0
  43. data/lib/rubocop/cop/layout/indent_heredoc.rb +3 -0
  44. data/lib/rubocop/cop/layout/indentation_width.rb +2 -0
  45. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -0
  46. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -1
  47. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +34 -11
  48. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -0
  49. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  50. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -1
  51. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -0
  52. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -0
  53. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +16 -8
  54. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +2 -0
  55. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  56. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -0
  57. data/lib/rubocop/cop/layout/tab.rb +1 -0
  58. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -0
  59. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -0
  60. data/lib/rubocop/cop/lint/duplicate_methods.rb +9 -1
  61. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -0
  62. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -0
  63. data/lib/rubocop/cop/lint/interpolation_check.rb +2 -0
  64. data/lib/rubocop/cop/lint/literal_as_condition.rb +3 -6
  65. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -0
  66. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -0
  67. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -0
  68. data/lib/rubocop/cop/lint/rescue_type.rb +1 -0
  69. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +2 -2
  70. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -0
  71. data/lib/rubocop/cop/lint/script_permission.rb +1 -0
  72. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -0
  73. data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -0
  74. data/lib/rubocop/cop/lint/unneeded_cop_disable_directive.rb +1 -0
  75. data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +1 -0
  76. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -0
  77. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
  78. data/lib/rubocop/cop/lint/unreachable_code.rb +2 -0
  79. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -0
  80. data/lib/rubocop/cop/lint/useless_setter_call.rb +3 -0
  81. data/lib/rubocop/cop/lint/void.rb +1 -0
  82. data/lib/rubocop/cop/message_annotator.rb +1 -0
  83. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  84. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -0
  85. data/lib/rubocop/cop/metrics/line_length.rb +6 -1
  86. data/lib/rubocop/cop/metrics/method_length.rb +1 -0
  87. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -0
  88. data/lib/rubocop/cop/mixin/classish_length.rb +1 -0
  89. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -0
  90. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  91. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -6
  92. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -0
  93. data/lib/rubocop/cop/mixin/ignored_methods.rb +19 -0
  94. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +25 -1
  95. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +5 -3
  96. data/lib/rubocop/cop/mixin/percent_literal.rb +2 -0
  97. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +2 -0
  98. data/lib/rubocop/cop/mixin/safe_assignment.rb +2 -1
  99. data/lib/rubocop/cop/mixin/statement_modifier.rb +6 -1
  100. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -0
  101. data/lib/rubocop/cop/mixin/surrounding_space.rb +4 -0
  102. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -0
  103. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +2 -0
  104. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -0
  105. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -0
  106. data/lib/rubocop/cop/naming/file_name.rb +4 -1
  107. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -0
  108. data/lib/rubocop/cop/naming/predicate_name.rb +1 -0
  109. data/lib/rubocop/cop/naming/uncommunicative_block_param_name.rb +1 -0
  110. data/lib/rubocop/cop/naming/uncommunicative_method_param_name.rb +1 -0
  111. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  112. data/lib/rubocop/cop/performance/case_when_splat.rb +11 -7
  113. data/lib/rubocop/cop/performance/casecmp.rb +33 -42
  114. data/lib/rubocop/cop/performance/chain_array_allocation.rb +77 -0
  115. data/lib/rubocop/cop/performance/compare_with_block.rb +3 -0
  116. data/lib/rubocop/cop/performance/regexp_match.rb +1 -0
  117. data/lib/rubocop/cop/performance/sample.rb +2 -0
  118. data/lib/rubocop/cop/performance/size.rb +8 -2
  119. data/lib/rubocop/cop/performance/string_replacement.rb +1 -0
  120. data/lib/rubocop/cop/rails/active_support_aliases.rb +1 -0
  121. data/lib/rubocop/cop/rails/bulk_change_table.rb +9 -2
  122. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +1 -0
  123. data/lib/rubocop/cop/rails/delegate.rb +7 -2
  124. data/lib/rubocop/cop/rails/dynamic_find_by.rb +1 -0
  125. data/lib/rubocop/cop/rails/find_each.rb +7 -2
  126. data/lib/rubocop/cop/rails/http_positional_arguments.rb +1 -1
  127. data/lib/rubocop/cop/rails/http_status.rb +2 -0
  128. data/lib/rubocop/cop/rails/inverse_of.rb +4 -0
  129. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +1 -0
  130. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -0
  131. data/lib/rubocop/cop/rails/reversible_migration.rb +1 -0
  132. data/lib/rubocop/cop/rails/save_bang.rb +189 -38
  133. data/lib/rubocop/cop/rails/time_zone.rb +1 -0
  134. data/lib/rubocop/cop/security/eval.rb +1 -0
  135. data/lib/rubocop/cop/security/json_load.rb +2 -2
  136. data/lib/rubocop/cop/security/open.rb +6 -3
  137. data/lib/rubocop/cop/severity.rb +1 -0
  138. data/lib/rubocop/cop/style/and_or.rb +3 -3
  139. data/lib/rubocop/cop/style/ascii_comments.rb +1 -0
  140. data/lib/rubocop/cop/style/block_delimiters.rb +2 -4
  141. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +2 -3
  142. data/lib/rubocop/cop/style/class_and_module_children.rb +3 -0
  143. data/lib/rubocop/cop/style/class_vars.rb +1 -1
  144. data/lib/rubocop/cop/style/colon_method_definition.rb +1 -0
  145. data/lib/rubocop/cop/style/commented_keyword.rb +2 -0
  146. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
  147. data/lib/rubocop/cop/style/copyright.rb +7 -2
  148. data/lib/rubocop/cop/style/date_time.rb +40 -7
  149. data/lib/rubocop/cop/style/double_negation.rb +1 -1
  150. data/lib/rubocop/cop/style/empty_case_condition.rb +8 -0
  151. data/lib/rubocop/cop/style/empty_else.rb +2 -0
  152. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -0
  153. data/lib/rubocop/cop/style/eval_with_location.rb +2 -0
  154. data/lib/rubocop/cop/style/for.rb +56 -10
  155. data/lib/rubocop/cop/style/format_string_token.rb +1 -1
  156. data/lib/rubocop/cop/style/if_with_semicolon.rb +1 -0
  157. data/lib/rubocop/cop/style/inverse_methods.rb +1 -0
  158. data/lib/rubocop/cop/style/lambda.rb +1 -0
  159. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -5
  160. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +3 -5
  161. data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -2
  162. data/lib/rubocop/cop/style/missing_else.rb +1 -0
  163. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -0
  164. data/lib/rubocop/cop/style/multiline_method_signature.rb +65 -0
  165. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -0
  166. data/lib/rubocop/cop/style/nil_comparison.rb +45 -5
  167. data/lib/rubocop/cop/style/not.rb +1 -1
  168. data/lib/rubocop/cop/style/numeric_predicate.rb +5 -0
  169. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  170. data/lib/rubocop/cop/style/or_assignment.rb +2 -0
  171. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  172. data/lib/rubocop/cop/style/random_with_offset.rb +1 -0
  173. data/lib/rubocop/cop/style/redundant_begin.rb +13 -0
  174. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -0
  175. data/lib/rubocop/cop/style/redundant_parentheses.rb +6 -1
  176. data/lib/rubocop/cop/style/redundant_return.rb +1 -0
  177. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -0
  178. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -0
  179. data/lib/rubocop/cop/style/safe_navigation.rb +4 -0
  180. data/lib/rubocop/cop/style/semicolon.rb +4 -0
  181. data/lib/rubocop/cop/style/signal_exception.rb +1 -0
  182. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  183. data/lib/rubocop/cop/style/symbol_proc.rb +1 -8
  184. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +1 -0
  185. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  186. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -0
  187. data/lib/rubocop/cop/style/unneeded_condition.rb +13 -2
  188. data/lib/rubocop/cop/style/unneeded_percent_q.rb +2 -0
  189. data/lib/rubocop/cop/style/word_array.rb +13 -1
  190. data/lib/rubocop/cop/team.rb +1 -0
  191. data/lib/rubocop/cop/variable_force.rb +5 -0
  192. data/lib/rubocop/cop/variable_force/assignment.rb +4 -0
  193. data/lib/rubocop/cop/variable_force/branch.rb +4 -0
  194. data/lib/rubocop/cop/variable_force/branchable.rb +2 -0
  195. data/lib/rubocop/cop/variable_force/scope.rb +6 -0
  196. data/lib/rubocop/cop/variable_force/variable_table.rb +1 -0
  197. data/lib/rubocop/file_finder.rb +2 -0
  198. data/lib/rubocop/formatter/disabled_config_formatter.rb +4 -4
  199. data/lib/rubocop/formatter/file_list_formatter.rb +1 -0
  200. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -0
  201. data/lib/rubocop/options.rb +16 -0
  202. data/lib/rubocop/path_util.rb +16 -1
  203. data/lib/rubocop/processed_source.rb +4 -0
  204. data/lib/rubocop/remote_config.rb +6 -1
  205. data/lib/rubocop/result_cache.rb +1 -0
  206. data/lib/rubocop/rspec/cop_helper.rb +3 -5
  207. data/lib/rubocop/rspec/shared_examples.rb +1 -9
  208. data/lib/rubocop/runner.rb +4 -0
  209. data/lib/rubocop/target_finder.rb +2 -0
  210. data/lib/rubocop/version.rb +1 -1
  211. metadata +7 -2
@@ -29,6 +29,7 @@ module RuboCop
29
29
  def run_hook(method_name, *args)
30
30
  cops.each do |cop|
31
31
  next unless cop.respond_to?(method_name)
32
+
32
33
  cop.send(method_name, *args)
33
34
  end
34
35
  end
@@ -61,6 +61,7 @@ module RuboCop
61
61
 
62
62
  def investigate(processed_source)
63
63
  return if processed_source.blank?
64
+
64
65
  dependency_declarations(processed_source.ast)
65
66
  .each_cons(2) do |previous, current|
66
67
  next unless consecutive_lines(previous, current)
@@ -203,6 +203,7 @@ module RuboCop
203
203
 
204
204
  def snake_case(camel_case_string)
205
205
  return 'rspec' if camel_case_string == 'RSpec'
206
+
206
207
  camel_case_string
207
208
  .gsub(/([^A-Z])([A-Z]+)/, '\1_\2')
208
209
  .gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2')
@@ -66,6 +66,7 @@ module RuboCop
66
66
 
67
67
  def check_body(body, node)
68
68
  return if body.nil? # Empty class etc.
69
+ return unless body.begin_type?
69
70
 
70
71
  modifiers = body.each_child_node(:send).select(&:access_modifier?)
71
72
  class_column = node.source_range.column
@@ -162,6 +162,7 @@ module RuboCop
162
162
  # @return String otherwise trying to {humanize_node} of the current node
163
163
  def classify(node)
164
164
  return node.to_s unless node.respond_to?(:type)
165
+
165
166
  case node.type
166
167
  when :block
167
168
  classify(node.send_node)
@@ -185,6 +186,7 @@ module RuboCop
185
186
  class_elements(class_node).each do |node|
186
187
  classification = classify(node)
187
188
  next if ignore?(classification)
189
+
188
190
  yield node, classification
189
191
  end
190
192
  end
@@ -192,6 +194,7 @@ module RuboCop
192
194
  def class_elements(class_node)
193
195
  *, class_def = class_node.children
194
196
  return [] unless class_def
197
+
195
198
  if class_def.def_type? || class_def.send_type?
196
199
  [class_def]
197
200
  else
@@ -241,6 +244,7 @@ module RuboCop
241
244
  method_name, = *node
242
245
  if node.def_type?
243
246
  return :initializer if method_name == :initialize
247
+
244
248
  return "#{node_visibility(node)}_methods"
245
249
  end
246
250
  HUMANIZED_NODE_TYPE[node.type] || node.type
@@ -79,10 +79,11 @@ module RuboCop
79
79
  end
80
80
 
81
81
  def argument_indentation_correct?(node)
82
- node.argument? &&
83
- opening_indentation(
84
- find_node_used_heredoc_argument(node.parent)
85
- ) == closing_indentation(node)
82
+ return unless node.argument? || node.chained?
83
+
84
+ opening_indentation(
85
+ find_node_used_heredoc_argument(node.parent)
86
+ ) == closing_indentation(node)
86
87
  end
87
88
 
88
89
  def contents_indentation(node)
@@ -95,6 +95,14 @@ module RuboCop
95
95
  private
96
96
 
97
97
  def check(node, elements)
98
+ if elements.empty?
99
+ check_for_no_elements(node)
100
+ else
101
+ check_for_elements(node, elements)
102
+ end
103
+ end
104
+
105
+ def check_for_elements(node, elements)
98
106
  left_paren = node.loc.begin
99
107
  right_paren = node.loc.end
100
108
 
@@ -113,6 +121,25 @@ module RuboCop
113
121
  right_paren))
114
122
  end
115
123
 
124
+ def check_for_no_elements(node)
125
+ left_paren = node.loc.begin
126
+ right_paren = node.loc.end
127
+ return unless right_paren && begins_its_line?(right_paren)
128
+
129
+ candidates = correct_column_candidates(node, left_paren)
130
+
131
+ return if candidates.include?(right_paren.column)
132
+
133
+ # Although there are multiple choices for a correct column,
134
+ # select the first one of candidates to determine a specification.
135
+ correct_column = candidates.first
136
+ add_offense(right_paren,
137
+ location: right_paren,
138
+ message: message(correct_column,
139
+ left_paren,
140
+ right_paren))
141
+ end
142
+
116
143
  def expected_column(left_paren, elements)
117
144
  if !line_break_after_left_paren?(left_paren, elements) &&
118
145
  all_elements_aligned?(elements)
@@ -140,6 +167,14 @@ module RuboCop
140
167
  .first_line
141
168
  end
142
169
 
170
+ def correct_column_candidates(node, left_paren)
171
+ [
172
+ processed_source.line_indentation(left_paren.line),
173
+ left_paren.column,
174
+ node.loc.column
175
+ ]
176
+ end
177
+
143
178
  def message(correct_column, left_paren, right_paren)
144
179
  if correct_column == left_paren.column
145
180
  MSG_ALIGN
@@ -120,6 +120,7 @@ module RuboCop
120
120
 
121
121
  @column_delta = effective_column(base_range) - else_range.column
122
122
  return if @column_delta.zero?
123
+
123
124
  message = format(
124
125
  MSG,
125
126
  else_range: else_range.source,
@@ -80,6 +80,7 @@ module RuboCop
80
80
 
81
81
  def def_node?(node)
82
82
  return unless node
83
+
83
84
  node.def_type? || node.defs_type?
84
85
  end
85
86
 
@@ -88,6 +89,7 @@ module RuboCop
88
89
  blank_start = lines.each_index.select { |i| lines[i].blank? }.max
89
90
  non_blank_end = lines.each_index.reject { |i| lines[i].blank? }.min
90
91
  return false if blank_start.nil? || non_blank_end.nil?
92
+
91
93
  blank_start > non_blank_end
92
94
  end
93
95
 
@@ -45,6 +45,7 @@ module RuboCop
45
45
 
46
46
  def on_send(node)
47
47
  return if node.single_line? || node.arguments.empty?
48
+
48
49
  extra_lines(node) { |range| add_offense(node, location: range) }
49
50
  end
50
51
 
@@ -70,8 +70,11 @@ module RuboCop
70
70
  KIND = 'class'.freeze
71
71
 
72
72
  def on_class(node)
73
- _name, _superclass, body = *node
74
- check(node, body)
73
+ _name, superclass, body = *node
74
+
75
+ adjusted_first_line = superclass.first_line if superclass
76
+
77
+ check(node, body, adjusted_first_line: adjusted_first_line)
75
78
  end
76
79
 
77
80
  def on_sclass(node)
@@ -104,6 +104,7 @@ module RuboCop
104
104
 
105
105
  def keyword_locations(node)
106
106
  return [] unless node
107
+
107
108
  case node.type
108
109
  when :rescue
109
110
  keyword_locations_in_rescue(node)
@@ -51,6 +51,7 @@ module RuboCop
51
51
 
52
52
  processed_source.raw_source.each_line.with_index do |line, index|
53
53
  break if index >= last_line
54
+
54
55
  msg = offense_message(line)
55
56
  next unless msg
56
57
  next if unimportant_missing_cr?(index, last_line, line)
@@ -89,6 +89,7 @@ module RuboCop
89
89
  message = format(MSG_UNALIGNED_ASGN, location: 'following')
90
90
  end
91
91
  return if aligned_assignment?(token.pos, assignment_line)
92
+
92
93
  add_offense(token.pos, location: token.pos, message: message)
93
94
  end
94
95
 
@@ -114,6 +114,7 @@ module RuboCop
114
114
  first_elem = array_node.values.first
115
115
  if first_elem
116
116
  return if first_elem.source_range.line == left_bracket.line
117
+
117
118
  check_first(first_elem, left_bracket, left_parenthesis, 0)
118
119
  end
119
120
 
@@ -100,6 +100,7 @@ module RuboCop
100
100
  end
101
101
 
102
102
  return if too_long_line?(node)
103
+
103
104
  add_offense(node, location: :heredoc_body)
104
105
  end
105
106
 
@@ -174,6 +175,7 @@ module RuboCop
174
175
 
175
176
  def too_long_line?(node)
176
177
  return false if config.for_cop('Metrics/LineLength')['AllowHeredoc']
178
+
177
179
  body = heredoc_body(node)
178
180
 
179
181
  expected_indent = base_indent_level(node) + indentation_width
@@ -191,6 +193,7 @@ module RuboCop
191
193
 
192
194
  def correct_by_squiggly(node)
193
195
  return if target_ruby_version < 2.3
196
+
194
197
  lambda do |corrector|
195
198
  if heredoc_indent_type(node) == '~'
196
199
  adjust_squiggly(corrector, node)
@@ -70,6 +70,7 @@ module RuboCop
70
70
  # Check indentation against end keyword but only if it's first on its
71
71
  # line.
72
72
  return unless begins_its_line?(node.loc.end)
73
+
73
74
  check_indentation(node.loc.end, node.children.first)
74
75
  end
75
76
 
@@ -165,6 +166,7 @@ module RuboCop
165
166
  else
166
167
  members.first.children.each do |member|
167
168
  next if member.send_type? && member.access_modifier?
169
+
168
170
  check_indentation(base, member)
169
171
  end
170
172
  end
@@ -196,6 +196,7 @@ module RuboCop
196
196
  node = node.parent until node.loc.dot
197
197
 
198
198
  return if node.loc.dot.line != node.first_line
199
+
199
200
  node
200
201
  end
201
202
 
@@ -61,6 +61,8 @@ module RuboCop
61
61
  private
62
62
 
63
63
  def relevant_node?(node)
64
+ return false if node.unary_operation?
65
+
64
66
  !node.loc.dot # Don't check method calls with dot operator.
65
67
  end
66
68
 
@@ -72,7 +74,6 @@ module RuboCop
72
74
 
73
75
  def offending_range(node, lhs, rhs, given_style)
74
76
  return false unless begins_its_line?(rhs)
75
- return false if lhs.first_line == rhs.line # Needed for unary op.
76
77
  return false if not_for_this_cop?(node)
77
78
 
78
79
  correct_column = if should_align?(node, rhs, given_style)
@@ -25,8 +25,10 @@ module RuboCop
25
25
  include RangeHelp
26
26
 
27
27
  MSG = '`%<kw_loc>s` at %<kw_loc_line>d, %<kw_loc_column>d is not ' \
28
- 'aligned with `end` at %<end_loc_line>d, %<end_loc_column>d.'
29
- .freeze
28
+ 'aligned with `%<beginning>s` at ' \
29
+ '%<begin_loc_line>d, %<begin_loc_column>d.'.freeze
30
+ ANCESTOR_TYPES = %i[kwbegin def defs class module].freeze
31
+ RUBY_2_5_ANCESTOR_TYPES = (ANCESTOR_TYPES + [:block]).freeze
30
32
 
31
33
  def on_resbody(node)
32
34
  check(node) unless modifier?(node)
@@ -40,6 +42,7 @@ module RuboCop
40
42
  @modifier_locations =
41
43
  processed_source.tokens.each_with_object([]) do |token, locations|
42
44
  next unless token.rescue_modifier?
45
+
43
46
  locations << token.pos
44
47
  end
45
48
  end
@@ -55,28 +58,44 @@ module RuboCop
55
58
  private
56
59
 
57
60
  def check(node)
58
- end_loc = ancestor_node(node).loc.end
61
+ ancestor_node = ancestor_node(node)
62
+ alignment_loc = ancestor_node.loc.expression
59
63
  kw_loc = node.loc.keyword
60
64
 
61
- return if end_loc.column == kw_loc.column
62
- return if end_loc.line == kw_loc.line
65
+ return if alignment_loc.column == kw_loc.column
66
+ return if alignment_loc.line == kw_loc.line
63
67
 
64
68
  add_offense(node,
65
69
  location: kw_loc,
66
- message: format_message(kw_loc, end_loc))
70
+ message: format_message(kw_loc,
71
+ alignment_loc,
72
+ ancestor_node))
67
73
  end
68
74
 
69
- def format_message(kw_loc, end_loc)
75
+ def format_message(kw_loc, alignment_loc, ancestor_node)
70
76
  format(MSG,
71
77
  kw_loc: kw_loc.source,
72
78
  kw_loc_line: kw_loc.line,
73
79
  kw_loc_column: kw_loc.column,
74
- end_loc_line: end_loc.line,
75
- end_loc_column: end_loc.column)
80
+ beginning: alignment_source(ancestor_node),
81
+ begin_loc_line: alignment_loc.line,
82
+ begin_loc_column: alignment_loc.column)
83
+ end
84
+
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
92
+
93
+ range_between(node.loc.expression.begin_pos, ending.end_pos).source
76
94
  end
77
95
 
78
96
  def modifier?(node)
79
97
  return false unless @modifier_locations.respond_to?(:include?)
98
+
80
99
  @modifier_locations.include?(node.loc.keyword)
81
100
  end
82
101
 
@@ -88,8 +107,12 @@ module RuboCop
88
107
  end
89
108
 
90
109
  def ancestor_node(node)
91
- types = %i[kwbegin def defs class module]
92
- types << :block if target_ruby_version >= 2.5
110
+ types = if target_ruby_version >= 2.5
111
+ RUBY_2_5_ANCESTOR_TYPES
112
+ else
113
+ ANCESTOR_TYPES
114
+ end
115
+
93
116
  node.each_ancestor(*types).first
94
117
  end
95
118
  end
@@ -23,6 +23,7 @@ module RuboCop
23
23
  def on_def(node)
24
24
  args = node.arguments
25
25
  return unless args.loc.begin && args.loc.begin.is?('(')
26
+
26
27
  expr = args.source_range
27
28
  pos_before_left_paren = range_between(expr.begin_pos - 1,
28
29
  expr.begin_pos)
@@ -17,7 +17,7 @@ module RuboCop
17
17
  MSG = 'Do not leave space between `!` and its argument.'.freeze
18
18
 
19
19
  def on_send(node)
20
- return unless node.keyword_bang? && whitespace_after_operator?(node)
20
+ return unless node.prefix_bang? && whitespace_after_operator?(node)
21
21
 
22
22
  add_offense(node)
23
23
  end
@@ -96,7 +96,7 @@ module RuboCop
96
96
  end
97
97
 
98
98
  def on_send(node)
99
- check(node, [:selector].freeze) if node.keyword_not?
99
+ check(node, [:selector].freeze) if node.prefix_not?
100
100
  end
101
101
 
102
102
  def on_super(node)
@@ -140,6 +140,7 @@ module RuboCop
140
140
  def check(node, locations, begin_keyword = DO)
141
141
  locations.each do |loc|
142
142
  next unless node.loc.respond_to?(loc)
143
+
143
144
  range = node.loc.public_send(loc)
144
145
  next unless range
145
146
 
@@ -182,6 +183,7 @@ module RuboCop
182
183
  def space_before_missing?(range)
183
184
  pos = range.begin_pos - 1
184
185
  return false if pos < 0
186
+
185
187
  range.source_buffer.source[pos] !~ /[\s\(\|\{\[;,\*\=]/
186
188
  end
187
189
 
@@ -71,6 +71,7 @@ module RuboCop
71
71
  _, _, right, = *node
72
72
 
73
73
  return unless right
74
+
74
75
  check_operator(node.loc.operator, right.source_range)
75
76
  end
76
77
 
@@ -19,6 +19,7 @@ module RuboCop
19
19
  processed_source.tokens.each_cons(2) do |token1, token2|
20
20
  next unless token2.comment?
21
21
  next unless token1.line == token2.line
22
+
22
23
  if token1.pos.end == token2.pos.begin
23
24
  add_offense(token2.pos, location: token2.pos)
24
25
  end
@@ -3,8 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Layout
6
- # This cop checks for spaces between -> and opening parameter
7
- # brace in lambda literals.
6
+ # This cop checks for spaces between `->` and opening parameter
7
+ # parenthesis (`(`) in lambda literals.
8
8
  #
9
9
  # @example EnforcedStyle: require_no_space (default)
10
10
  # # bad
@@ -24,20 +24,21 @@ module RuboCop
24
24
  include RangeHelp
25
25
 
26
26
  ARROW = '->'.freeze
27
- MSG_REQUIRE_SPACE = 'Use a space between `->` and opening brace ' \
28
- 'in lambda literals'.freeze
29
- MSG_REQUIRE_NO_SPACE = 'Do not use spaces between `->` and opening ' \
30
- 'brace in lambda literals'.freeze
27
+ MSG_REQUIRE_SPACE = 'Use a space between `->` and ' \
28
+ '`(` in lambda literals.'.freeze
29
+ MSG_REQUIRE_NO_SPACE = 'Do not use spaces between `->` and ' \
30
+ '`(` in lambda literals.'.freeze
31
31
 
32
32
  def on_send(node)
33
33
  return unless arrow_lambda_with_args?(node)
34
+
34
35
  if style == :require_space && !space_after_arrow?(node)
35
36
  add_offense(node,
36
- location: node.parent.loc.expression,
37
+ location: range_of_offense(node),
37
38
  message: MSG_REQUIRE_SPACE)
38
39
  elsif style == :require_no_space && space_after_arrow?(node)
39
40
  add_offense(node,
40
- location: node.parent.loc.expression,
41
+ location: range_of_offense(node),
41
42
  message: MSG_REQUIRE_NO_SPACE)
42
43
  end
43
44
  end
@@ -80,6 +81,13 @@ module RuboCop
80
81
  parentheses = lambda_node.parent.children[1]
81
82
  parentheses.source_range.begin_pos - arrow.source_range.end_pos > 0
82
83
  end
84
+
85
+ def range_of_offense(node)
86
+ range_between(
87
+ node.parent.loc.expression.begin_pos,
88
+ node.parent.arguments.loc.expression.end_pos
89
+ )
90
+ end
83
91
  end
84
92
  end
85
93
  end