rubocop 0.48.1 → 0.49.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 (184) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/config/default.yml +397 -357
  4. data/config/disabled.yml +29 -29
  5. data/config/enabled.yml +366 -326
  6. data/lib/rubocop.rb +85 -70
  7. data/lib/rubocop/ast/builder.rb +4 -1
  8. data/lib/rubocop/ast/node.rb +2 -2
  9. data/lib/rubocop/ast/node/and_node.rb +1 -1
  10. data/lib/rubocop/ast/node/args_node.rb +24 -0
  11. data/lib/rubocop/ast/node/block_node.rb +107 -0
  12. data/lib/rubocop/ast/node/case_node.rb +1 -1
  13. data/lib/rubocop/ast/node/ensure_node.rb +1 -1
  14. data/lib/rubocop/ast/node/for_node.rb +1 -1
  15. data/lib/rubocop/ast/node/if_node.rb +1 -1
  16. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +74 -0
  17. data/lib/rubocop/ast/node/or_node.rb +1 -1
  18. data/lib/rubocop/ast/node/pair_node.rb +1 -1
  19. data/lib/rubocop/ast/node/resbody_node.rb +1 -1
  20. data/lib/rubocop/ast/node/send_node.rb +36 -57
  21. data/lib/rubocop/ast/node/super_node.rb +42 -0
  22. data/lib/rubocop/ast/node/until_node.rb +1 -1
  23. data/lib/rubocop/ast/node/when_node.rb +1 -1
  24. data/lib/rubocop/ast/node/while_node.rb +1 -1
  25. data/lib/rubocop/cli.rb +10 -0
  26. data/lib/rubocop/config.rb +23 -7
  27. data/lib/rubocop/config_loader.rb +19 -3
  28. data/lib/rubocop/cop/badge.rb +1 -1
  29. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  30. data/lib/rubocop/cop/commissioner.rb +1 -1
  31. data/lib/rubocop/cop/cop.rb +10 -0
  32. data/lib/rubocop/cop/{style → layout}/access_modifier_indentation.rb +33 -3
  33. data/lib/rubocop/cop/{style → layout}/align_array.rb +16 -1
  34. data/lib/rubocop/cop/{style → layout}/align_hash.rb +1 -1
  35. data/lib/rubocop/cop/{style → layout}/align_parameters.rb +29 -1
  36. data/lib/rubocop/cop/{style → layout}/block_end_newline.rb +10 -5
  37. data/lib/rubocop/cop/{style → layout}/case_indentation.rb +64 -1
  38. data/lib/rubocop/cop/{style → layout}/closing_parenthesis_indentation.rb +2 -2
  39. data/lib/rubocop/cop/{style → layout}/comment_indentation.rb +1 -1
  40. data/lib/rubocop/cop/{style → layout}/dot_position.rb +1 -1
  41. data/lib/rubocop/cop/{style → layout}/else_alignment.rb +1 -1
  42. data/lib/rubocop/cop/{style → layout}/empty_line_after_magic_comment.rb +1 -1
  43. data/lib/rubocop/cop/{style → layout}/empty_line_between_defs.rb +1 -1
  44. data/lib/rubocop/cop/{style → layout}/empty_lines.rb +1 -1
  45. data/lib/rubocop/cop/{style → layout}/empty_lines_around_access_modifier.rb +2 -7
  46. data/lib/rubocop/cop/{style → layout}/empty_lines_around_begin_body.rb +1 -1
  47. data/lib/rubocop/cop/{style → layout}/empty_lines_around_block_body.rb +2 -4
  48. data/lib/rubocop/cop/{style → layout}/empty_lines_around_class_body.rb +1 -1
  49. data/lib/rubocop/cop/{style → layout}/empty_lines_around_exception_handling_keywords.rb +1 -1
  50. data/lib/rubocop/cop/{style → layout}/empty_lines_around_method_body.rb +1 -1
  51. data/lib/rubocop/cop/{style → layout}/empty_lines_around_module_body.rb +1 -1
  52. data/lib/rubocop/cop/{style → layout}/end_of_line.rb +1 -1
  53. data/lib/rubocop/cop/{style → layout}/extra_spacing.rb +1 -1
  54. data/lib/rubocop/cop/{style → layout}/first_array_element_line_break.rb +1 -1
  55. data/lib/rubocop/cop/{style → layout}/first_hash_element_line_break.rb +1 -1
  56. data/lib/rubocop/cop/{style → layout}/first_method_argument_line_break.rb +1 -1
  57. data/lib/rubocop/cop/{style → layout}/first_method_parameter_line_break.rb +1 -1
  58. data/lib/rubocop/cop/{style → layout}/first_parameter_indentation.rb +1 -1
  59. data/lib/rubocop/cop/{style → layout}/indent_array.rb +1 -1
  60. data/lib/rubocop/cop/{style → layout}/indent_assignment.rb +1 -1
  61. data/lib/rubocop/cop/{style → layout}/indent_hash.rb +2 -2
  62. data/lib/rubocop/cop/{style → layout}/indent_heredoc.rb +3 -3
  63. data/lib/rubocop/cop/{style → layout}/indentation_consistency.rb +1 -1
  64. data/lib/rubocop/cop/{style → layout}/indentation_width.rb +10 -12
  65. data/lib/rubocop/cop/{style → layout}/initial_indentation.rb +1 -1
  66. data/lib/rubocop/cop/{style → layout}/leading_comment_space.rb +1 -1
  67. data/lib/rubocop/cop/{style → layout}/multiline_array_brace_layout.rb +1 -1
  68. data/lib/rubocop/cop/{style → layout}/multiline_assignment_layout.rb +1 -1
  69. data/lib/rubocop/cop/{style → layout}/multiline_block_layout.rb +21 -36
  70. data/lib/rubocop/cop/{style → layout}/multiline_hash_brace_layout.rb +5 -1
  71. data/lib/rubocop/cop/{style → layout}/multiline_method_call_brace_layout.rb +1 -1
  72. data/lib/rubocop/cop/{style → layout}/multiline_method_call_indentation.rb +3 -3
  73. data/lib/rubocop/cop/{style → layout}/multiline_method_definition_brace_layout.rb +1 -1
  74. data/lib/rubocop/cop/{style → layout}/multiline_operation_indentation.rb +6 -5
  75. data/lib/rubocop/cop/{style → layout}/rescue_ensure_alignment.rb +1 -1
  76. data/lib/rubocop/cop/{style → layout}/space_after_colon.rb +2 -2
  77. data/lib/rubocop/cop/{style → layout}/space_after_comma.rb +2 -2
  78. data/lib/rubocop/cop/{style → layout}/space_after_method_name.rb +1 -1
  79. data/lib/rubocop/cop/{style → layout}/space_after_not.rb +1 -1
  80. data/lib/rubocop/cop/{style → layout}/space_after_semicolon.rb +2 -2
  81. data/lib/rubocop/cop/{style → layout}/space_around_block_parameters.rb +7 -5
  82. data/lib/rubocop/cop/{style → layout}/space_around_equals_in_parameter_default.rb +1 -1
  83. data/lib/rubocop/cop/{style → layout}/space_around_keyword.rb +1 -1
  84. data/lib/rubocop/cop/{style → layout}/space_around_operators.rb +6 -2
  85. data/lib/rubocop/cop/{style → layout}/space_before_block_braces.rb +6 -2
  86. data/lib/rubocop/cop/{style → layout}/space_before_comma.rb +1 -1
  87. data/lib/rubocop/cop/{style → layout}/space_before_comment.rb +1 -1
  88. data/lib/rubocop/cop/{style → layout}/space_before_first_arg.rb +4 -2
  89. data/lib/rubocop/cop/{style → layout}/space_before_semicolon.rb +1 -1
  90. data/lib/rubocop/cop/{style → layout}/space_in_lambda_literal.rb +1 -1
  91. data/lib/rubocop/cop/{style → layout}/space_inside_array_percent_literal.rb +1 -1
  92. data/lib/rubocop/cop/{style → layout}/space_inside_block_braces.rb +3 -4
  93. data/lib/rubocop/cop/{style → layout}/space_inside_brackets.rb +1 -1
  94. data/lib/rubocop/cop/{style → layout}/space_inside_hash_literal_braces.rb +1 -1
  95. data/lib/rubocop/cop/{style → layout}/space_inside_parens.rb +1 -1
  96. data/lib/rubocop/cop/{style → layout}/space_inside_percent_literal_delimiters.rb +8 -7
  97. data/lib/rubocop/cop/{style → layout}/space_inside_range_literal.rb +1 -1
  98. data/lib/rubocop/cop/{style → layout}/space_inside_string_interpolation.rb +1 -1
  99. data/lib/rubocop/cop/{style → layout}/tab.rb +1 -1
  100. data/lib/rubocop/cop/{style → layout}/trailing_blank_lines.rb +1 -1
  101. data/lib/rubocop/cop/{style → layout}/trailing_whitespace.rb +2 -2
  102. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  103. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -4
  104. data/lib/rubocop/cop/lint/debugger.rb +0 -15
  105. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -1
  106. data/lib/rubocop/cop/lint/rescue_type.rb +81 -0
  107. data/lib/rubocop/cop/lint/script_permission.rb +42 -0
  108. data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -1
  109. data/lib/rubocop/cop/message_annotator.rb +23 -13
  110. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  111. data/lib/rubocop/cop/mixin/array_min_size.rb +59 -0
  112. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +10 -11
  113. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  114. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  115. data/lib/rubocop/cop/mixin/enforce_superclass.rb +36 -0
  116. data/lib/rubocop/cop/mixin/hash_alignment.rb +1 -1
  117. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -3
  118. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  119. data/lib/rubocop/cop/performance/caller.rb +41 -0
  120. data/lib/rubocop/cop/performance/compare_with_block.rb +60 -14
  121. data/lib/rubocop/cop/performance/double_start_end_with.rb +2 -2
  122. data/lib/rubocop/cop/performance/redundant_merge.rb +2 -0
  123. data/lib/rubocop/cop/rails/action_filter.rb +1 -3
  124. data/lib/rubocop/cop/rails/application_job.rb +32 -0
  125. data/lib/rubocop/cop/rails/application_record.rb +32 -0
  126. data/lib/rubocop/cop/rails/blank.rb +9 -3
  127. data/lib/rubocop/cop/rails/output_safety.rb +59 -15
  128. data/lib/rubocop/cop/rails/present.rb +9 -3
  129. data/lib/rubocop/cop/rails/relative_date_constant.rb +35 -4
  130. data/lib/rubocop/cop/rails/reversible_migration.rb +82 -18
  131. data/lib/rubocop/cop/rails/save_bang.rb +7 -2
  132. data/lib/rubocop/cop/rails/skips_model_validations.rb +7 -0
  133. data/lib/rubocop/cop/registry.rb +4 -3
  134. data/lib/rubocop/cop/security/eval.rb +9 -3
  135. data/lib/rubocop/cop/style/and_or.rb +1 -1
  136. data/lib/rubocop/cop/style/block_delimiters.rb +11 -17
  137. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
  138. data/lib/rubocop/cop/style/collection_methods.rb +1 -3
  139. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  140. data/lib/rubocop/cop/style/copyright.rb +2 -2
  141. data/lib/rubocop/cop/style/documentation_method.rb +1 -1
  142. data/lib/rubocop/cop/style/each_for_simple_loop.rb +2 -1
  143. data/lib/rubocop/cop/style/each_with_object.rb +10 -6
  144. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  145. data/lib/rubocop/cop/style/for.rb +4 -5
  146. data/lib/rubocop/cop/style/format_string.rb +49 -0
  147. data/lib/rubocop/cop/style/format_string_token.rb +141 -0
  148. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  149. data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -2
  150. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +1 -1
  151. data/lib/rubocop/cop/style/inverse_methods.rb +10 -1
  152. data/lib/rubocop/cop/style/lambda.rb +9 -9
  153. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -0
  154. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -3
  155. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -2
  156. data/lib/rubocop/cop/style/method_name.rb +8 -2
  157. data/lib/rubocop/cop/style/mixin_grouping.rb +41 -3
  158. data/lib/rubocop/cop/style/multiline_block_chain.rb +7 -11
  159. data/lib/rubocop/cop/style/multiple_comparison.rb +77 -0
  160. data/lib/rubocop/cop/style/next.rb +11 -22
  161. data/lib/rubocop/cop/style/parallel_assignment.rb +10 -19
  162. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -2
  163. data/lib/rubocop/cop/style/self_assignment.rb +4 -0
  164. data/lib/rubocop/cop/style/single_line_block_params.rb +23 -17
  165. data/lib/rubocop/cop/style/symbol_array.rb +24 -13
  166. data/lib/rubocop/cop/style/symbol_proc.rb +4 -0
  167. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  168. data/lib/rubocop/cop/style/unneeded_interpolation.rb +4 -0
  169. data/lib/rubocop/cop/style/word_array.rb +33 -53
  170. data/lib/rubocop/cop/style/yoda_condition.rb +78 -0
  171. data/lib/rubocop/cop/team.rb +1 -14
  172. data/lib/rubocop/cop/util.rb +16 -0
  173. data/lib/rubocop/formatter/simple_text_formatter.rb +0 -11
  174. data/lib/rubocop/node_pattern.rb +52 -52
  175. data/lib/rubocop/options.rb +25 -0
  176. data/lib/rubocop/path_util.rb +17 -1
  177. data/lib/rubocop/result_cache.rb +8 -7
  178. data/lib/rubocop/rspec/expect_offense.rb +167 -0
  179. data/lib/rubocop/rspec/shared_examples.rb +0 -8
  180. data/lib/rubocop/rspec/support.rb +1 -0
  181. data/lib/rubocop/runner.rb +12 -2
  182. data/lib/rubocop/target_finder.rb +5 -0
  183. data/lib/rubocop/version.rb +1 -1
  184. metadata +101 -72
@@ -12,8 +12,8 @@ module RuboCop
12
12
  # @example
13
13
  # # Style/PercentLiteralDelimiters:
14
14
  # # PreferredDelimiters:
15
- # # default: []
16
- # # %i: ()
15
+ # # default: '[]'
16
+ # # '%i': '()'
17
17
  #
18
18
  # # good
19
19
  # %w[alpha beta] + %i(gamma delta)
@@ -16,6 +16,10 @@ module RuboCop
16
16
  MSG = 'Use self-assignment shorthand `%s=`.'.freeze
17
17
  OPS = %i[+ - * ** / | &].freeze
18
18
 
19
+ def self.autocorrect_incompatible_with
20
+ [Layout::SpaceAroundOperators]
21
+ end
22
+
19
23
  def on_lvasgn(node)
20
24
  check(node, :lvar)
21
25
  end
@@ -9,32 +9,34 @@ module RuboCop
9
9
  # For instance one can configure `reduce`(`inject`) to use |a, e| as
10
10
  # parameters.
11
11
  class SingleLineBlockParams < Cop
12
+ MSG = 'Name `%s` block params `|%s|`.'.freeze
13
+
12
14
  def on_block(node)
13
- # we care only for single line blocks
14
- return unless block_length(node).zero?
15
+ return unless node.single_line?
16
+
17
+ send_node = node.send_node
15
18
 
16
- method_node, args_node, _body_node = *node
17
- receiver, method_name, _method_args = *method_node
19
+ return unless send_node.receiver
20
+ return unless method_names.include?(send_node.method_name)
18
21
 
19
- # discard other scenarios
20
- return unless receiver
21
- return unless method_names.include?(method_name)
22
+ return unless node.arguments?
22
23
 
23
- args = *args_node
24
+ arguments = node.arguments.to_a
24
25
 
25
- return if args.empty?
26
26
  # discard cases with argument destructuring
27
- return true unless args.all?(&:arg_type?)
28
- return if args_match?(method_name, args)
27
+ return true unless arguments.all?(&:arg_type?)
28
+ return if args_match?(send_node.method_name, arguments)
29
29
 
30
- add_offense(args_node, :expression, message(method_name))
30
+ add_offense(node.arguments, :expression)
31
31
  end
32
32
 
33
33
  private
34
34
 
35
- def message(method_name)
36
- args = target_args(method_name).join(', ')
37
- "Name `#{method_name}` block params `|#{args}|`."
35
+ def message(node)
36
+ method_name = node.parent.send_node.method_name
37
+ arguments = target_args(method_name).join(', ')
38
+
39
+ format(MSG, method_name, arguments)
38
40
  end
39
41
 
40
42
  def methods
@@ -42,12 +44,16 @@ module RuboCop
42
44
  end
43
45
 
44
46
  def method_names
45
- methods.map { |e| e.keys.first.to_sym }
47
+ methods.map { |method| method_name(method).to_sym }
48
+ end
49
+
50
+ def method_name(method)
51
+ method.keys.first
46
52
  end
47
53
 
48
54
  def target_args(method_name)
49
55
  method_name = method_name.to_s
50
- method_hash = methods.find { |m| m.keys.first == method_name }
56
+ method_hash = methods.find { |m| method_name(m) == method_name }
51
57
  method_hash[method_name]
52
58
  end
53
59
 
@@ -10,6 +10,11 @@ module RuboCop
10
10
  # projects which do not want to use that syntax, perhaps because they
11
11
  # support a version of Ruby lower than 2.0.
12
12
  #
13
+ # Configuration option: MinSize
14
+ # If set, arrays with fewer elements than this value will not trigger the
15
+ # cop. For example, a `MinSize of `3` will not enforce a style on an array
16
+ # of 2 or fewer elements.
17
+ #
13
18
  # @example
14
19
  # EnforcedStyle: percent (default)
15
20
  #
@@ -28,8 +33,9 @@ module RuboCop
28
33
  # # bad
29
34
  # %i[foo bar baz]
30
35
  class SymbolArray < Cop
31
- include ConfigurableEnforcedStyle
36
+ include ArrayMinSize
32
37
  include ArraySyntax
38
+ include ConfigurableEnforcedStyle
33
39
  include PercentLiteral
34
40
  extend TargetRubyVersion
35
41
 
@@ -38,6 +44,10 @@ module RuboCop
38
44
  PERCENT_MSG = 'Use `%i` or `%I` for an array of symbols.'.freeze
39
45
  ARRAY_MSG = 'Use `[]` for an array of symbols.'.freeze
40
46
 
47
+ class << self
48
+ attr_accessor :largest_brackets
49
+ end
50
+
41
51
  def on_array(node)
42
52
  if bracketed_array_of?(:sym, node)
43
53
  check_bracketed_array(node)
@@ -46,18 +56,27 @@ module RuboCop
46
56
  end
47
57
  end
48
58
 
59
+ def autocorrect(node)
60
+ if style == :percent
61
+ correct_percent(node, 'i')
62
+ else
63
+ correct_bracketed(node)
64
+ end
65
+ end
66
+
49
67
  private
50
68
 
51
69
  def check_bracketed_array(node)
52
- return if comments_in_array?(node)
53
- return if symbols_contain_spaces?(node)
70
+ return if comments_in_array?(node) ||
71
+ symbols_contain_spaces?(node) ||
72
+ below_array_length?(node)
54
73
 
55
- style_detected(:brackets)
74
+ array_style_detected(:brackets, node.values.size)
56
75
  add_offense(node, :expression, PERCENT_MSG) if style == :percent
57
76
  end
58
77
 
59
78
  def check_percent_array(node)
60
- style_detected(:percent)
79
+ array_style_detected(:percent, node.values.size)
61
80
  add_offense(node, :expression, ARRAY_MSG) if style == :brackets
62
81
  end
63
82
 
@@ -77,14 +96,6 @@ module RuboCop
77
96
  end
78
97
  end
79
98
 
80
- def autocorrect(node)
81
- if style == :percent
82
- correct_percent(node, 'i')
83
- else
84
- correct_bracketed(node)
85
- end
86
- end
87
-
88
99
  def correct_bracketed(node)
89
100
  syms = node.children.map { |c| to_symbol_literal(c.children[0].to_s) }
90
101
 
@@ -23,6 +23,10 @@ module RuboCop
23
23
  $(send lvar $_))
24
24
  PATTERN
25
25
 
26
+ def self.autocorrect_incompatible_with
27
+ [Layout::SpaceBeforeBlockBraces]
28
+ end
29
+
26
30
  def on_block(node)
27
31
  symbol_proc?(node) do |send_or_super, block_args, block_body, method|
28
32
  block_method_name = resolve_block_method_name(send_or_super)
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # This cop checks for the presence of parentheses around ternary
7
7
  # conditions. It is configurable to enforce inclusion or omission of
8
8
  # parentheses using `EnforcedStyle`. Omission is only enforced when
9
- # removing the parentheses won't cause a different behaviour.
9
+ # removing the parentheses won't cause a different behavior.
10
10
  #
11
11
  # @example
12
12
  #
@@ -20,6 +20,10 @@ module RuboCop
20
20
 
21
21
  MSG = 'Prefer `to_s` over string interpolation.'.freeze
22
22
 
23
+ def self.autocorrect_incompatible_with
24
+ [Style::LineEndConcatenation]
25
+ end
26
+
23
27
  def on_dstr(node)
24
28
  add_offense(node, :expression, MSG) if single_interpolation?(node)
25
29
  end
@@ -8,7 +8,31 @@ module RuboCop
8
8
  #
9
9
  # Alternatively, it can check for uses of the %w() syntax, in projects
10
10
  # which do not want to include that syntax.
11
+ #
12
+ # Configuration option: MinSize
13
+ # If set, arrays with fewer elements than this value will not trigger the
14
+ # cop. For example, a `MinSize of `3` will not enforce a style on an array
15
+ # of 2 or fewer elements.
16
+ #
17
+ # @example
18
+ # EnforcedStyle: percent (default)
19
+ #
20
+ # # good
21
+ # %w[foo bar baz]
22
+ #
23
+ # # bad
24
+ # ['foo', 'bar', 'baz']
25
+ #
26
+ # @example
27
+ # EnforcedStyle: brackets
28
+ #
29
+ # # good
30
+ # ['foo', 'bar', 'baz']
31
+ #
32
+ # # bad
33
+ # %w[foo bar baz]
11
34
  class WordArray < Cop
35
+ include ArrayMinSize
12
36
  include ArraySyntax
13
37
  include ConfigurableEnforcedStyle
14
38
  include PercentLiteral
@@ -23,9 +47,9 @@ module RuboCop
23
47
 
24
48
  def on_array(node)
25
49
  if bracketed_array_of?(:str, node)
26
- check_bracketed(node)
50
+ check_bracketed_array(node)
27
51
  elsif node.percent_literal?(:string)
28
- check_percent(node)
52
+ check_percent_array(node)
29
53
  end
30
54
  end
31
55
 
@@ -39,18 +63,17 @@ module RuboCop
39
63
 
40
64
  private
41
65
 
42
- def check_bracketed(node)
66
+ def check_bracketed_array(node)
43
67
  return if complex_content?(node.values) ||
44
- comments_in_array?(node)
45
- style_detected(:brackets, node.values.size)
68
+ comments_in_array?(node) ||
69
+ below_array_length?(node)
46
70
 
47
- return unless style == :percent && node.values.size >= min_size
48
-
49
- add_offense(node, :expression, PERCENT_MSG)
71
+ array_style_detected(:brackets, node.values.size)
72
+ add_offense(node, :expression, PERCENT_MSG) if style == :percent
50
73
  end
51
74
 
52
- def check_percent(node)
53
- style_detected(:percent, node.values.size)
75
+ def check_percent_array(node)
76
+ array_style_detected(:percent, node.values.size)
54
77
  add_offense(node, :expression, ARRAY_MSG) if style == :brackets
55
78
  end
56
79
 
@@ -74,10 +97,6 @@ module RuboCop
74
97
  end
75
98
  end
76
99
 
77
- def min_size
78
- cop_config['MinSize']
79
- end
80
-
81
100
  def word_regex
82
101
  Regexp.new(cop_config['WordRegex'])
83
102
  end
@@ -89,45 +108,6 @@ module RuboCop
89
108
  corrector.replace(node.source_range, "[#{words.join(', ')}]")
90
109
  end
91
110
  end
92
-
93
- def style_detected(style, ary_size)
94
- cfg = config_to_allow_offenses
95
- return if cfg['Enabled'] == false
96
-
97
- largest_brackets = largest_brackets_size(style, ary_size)
98
- smallest_percent = smallest_percent_size(style, ary_size)
99
-
100
- if cfg['EnforcedStyle'] == style.to_s
101
- # do nothing
102
- elsif cfg['EnforcedStyle'].nil?
103
- cfg['EnforcedStyle'] = style.to_s
104
- elsif smallest_percent <= largest_brackets
105
- self.config_to_allow_offenses = { 'Enabled' => false }
106
- else
107
- cfg['EnforcedStyle'] = 'percent'
108
- cfg['MinSize'] = largest_brackets + 1
109
- end
110
- end
111
-
112
- def largest_brackets_size(style, ary_size)
113
- self.class.largest_brackets ||= -Float::INFINITY
114
-
115
- if style == :brackets && ary_size > self.class.largest_brackets
116
- self.class.largest_brackets = ary_size
117
- end
118
-
119
- self.class.largest_brackets
120
- end
121
-
122
- def smallest_percent_size(style, ary_size)
123
- @smallest_percent ||= Float::INFINITY
124
-
125
- if style == :percent && ary_size < @smallest_percent
126
- @smallest_percent = ary_size
127
- end
128
-
129
- @smallest_percent
130
- end
131
111
  end
132
112
  end
133
113
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for Yoda conditions, i.e. comparison operations where
7
+ # readability is reduced because the operands are not ordered the same
8
+ # way as they would be ordered in spoken English.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ # 99 == foo
14
+ # "bar" == foo
15
+ # 42 >= foo
16
+ #
17
+ # @example
18
+ #
19
+ # # good
20
+ # foo == 99
21
+ # foo == "bar"
22
+ # for <= 42
23
+ class YodaCondition < Cop
24
+ MSG = 'Reverse the order of the operands `%s`.'.freeze
25
+ WHITELIST_TYPES = %i[lvar ivar send const regexp begin].freeze
26
+ REVERSE_COMPARISON = {
27
+ '<' => '>',
28
+ '<=' => '>=',
29
+ '>' => '<',
30
+ '>=' => '<='
31
+ }.freeze
32
+
33
+ def on_send(node)
34
+ return unless yoda_condition?(node)
35
+
36
+ register_offense(node)
37
+ end
38
+
39
+ private
40
+
41
+ def yoda_condition?(node)
42
+ return false unless comparison_operator?(node)
43
+
44
+ !WHITELIST_TYPES.include?(node.receiver.type)
45
+ end
46
+
47
+ def comparison_operator?(node)
48
+ RuboCop::AST::Node::COMPARISON_OPERATORS.include?(node.method_name)
49
+ end
50
+
51
+ def register_offense(node)
52
+ add_offense(node, :expression, format(MSG, node.source))
53
+ end
54
+
55
+ def autocorrect(node)
56
+ lambda do |corrector|
57
+ corrector.replace(actual_code_range(node), corrected_code(node))
58
+ end
59
+ end
60
+
61
+ def corrected_code(node)
62
+ first, operator, last = node.children
63
+ "#{last.source} #{reverse_comparison(operator)} #{first.source}"
64
+ end
65
+
66
+ def actual_code_range(node)
67
+ range_between(
68
+ node.loc.expression.begin_pos, node.loc.expression.end_pos
69
+ )
70
+ end
71
+
72
+ def reverse_comparison(operator)
73
+ REVERSE_COMPARISON.fetch(operator.to_s, operator)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -4,18 +4,6 @@ module RuboCop
4
4
  module Cop
5
5
  # FIXME
6
6
  class Team
7
- # If these cops try to autocorrect the same file at the same time,
8
- # bad things are liable to happen
9
- INCOMPATIBLE_COPS = {
10
- Style::SymbolProc => [Style::SpaceBeforeBlockBraces],
11
- Style::SpaceBeforeBlockBraces => [Style::SymbolProc],
12
- Style::LineEndConcatenation => [Style::UnneededInterpolation],
13
- Style::UnneededInterpolation => [Style::LineEndConcatenation],
14
- Style::SelfAssignment => [Style::SpaceAroundOperators],
15
- Style::SpaceAroundOperators => [Style::SelfAssignment],
16
- Style::BracesAroundHashParameters => [Style::MultilineHashBraceLayout]
17
- }.freeze
18
-
19
7
  DEFAULT_OPTIONS = {
20
8
  auto_correct: false,
21
9
  debug: false
@@ -135,8 +123,7 @@ module RuboCop
135
123
  next if cop.corrections.empty?
136
124
  next if skip.include?(cop.class)
137
125
  corrector.corrections.concat(cop.corrections)
138
- incompatible = INCOMPATIBLE_COPS[cop.class]
139
- skip.merge(incompatible) if incompatible
126
+ skip.merge(cop.class.autocorrect_incompatible_with)
140
127
  end
141
128
 
142
129
  if !corrector.corrections.empty?
@@ -152,6 +152,22 @@ module RuboCop
152
152
  Parser::Source::Range.new(buffer, begin_pos, end_pos)
153
153
  end
154
154
 
155
+ def range_by_whole_lines(range, include_final_newline: false)
156
+ buffer = @processed_source.buffer
157
+
158
+ begin_pos = range.begin_pos
159
+ begin_offset = range.column
160
+ begin_of_first_line = begin_pos - begin_offset
161
+
162
+ last_line = buffer.source_line(range.last_line)
163
+ end_pos = range.end_pos
164
+ end_offset = last_line.length - range.last_column
165
+ end_offset += 1 if include_final_newline
166
+ end_of_last_line = end_pos + end_offset
167
+
168
+ Parser::Source::Range.new(buffer, begin_of_first_line, end_of_last_line)
169
+ end
170
+
155
171
  def move_pos(src, pos, step, condition, regexp)
156
172
  offset = step == -1 ? -1 : 0
157
173
  pos += step while condition && src[pos + offset] =~ regexp