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
@@ -8,10 +8,15 @@ module RuboCop
8
8
  # that big. If you need a float that big, something is wrong with you.
9
9
  #
10
10
  # @example
11
+ #
11
12
  # # bad
13
+ #
12
14
  # float = 3.0e400
13
15
  #
16
+ # @example
17
+ #
14
18
  # # good
19
+ #
15
20
  # float = 42.9
16
21
  class FloatOutOfRange < Cop
17
22
  MSG = 'Float out of range.'.freeze
@@ -9,8 +9,15 @@ module RuboCop
9
9
  #
10
10
  # @example
11
11
  #
12
+ # # bad
13
+ #
12
14
  # format('A value: %s and another: %i', a_value)
13
15
  #
16
+ # @example
17
+ #
18
+ # # good
19
+ #
20
+ # format('A value: %s and another: %i', a_value, another)
14
21
  class FormatParameterMismatch < Cop
15
22
  # http://rubular.com/r/CvpbxkcTzy
16
23
  MSG = "Number of arguments (%i) to `%s` doesn't match the number of " \
@@ -38,8 +45,16 @@ module RuboCop
38
45
 
39
46
  num_of_format_args, num_of_expected_fields = count_matches(node)
40
47
 
41
- num_of_format_args != :unknown &&
42
- num_of_expected_fields != num_of_format_args
48
+ return false if num_of_format_args == :unknown
49
+ matched_arguments_count?(num_of_expected_fields, num_of_format_args)
50
+ end
51
+
52
+ def matched_arguments_count?(expected, passed)
53
+ if passed < 0
54
+ expected < passed.abs
55
+ else
56
+ expected != passed
57
+ end
43
58
  end
44
59
 
45
60
  def called_on_string?(node)
@@ -85,11 +100,11 @@ module RuboCop
85
100
  receiver_node, _method_name, *args = *node
86
101
 
87
102
  if (sprintf?(node) || format?(node)) && !heredoc?(node)
88
- number_of_args_for_format = (args.size - 1)
103
+ number_of_args_for_format = arguments_count(args) - 1
89
104
  number_of_expected_fields = expected_fields_count(args.first)
90
105
  elsif percent?(node) && args.first.array_type?
91
106
  number_of_expected_fields = expected_fields_count(receiver_node)
92
- number_of_args_for_format = args.first.child_nodes.size
107
+ number_of_args_for_format = arguments_count(args.first.child_nodes)
93
108
  else
94
109
  number_of_args_for_format = number_of_expected_fields = :unknown
95
110
  end
@@ -120,6 +135,16 @@ module RuboCop
120
135
  .reduce(0) { |acc, elem| acc + (elem[2] =~ /\*/ ? 2 : 1) }
121
136
  end
122
137
 
138
+ def arguments_count(args)
139
+ if args.empty?
140
+ 0
141
+ elsif args.last.type == :splat
142
+ -(args.count - 1)
143
+ else
144
+ args.count
145
+ end
146
+ end
147
+
123
148
  def format?(node)
124
149
  format_method?(:format, node)
125
150
  end
@@ -4,6 +4,46 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # This cop checks for *rescue* blocks with no body.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # def some_method
13
+ # do_something
14
+ # rescue
15
+ # # do nothing
16
+ # end
17
+ #
18
+ # @example
19
+ #
20
+ # # bad
21
+ #
22
+ # begin
23
+ # do_something
24
+ # rescue
25
+ # # do nothing
26
+ # end
27
+ #
28
+ # @example
29
+ #
30
+ # # good
31
+ #
32
+ # def some_method
33
+ # do_something
34
+ # rescue
35
+ # handle_exception
36
+ # end
37
+ #
38
+ # @example
39
+ #
40
+ # # good
41
+ #
42
+ # begin
43
+ # do_something
44
+ # rescue
45
+ # handle_exception
46
+ # end
7
47
  class HandleExceptions < Cop
8
48
  MSG = 'Do not suppress exceptions.'.freeze
9
49
 
@@ -7,10 +7,15 @@ module RuboCop
7
7
  # which are on the same line.
8
8
  #
9
9
  # @example
10
- # @bad
10
+ #
11
+ # # bad
12
+ #
11
13
  # array = ['Item 1' 'Item 2']
12
14
  #
13
- # @good
15
+ # @example
16
+ #
17
+ # # good
18
+ #
14
19
  # array = ['Item 1Item 2']
15
20
  # array = ['Item 1' + 'Item 2']
16
21
  # array = [
@@ -9,7 +9,9 @@ module RuboCop
9
9
  # used for that.
10
10
  #
11
11
  # @example
12
- # @bad
12
+ #
13
+ # # bad
14
+ #
13
15
  # class C
14
16
  # private
15
17
  #
@@ -18,7 +20,10 @@ module RuboCop
18
20
  # end
19
21
  # end
20
22
  #
21
- # @good
23
+ # @example
24
+ #
25
+ # # good
26
+ #
22
27
  # class C
23
28
  # def self.method
24
29
  # puts 'hi'
@@ -27,6 +32,10 @@ module RuboCop
27
32
  # private_class_method :method
28
33
  # end
29
34
  #
35
+ # @example
36
+ #
37
+ # # good
38
+ #
30
39
  # class C
31
40
  # class << self
32
41
  # private
@@ -16,6 +16,9 @@ module RuboCop
16
16
  # ^
17
17
  #
18
18
  # @example
19
+ #
20
+ # # bad
21
+ #
19
22
  # p(? )
20
23
  class InvalidCharacterLiteral < Cop
21
24
  include ParserDiagnostic
@@ -9,14 +9,27 @@ module RuboCop
9
9
  #
10
10
  # @example
11
11
  #
12
+ # # bad
13
+ #
12
14
  # if 20
13
15
  # do_something
14
16
  # end
15
17
  #
18
+ # @example
19
+ #
20
+ # # bad
21
+ #
16
22
  # if some_var && true
17
23
  # do_something
18
24
  # end
19
25
  #
26
+ # @example
27
+ #
28
+ # # good
29
+ #
30
+ # if some_var && some_condition
31
+ # do_something
32
+ # end
20
33
  class LiteralInCondition < Cop
21
34
  MSG = 'Literal `%s` appeared in a condition.'.freeze
22
35
 
@@ -40,14 +53,14 @@ module RuboCop
40
53
  check_for_literal(node)
41
54
  end
42
55
 
43
- def on_case(node)
44
- cond, *whens, _else = *node
45
-
46
- if cond
47
- check_case_cond(cond)
56
+ def on_case(case_node)
57
+ if case_node.condition
58
+ check_case(case_node)
48
59
  else
49
- whens.each do |when_node|
50
- check_for_literal(when_node)
60
+ case_node.each_when do |when_node|
61
+ next unless when_node.conditions.all?(&:literal?)
62
+
63
+ add_offense(when_node, :expression)
51
64
  end
52
65
  end
53
66
  end
@@ -59,28 +72,15 @@ module RuboCop
59
72
  private
60
73
 
61
74
  def check_for_literal(node)
62
- cond, = *node
63
-
64
- # if the cond node is literal we obviously have a problem
65
- if cond.literal?
66
- add_offense(cond, :expression)
75
+ if node.condition.literal?
76
+ add_offense(node.condition, :expression)
67
77
  else
68
- # alternatively we have to consider a logical node with a
69
- # literal argument
70
- check_node(cond)
78
+ check_node(node.condition)
71
79
  end
72
80
  end
73
81
 
74
- def not?(node)
75
- return false unless node && node.send_type?
76
-
77
- _receiver, method_name, *_args = *node
78
-
79
- method_name == :!
80
- end
81
-
82
82
  def basic_literal?(node)
83
- if node && node.array_type?
83
+ if node.array_type?
84
84
  primitive_array?(node)
85
85
  else
86
86
  node.basic_literal?
@@ -94,18 +94,14 @@ module RuboCop
94
94
  def check_node(node)
95
95
  return unless node
96
96
 
97
- if not?(node)
97
+ if node.keyword_bang?
98
98
  receiver, = *node
99
99
 
100
100
  handle_node(receiver)
101
- elsif [:and, :or].include?(node.type)
102
- *operands = *node
103
- operands.each do |op|
104
- handle_node(op)
105
- end
101
+ elsif LOGICAL_OPERATOR_NODES.include?(node.type)
102
+ node.each_child_node { |op| handle_node(op) }
106
103
  elsif node.begin_type? && node.children.one?
107
- child_node = node.children.first
108
- handle_node(child_node)
104
+ handle_node(node.children.first)
109
105
  end
110
106
  end
111
107
 
@@ -117,11 +113,13 @@ module RuboCop
117
113
  end
118
114
  end
119
115
 
120
- def check_case_cond(node)
121
- return if node.array_type? && !primitive_array?(node)
122
- return if node.dstr_type?
116
+ def check_case(case_node)
117
+ condition = case_node.condition
118
+
119
+ return if condition.array_type? && !primitive_array?(condition)
120
+ return if condition.dstr_type?
123
121
 
124
- handle_node(node)
122
+ handle_node(condition)
125
123
  end
126
124
  end
127
125
  end
@@ -7,7 +7,15 @@ module RuboCop
7
7
  #
8
8
  # @example
9
9
  #
10
+ # # bad
11
+ #
10
12
  # "result is #{10}"
13
+ #
14
+ # @example
15
+ #
16
+ # # good
17
+ #
18
+ # "result is 10"
11
19
  class LiteralInInterpolation < Cop
12
20
  MSG = 'Literal interpolation detected.'.freeze
13
21
  COMPOSITE = [:array, :hash, :pair, :irange, :erange].freeze
@@ -4,6 +4,42 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # This cop checks for uses of *begin...end while/until something*.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # # using while
13
+ # begin
14
+ # do_something
15
+ # end while some_condition
16
+ #
17
+ # @example
18
+ #
19
+ # # bad
20
+ #
21
+ # # using until
22
+ # begin
23
+ # do_something
24
+ # end until some_condition
25
+ #
26
+ # @example
27
+ #
28
+ # # good
29
+ #
30
+ # # using while
31
+ # while some_condition
32
+ # do_something
33
+ # end
34
+ #
35
+ # @example
36
+ #
37
+ # # good
38
+ #
39
+ # # using until
40
+ # until some_condition
41
+ # do_something
42
+ # end
7
43
  class Loop < Cop
8
44
  MSG = 'Use `Kernel#loop` with `break` rather than ' \
9
45
  '`begin/end/until`(or `while`).'.freeze
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # In math and Python, we can use `x < y < z` style comparison to compare
7
+ # multiple value. However, we can't use the comparison in Ruby. However,
8
+ # the comparison is not syntax error. This cop checks the bad usage of
9
+ # comparison operators.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ #
15
+ # x < y < z
16
+ # 10 <= x <= 20
17
+ #
18
+ # @example
19
+ #
20
+ # # good
21
+ #
22
+ # x < y && y < z
23
+ # 10 <= x && x <= 20
24
+ class MultipleCompare < Cop
25
+ MSG = 'Use `&&` operator to compare multiple value.'.freeze
26
+
27
+ def_node_matcher :multiple_compare?, <<-PATTERN
28
+ (send (send _ {:< :> :<= :>=} $_) {:< :> :<= :>=} _)
29
+ PATTERN
30
+
31
+ def on_send(node)
32
+ return unless multiple_compare?(node)
33
+ add_offense(node, :expression)
34
+ end
35
+
36
+ def autocorrect(node)
37
+ lambda do |corrector|
38
+ center = multiple_compare?(node)
39
+ new_center = "#{center.source} && #{center.source}"
40
+ corrector.replace(center.source_range, new_center)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -6,6 +6,9 @@ module RuboCop
6
6
  # This cop checks for nested method definitions.
7
7
  #
8
8
  # @example
9
+ #
10
+ # # bad
11
+ #
9
12
  # # `bar` definition actually produces methods in the same scope
10
13
  # # as the outer `foo` method. Furthermore, the `bar` method
11
14
  # # will be redefined every time `foo` is invoked.
@@ -14,6 +17,25 @@ module RuboCop
14
17
  # end
15
18
  # end
16
19
  #
20
+ # @example
21
+ #
22
+ # # good
23
+ #
24
+ # def foo
25
+ # bar = -> { puts 'hello' }
26
+ # bar.call
27
+ # end
28
+ #
29
+ # @example
30
+ #
31
+ # # good
32
+ #
33
+ # def foo
34
+ # self.class_eval do
35
+ # def bar
36
+ # end
37
+ # end
38
+ # end
17
39
  class NestedMethodDefinition < Cop
18
40
  include OnMethodDef
19
41
  extend RuboCop::NodePattern::Macros