rubocop 0.46.0 → 0.47.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 (214) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +77 -2
  4. data/config/default.yml +151 -74
  5. data/config/disabled.yml +9 -0
  6. data/config/enabled.yml +49 -9
  7. data/lib/rubocop.rb +36 -8
  8. data/lib/rubocop/ast/builder.rb +59 -0
  9. data/lib/rubocop/ast/node.rb +607 -0
  10. data/lib/rubocop/ast/node/array_node.rb +45 -0
  11. data/lib/rubocop/ast/node/case_node.rb +63 -0
  12. data/lib/rubocop/ast/node/for_node.rb +53 -0
  13. data/lib/rubocop/ast/node/hash_node.rb +102 -0
  14. data/lib/rubocop/ast/node/if_node.rb +136 -0
  15. data/lib/rubocop/ast/node/keyword_splat_node.rb +45 -0
  16. data/lib/rubocop/ast/node/mixin/conditional_node.rb +45 -0
  17. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +125 -0
  18. data/lib/rubocop/ast/node/mixin/modifier_node.rb +17 -0
  19. data/lib/rubocop/ast/node/pair_node.rb +64 -0
  20. data/lib/rubocop/ast/node/until_node.rb +43 -0
  21. data/lib/rubocop/ast/node/when_node.rb +61 -0
  22. data/lib/rubocop/ast/node/while_node.rb +43 -0
  23. data/lib/rubocop/ast/sexp.rb +16 -0
  24. data/lib/rubocop/{ast_node → ast}/traversal.rb +1 -1
  25. data/lib/rubocop/cli.rb +18 -14
  26. data/lib/rubocop/comment_config.rb +1 -3
  27. data/lib/rubocop/config.rb +93 -35
  28. data/lib/rubocop/config_loader.rb +1 -1
  29. data/lib/rubocop/cop/badge.rb +73 -0
  30. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  31. data/lib/rubocop/cop/bundler/ordered_gems.rb +43 -3
  32. data/lib/rubocop/cop/commissioner.rb +17 -6
  33. data/lib/rubocop/cop/cop.rb +25 -112
  34. data/lib/rubocop/cop/lint/ambiguous_operator.rb +9 -4
  35. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +7 -0
  36. data/lib/rubocop/cop/lint/assignment_in_condition.rb +18 -4
  37. data/lib/rubocop/cop/lint/block_alignment.rb +40 -9
  38. data/lib/rubocop/cop/lint/circular_argument_reference.rb +14 -0
  39. data/lib/rubocop/cop/lint/condition_position.rb +14 -16
  40. data/lib/rubocop/cop/lint/debugger.rb +28 -0
  41. data/lib/rubocop/cop/lint/def_end_alignment.rb +21 -1
  42. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +13 -1
  43. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +26 -22
  44. data/lib/rubocop/cop/lint/duplicate_methods.rb +15 -1
  45. data/lib/rubocop/cop/lint/duplicated_key.rb +16 -8
  46. data/lib/rubocop/cop/lint/each_with_object_argument.rb +9 -0
  47. data/lib/rubocop/cop/lint/else_layout.rb +26 -29
  48. data/lib/rubocop/cop/lint/empty_ensure.rb +38 -0
  49. data/lib/rubocop/cop/lint/empty_expression.rb +11 -1
  50. data/lib/rubocop/cop/lint/empty_interpolation.rb +8 -0
  51. data/lib/rubocop/cop/lint/empty_when.rb +14 -16
  52. data/lib/rubocop/cop/lint/end_alignment.rb +48 -28
  53. data/lib/rubocop/cop/lint/end_in_method.rb +23 -0
  54. data/lib/rubocop/cop/lint/ensure_return.rb +21 -0
  55. data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -0
  56. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +29 -4
  57. data/lib/rubocop/cop/lint/handle_exceptions.rb +40 -0
  58. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +7 -2
  59. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +11 -2
  60. data/lib/rubocop/cop/lint/invalid_character_literal.rb +3 -0
  61. data/lib/rubocop/cop/lint/literal_in_condition.rb +34 -36
  62. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -0
  63. data/lib/rubocop/cop/lint/loop.rb +36 -0
  64. data/lib/rubocop/cop/lint/multiple_compare.rb +46 -0
  65. data/lib/rubocop/cop/lint/nested_method_definition.rb +22 -0
  66. data/lib/rubocop/cop/lint/next_without_accumulator.rb +5 -0
  67. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -0
  68. data/lib/rubocop/cop/lint/percent_string_array.rb +27 -13
  69. data/lib/rubocop/cop/lint/percent_symbol_array.rb +14 -4
  70. data/lib/rubocop/cop/lint/rand_one.rb +7 -3
  71. data/lib/rubocop/cop/lint/require_parentheses.rb +20 -19
  72. data/lib/rubocop/cop/lint/rescue_exception.rb +20 -0
  73. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +66 -0
  74. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -1
  75. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +24 -0
  76. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +8 -0
  77. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +24 -0
  78. data/lib/rubocop/cop/lint/unified_integer.rb +5 -0
  79. data/lib/rubocop/cop/lint/unneeded_disable.rb +2 -2
  80. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +5 -0
  81. data/lib/rubocop/cop/lint/unreachable_code.rb +17 -0
  82. data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -0
  83. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  84. data/lib/rubocop/cop/lint/useless_access_modifier.rb +28 -1
  85. data/lib/rubocop/cop/lint/useless_assignment.rb +18 -0
  86. data/lib/rubocop/cop/lint/useless_comparison.rb +3 -1
  87. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +16 -1
  88. data/lib/rubocop/cop/lint/useless_setter_call.rb +16 -4
  89. data/lib/rubocop/cop/lint/void.rb +52 -0
  90. data/lib/rubocop/cop/message_annotator.rb +102 -0
  91. data/lib/rubocop/cop/metrics/block_length.rb +6 -0
  92. data/lib/rubocop/cop/metrics/block_nesting.rb +17 -5
  93. data/lib/rubocop/cop/metrics/line_length.rb +11 -4
  94. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
  95. data/lib/rubocop/cop/mixin/array_syntax.rb +2 -11
  96. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +12 -5
  97. data/lib/rubocop/cop/mixin/configurable_formatting.rb +48 -0
  98. data/lib/rubocop/cop/mixin/configurable_max.rb +3 -3
  99. data/lib/rubocop/cop/mixin/configurable_naming.rb +5 -33
  100. data/lib/rubocop/cop/mixin/configurable_numbering.rb +6 -47
  101. data/lib/rubocop/cop/mixin/documentation_comment.rb +7 -1
  102. data/lib/rubocop/cop/mixin/duplication.rb +46 -0
  103. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +2 -2
  104. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +14 -11
  105. data/lib/rubocop/cop/mixin/hash_alignment.rb +114 -0
  106. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  107. data/lib/rubocop/cop/mixin/negative_conditional.rb +21 -7
  108. data/lib/rubocop/cop/mixin/on_method_def.rb +14 -0
  109. data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +1 -24
  110. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -13
  111. data/lib/rubocop/cop/mixin/target_ruby_version.rb +16 -0
  112. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -3
  113. data/lib/rubocop/cop/offense.rb +1 -1
  114. data/lib/rubocop/cop/performance/case_when_splat.rb +56 -59
  115. data/lib/rubocop/cop/performance/detect.rb +2 -2
  116. data/lib/rubocop/cop/performance/flat_map.rb +3 -3
  117. data/lib/rubocop/cop/performance/redundant_merge.rb +3 -6
  118. data/lib/rubocop/cop/performance/regexp_match.rb +201 -0
  119. data/lib/rubocop/cop/rails/delegate.rb +2 -2
  120. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +10 -19
  121. data/lib/rubocop/cop/rails/enum_uniqueness.rb +12 -40
  122. data/lib/rubocop/cop/rails/file_path.rb +80 -0
  123. data/lib/rubocop/cop/rails/find_each.rb +5 -14
  124. data/lib/rubocop/cop/rails/http_positional_arguments.rb +30 -24
  125. data/lib/rubocop/cop/rails/not_null_column.rb +23 -0
  126. data/lib/rubocop/cop/rails/reversible_migration.rb +217 -0
  127. data/lib/rubocop/cop/rails/safe_navigation.rb +4 -2
  128. data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -0
  129. data/lib/rubocop/cop/rails/time_zone.rb +1 -1
  130. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +7 -5
  131. data/lib/rubocop/cop/registry.rb +170 -0
  132. data/lib/rubocop/cop/{lint → security}/eval.rb +7 -1
  133. data/lib/rubocop/cop/security/marshal_load.rb +33 -0
  134. data/lib/rubocop/cop/security/yaml_load.rb +37 -0
  135. data/lib/rubocop/cop/style/align_hash.rb +138 -169
  136. data/lib/rubocop/cop/style/and_or.rb +1 -1
  137. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +10 -15
  138. data/lib/rubocop/cop/style/case_indentation.rb +36 -27
  139. data/lib/rubocop/cop/style/conditional_assignment.rb +64 -47
  140. data/lib/rubocop/cop/style/each_with_object.rb +4 -1
  141. data/lib/rubocop/cop/style/else_alignment.rb +14 -20
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +16 -25
  143. data/lib/rubocop/cop/style/empty_else.rb +20 -22
  144. data/lib/rubocop/cop/style/empty_literal.rb +4 -4
  145. data/lib/rubocop/cop/style/empty_method.rb +12 -6
  146. data/lib/rubocop/cop/style/encoding.rb +1 -1
  147. data/lib/rubocop/cop/style/file_name.rb +24 -4
  148. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
  149. data/lib/rubocop/cop/style/format_string.rb +17 -48
  150. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +40 -11
  151. data/lib/rubocop/cop/style/guard_clause.rb +11 -17
  152. data/lib/rubocop/cop/style/hash_syntax.rb +24 -42
  153. data/lib/rubocop/cop/style/identical_conditional_branches.rb +40 -28
  154. data/lib/rubocop/cop/style/if_inside_else.rb +6 -9
  155. data/lib/rubocop/cop/style/if_unless_modifier.rb +16 -25
  156. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -9
  157. data/lib/rubocop/cop/style/indent_array.rb +1 -1
  158. data/lib/rubocop/cop/style/indentation_width.rb +29 -60
  159. data/lib/rubocop/cop/style/infinite_loop.rb +21 -22
  160. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +86 -0
  161. data/lib/rubocop/cop/style/{method_call_parentheses.rb → method_call_without_args_parentheses.rb} +8 -1
  162. data/lib/rubocop/cop/style/missing_else.rb +40 -14
  163. data/lib/rubocop/cop/style/multiline_if_modifier.rb +5 -15
  164. data/lib/rubocop/cop/style/multiline_if_then.rb +14 -8
  165. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +3 -3
  166. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -5
  167. data/lib/rubocop/cop/style/mutable_constant.rb +3 -2
  168. data/lib/rubocop/cop/style/negated_if.rb +3 -19
  169. data/lib/rubocop/cop/style/negated_while.rb +2 -17
  170. data/lib/rubocop/cop/style/nested_modifier.rb +16 -43
  171. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -5
  172. data/lib/rubocop/cop/style/next.rb +23 -21
  173. data/lib/rubocop/cop/style/non_nil_check.rb +2 -3
  174. data/lib/rubocop/cop/style/not.rb +1 -3
  175. data/lib/rubocop/cop/style/numeric_literals.rb +2 -2
  176. data/lib/rubocop/cop/style/one_line_conditional.rb +12 -22
  177. data/lib/rubocop/cop/style/option_hash.rb +4 -15
  178. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -3
  179. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -12
  180. data/lib/rubocop/cop/style/percent_q_literals.rb +15 -12
  181. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -2
  182. data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -4
  183. data/lib/rubocop/cop/style/redundant_return.rb +4 -8
  184. data/lib/rubocop/cop/style/safe_navigation.rb +13 -6
  185. data/lib/rubocop/cop/style/space_after_colon.rb +2 -4
  186. data/lib/rubocop/cop/style/space_around_block_parameters.rb +1 -1
  187. data/lib/rubocop/cop/style/space_around_operators.rb +15 -13
  188. data/lib/rubocop/cop/style/string_methods.rb +1 -3
  189. data/lib/rubocop/cop/style/symbol_array.rb +1 -5
  190. data/lib/rubocop/cop/style/ternary_parentheses.rb +5 -6
  191. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
  192. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +1 -1
  193. data/lib/rubocop/cop/style/unless_else.rb +1 -5
  194. data/lib/rubocop/cop/style/when_then.rb +4 -2
  195. data/lib/rubocop/cop/style/while_until_do.rb +9 -13
  196. data/lib/rubocop/cop/style/while_until_modifier.rb +12 -11
  197. data/lib/rubocop/cop/style/word_array.rb +5 -9
  198. data/lib/rubocop/cop/team.rb +16 -15
  199. data/lib/rubocop/cop/util.rb +13 -3
  200. data/lib/rubocop/formatter/clang_style_formatter.rb +2 -2
  201. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
  202. data/lib/rubocop/magic_comment.rb +196 -0
  203. data/lib/rubocop/options.rb +5 -4
  204. data/lib/rubocop/processed_source.rb +1 -1
  205. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  206. data/lib/rubocop/rspec/shared_examples.rb +1 -1
  207. data/lib/rubocop/runner.rb +7 -2
  208. data/lib/rubocop/version.rb +1 -1
  209. metadata +41 -14
  210. data/lib/rubocop/ast_node.rb +0 -624
  211. data/lib/rubocop/ast_node/builder.rb +0 -30
  212. data/lib/rubocop/ast_node/sexp.rb +0 -13
  213. data/lib/rubocop/cop/mixin/hash_node.rb +0 -14
  214. data/lib/rubocop/cop/mixin/if_node.rb +0 -42
@@ -159,7 +159,7 @@ module RuboCop
159
159
 
160
160
  def cop_range(comment, cop)
161
161
  matching_range(comment.loc.expression, cop) ||
162
- matching_range(comment.loc.expression, cop.split('/').last) ||
162
+ matching_range(comment.loc.expression, Badge.parse(cop).cop_name) ||
163
163
  raise("Couldn't find #{cop} in comment: #{comment.text}")
164
164
  end
165
165
 
@@ -199,7 +199,7 @@ module RuboCop
199
199
  end
200
200
 
201
201
  def all_cop_names
202
- @all_cop_names ||= Cop.all.map(&:cop_name)
202
+ @all_cop_names ||= Cop.registry.names
203
203
  end
204
204
  end
205
205
  end
@@ -6,7 +6,9 @@ module RuboCop
6
6
  # This cop checks for unneeded usages of splat expansion
7
7
  #
8
8
  # @example
9
+ #
9
10
  # # bad
11
+ #
10
12
  # a = *[1, 2, 3]
11
13
  # a = *'a'
12
14
  # a = *1
@@ -24,7 +26,10 @@ module RuboCop
24
26
  # baz
25
27
  # end
26
28
  #
29
+ # @example
30
+ #
27
31
  # # good
32
+ #
28
33
  # c = [1, 2, 3]
29
34
  # a = *c
30
35
  # a, b = *c
@@ -6,6 +6,23 @@ module RuboCop
6
6
  # This cop checks for unreachable code.
7
7
  # The check are based on the presence of flow of control
8
8
  # statement in non-final position in *begin*(implicit) blocks.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ #
14
+ # def some_method
15
+ # return
16
+ # do_something
17
+ # end
18
+ #
19
+ # @example
20
+ #
21
+ # # good
22
+ #
23
+ # def some_method
24
+ # do_something
25
+ # end
9
26
  class UnreachableCode < Cop
10
27
  MSG = 'Unreachable code detected.'.freeze
11
28
 
@@ -21,6 +21,8 @@ module RuboCop
21
21
  # puts :baz
22
22
  # end
23
23
  #
24
+ # @example
25
+ #
24
26
  # # bad
25
27
  #
26
28
  # do_something do |used, _unused|
@@ -7,9 +7,19 @@ module RuboCop
7
7
  #
8
8
  # @example
9
9
  #
10
+ # # bad
11
+ #
10
12
  # def some_method(used, unused, _unused_but_allowed)
11
13
  # puts used
12
14
  # end
15
+ #
16
+ # @example
17
+ #
18
+ # # good
19
+ #
20
+ # def some_method(used, _unused, _unused_but_allowed)
21
+ # puts used
22
+ # end
13
23
  class UnusedMethodArgument < Cop
14
24
  include UnusedArgument
15
25
 
@@ -78,6 +78,18 @@ module RuboCop
78
78
  # def some_other_private_method
79
79
  # end
80
80
  # end
81
+ #
82
+ # @example
83
+ # # Lint/UselessAccessModifier:
84
+ # # MethodCreatingMethods:
85
+ # # - delegate
86
+ # require 'active_support/core_ext/module/delegation'
87
+ # class Foo
88
+ # # this is not redundant because `delegate` creates methods
89
+ # private
90
+ #
91
+ # delegate :method_a, to: :method_b
92
+ # end
81
93
  class UselessAccessModifier < Cop
82
94
  MSG = 'Useless `%s` access modifier.'.freeze
83
95
 
@@ -170,7 +182,22 @@ module RuboCop
170
182
  end
171
183
 
172
184
  def method_definition?(child)
173
- static_method_definition?(child) || dynamic_method_definition?(child)
185
+ static_method_definition?(child) ||
186
+ dynamic_method_definition?(child) ||
187
+ any_method_definition?(child)
188
+ end
189
+
190
+ def any_method_definition?(child)
191
+ cop_config.fetch('MethodCreatingMethods', []).any? do |m|
192
+ matcher_name = "#{m}_method?".to_sym
193
+ unless respond_to?(matcher_name)
194
+ self.class.def_node_matcher matcher_name, <<-PATTERN
195
+ {def (send nil :#{m} ...)}
196
+ PATTERN
197
+ end
198
+
199
+ send(matcher_name, child)
200
+ end
174
201
  end
175
202
 
176
203
  def start_of_new_scope?(child)
@@ -12,6 +12,24 @@ module RuboCop
12
12
  # Currently this cop has advanced logic that detects unreferenced
13
13
  # reassignments and properly handles varied cases such as branch, loop,
14
14
  # rescue, ensure, etc.
15
+ #
16
+ # @example
17
+ #
18
+ # # bad
19
+ #
20
+ # def some_method
21
+ # some_var = 1
22
+ # do_something
23
+ # end
24
+ #
25
+ # @example
26
+ #
27
+ # # good
28
+ #
29
+ # def some_method
30
+ # some_var = 1
31
+ # do_something(some_var)
32
+ # end
15
33
  class UselessAssignment < Cop
16
34
  include NameSimilarity
17
35
  MSG = 'Useless assignment to variable - `%s`.'.freeze
@@ -7,7 +7,9 @@ module RuboCop
7
7
  #
8
8
  # @example
9
9
  #
10
- # x.top >= x.top
10
+ # # bad
11
+ #
12
+ # x.top >= x.top
11
13
  class UselessComparison < Cop
12
14
  MSG = 'Comparison of something with itself detected.'.freeze
13
15
  OPS = %w(== === != < > <= >= <=>).freeze
@@ -6,10 +6,25 @@ module RuboCop
6
6
  # This cop checks for useless `else` in `begin..end` without `rescue`.
7
7
  #
8
8
  # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # begin
13
+ # do_something
14
+ # else
15
+ # do_something_else # This will never be run.
16
+ # end
17
+ #
18
+ # @example
19
+ #
20
+ # # good
21
+ #
9
22
  # begin
10
23
  # do_something
24
+ # rescue
25
+ # handle_errors
11
26
  # else
12
- # handle_errors # This will never be run.
27
+ # do_something_else
13
28
  # end
14
29
  class UselessElseWithoutRescue < Cop
15
30
  include ParserDiagnostic
@@ -8,10 +8,22 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  #
11
- # def something
12
- # x = Something.new
13
- # x.attr = 5
14
- # end
11
+ # # bad
12
+ #
13
+ # def something
14
+ # x = Something.new
15
+ # x.attr = 5
16
+ # end
17
+ #
18
+ # @example
19
+ #
20
+ # # good
21
+ #
22
+ # def something
23
+ # x = Something.new
24
+ # x.attr = 5
25
+ # x
26
+ # end
15
27
  class UselessSetterCall < Cop
16
28
  include OnMethodDef
17
29
 
@@ -5,10 +5,48 @@ module RuboCop
5
5
  module Lint
6
6
  # This cop checks for operators, variables and literals used
7
7
  # in void context.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ #
13
+ # def some_method
14
+ # some_num * 10
15
+ # do_something
16
+ # end
17
+ #
18
+ # @example
19
+ #
20
+ # # bad
21
+ #
22
+ # def some_method
23
+ # some_var
24
+ # do_something
25
+ # end
26
+ #
27
+ # @example
28
+ #
29
+ # # good
30
+ #
31
+ # def some_method
32
+ # do_something
33
+ # some_num * 10
34
+ # end
35
+ #
36
+ # @example
37
+ #
38
+ # # good
39
+ #
40
+ # def some_method
41
+ # do_something
42
+ # some_var
43
+ # end
8
44
  class Void < Cop
9
45
  OP_MSG = 'Operator `%s` used in void context.'.freeze
10
46
  VAR_MSG = 'Variable `%s` used in void context.'.freeze
11
47
  LIT_MSG = 'Literal `%s` used in void context.'.freeze
48
+ SELF_MSG = '`self` used in void context.'.freeze
49
+ DEFINED_MSG = '`%s` used in void context.'.freeze
12
50
 
13
51
  OPS = %w(* / % + - == === != < > <= >= <=>).freeze
14
52
 
@@ -29,6 +67,8 @@ module RuboCop
29
67
  check_for_void_op(expr)
30
68
  check_for_literal(expr)
31
69
  check_for_var(expr)
70
+ check_for_self(expr)
71
+ check_for_defined(expr)
32
72
  end
33
73
  end
34
74
 
@@ -50,6 +90,18 @@ module RuboCop
50
90
 
51
91
  add_offense(node, :expression, format(LIT_MSG, node.source))
52
92
  end
93
+
94
+ def check_for_self(node)
95
+ return unless node.self_type?
96
+
97
+ add_offense(node, :expression, SELF_MSG)
98
+ end
99
+
100
+ def check_for_defined(node)
101
+ return unless node.defined_type?
102
+
103
+ add_offense(node, :expression, format(DEFINED_MSG, node.source))
104
+ end
53
105
  end
54
106
  end
55
107
  end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Message Annotator class annotates a basic offense message
6
+ # based on params passed into initializer.
7
+ #
8
+ # @see #initialize
9
+ #
10
+ # @example
11
+ # RuboCop::Cop::MessageAnnotator.new(
12
+ # config, cop_config, @options
13
+ # ).annotate('message', 'Cop/CopName')
14
+ # #=> 'Cop/CopName: message (http://example.org/styleguide)'
15
+ class MessageAnnotator
16
+ attr_reader :options, :config, :cop_config
17
+
18
+ # @param config [RuboCop::Config] Check configs for all cops
19
+ # @note Message Annotator specifically checks the
20
+ # following config options for_all_cops
21
+ # :StyleGuideBaseURL [String] URL for styleguide
22
+ # :DisplayStyleGuide [Boolean] Include styleguide and reference URLs
23
+ # :ExtraDetails [Boolean] Include cop details
24
+ # :DisplayCopNames [Boolean] Include cop name
25
+ #
26
+ # @param [Hash] cop_config configs for specific cop, from config#for_cop
27
+ # @option cop_config [String] :StyleGuide Extension of base styleguide URL
28
+ # @option cop_config [String] :Reference Full reference URL
29
+ # @option cop_config [String] :Details
30
+ #
31
+ # @param [Hash] options
32
+ # @option option [Boolean] :display_style_guide
33
+ # Include style guide and reference URLs
34
+ # @option option [Boolean] :extra_details
35
+ # Include cop specific details
36
+ # @option option [Boolean] :debug
37
+ # Include debug output
38
+ # @option option [Boolean] :display_cop_names
39
+ # Include cop name
40
+ def initialize(config, cop_config, options)
41
+ @config = config
42
+ @cop_config = cop_config || {}
43
+ @options = options
44
+ end
45
+
46
+ # Returns the annotated message,
47
+ # based on params passed into initializer
48
+ #
49
+ # @return [String] annotated message
50
+ def annotate(message, name)
51
+ message = "#{name}: #{message}" if display_cop_names?
52
+ message += " #{details}" if extra_details?
53
+ if display_style_guide?
54
+ links = [style_guide_url, reference_url].compact.join(', ')
55
+ message = "#{message} (#{links})"
56
+ end
57
+ message
58
+ end
59
+
60
+ private
61
+
62
+ def style_guide_url
63
+ url = cop_config['StyleGuide']
64
+ return nil if url.nil? || url.empty?
65
+
66
+ base_url = config.for_all_cops['StyleGuideBaseURL']
67
+ return url if base_url.nil? || base_url.empty?
68
+
69
+ URI.join(base_url, url).to_s
70
+ end
71
+
72
+ def display_style_guide?
73
+ (style_guide_url || reference_url) &&
74
+ (options[:display_style_guide] ||
75
+ config.for_all_cops['DisplayStyleGuide'])
76
+ end
77
+
78
+ def reference_url
79
+ url = cop_config['Reference']
80
+ url.nil? || url.empty? ? nil : url
81
+ end
82
+
83
+ def extra_details?
84
+ options[:extra_details] || config.for_all_cops['ExtraDetails']
85
+ end
86
+
87
+ def debug?
88
+ options[:debug]
89
+ end
90
+
91
+ def display_cop_names?
92
+ debug? || options[:display_cop_names] ||
93
+ config.for_all_cops['DisplayCopNames']
94
+ end
95
+
96
+ def details
97
+ details = cop_config && cop_config['Details']
98
+ details.nil? || details.empty? ? nil : details
99
+ end
100
+ end
101
+ end
102
+ end
@@ -6,17 +6,23 @@ module RuboCop
6
6
  # This cop checks if the length of a block exceeds some maximum value.
7
7
  # Comment lines can optionally be ignored.
8
8
  # The maximum allowed length is configurable.
9
+ # The cop can be configured to ignore blocks passed to certain methods.
9
10
  class BlockLength < Cop
10
11
  include TooManyLines
11
12
 
12
13
  LABEL = 'Block'.freeze
13
14
 
14
15
  def on_block(node)
16
+ return if excluded_methods.include?(node.method_name.to_s)
15
17
  check_code_length(node)
16
18
  end
17
19
 
18
20
  private
19
21
 
22
+ def excluded_methods
23
+ cop_config['ExcludedMethods'] || []
24
+ end
25
+
20
26
  def cop_label
21
27
  LABEL
22
28
  end
@@ -4,13 +4,15 @@ module RuboCop
4
4
  module Cop
5
5
  module Metrics
6
6
  # This cop checks for excessive nesting of conditional and looping
7
- # constructs. Despite the cop's name, blocks are not considered as an
8
- # extra level of nesting.
7
+ # constructs.
8
+ #
9
+ # You can configure if blocks are considered using the `CountBlocks`
10
+ # option. When set to `false` (the default) blocks are not counted
11
+ # towards the nesting level. Set to `true` to count blocks as well.
9
12
  #
10
13
  # The maximum level of nesting allowed is configurable.
11
14
  class BlockNesting < Cop
12
15
  include ConfigurableMax
13
- include IfNode
14
16
 
15
17
  NESTING_BLOCKS = [
16
18
  :case, :if, :while, :while_post,
@@ -26,8 +28,8 @@ module RuboCop
26
28
  private
27
29
 
28
30
  def check_nesting_level(node, max, current_level)
29
- if NESTING_BLOCKS.include?(node.type)
30
- current_level += 1 unless elsif?(node)
31
+ if consider_node?(node)
32
+ current_level += 1 unless node.if_type? && node.elsif?
31
33
  if current_level > max
32
34
  self.max = current_level
33
35
  unless part_of_ignored_node?(node)
@@ -43,9 +45,19 @@ module RuboCop
43
45
  end
44
46
  end
45
47
 
48
+ def consider_node?(node)
49
+ return true if NESTING_BLOCKS.include?(node.type)
50
+
51
+ count_blocks? && node.block_type?
52
+ end
53
+
46
54
  def message(max)
47
55
  "Avoid more than #{max} levels of block nesting."
48
56
  end
57
+
58
+ def count_blocks?
59
+ cop_config['CountBlocks']
60
+ end
49
61
  end
50
62
  end
51
63
  end